1 //
2 // Copyright (C) 2014-2019 Nick Gasson
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17
18 #include "util.h"
19 #include "phase.h"
20 #include "token.h"
21 #include "common.h"
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <ctype.h>
30 #include <assert.h>
31 #include <stdbool.h>
32 #include <stdlib.h>
33 #include <limits.h>
34
35 typedef struct {
36 token_t token;
37 yylval_t lval;
38 loc_t loc;
39 } tokenq_t;
40
41 typedef struct {
42 token_t look[4];
43 token_t stop[4];
44 token_t abort;
45 token_t nest_in;
46 token_t nest_out;
47 int depth;
48 } look_params_t;
49
50 typedef struct cond_state cond_state_t;
51
52 struct cond_state {
53 cond_state_t *next;
54 bool result;
55 loc_t loc;
56 };
57
58 static const char *perm_linebuf = NULL;
59 static ident_t perm_file_name = NULL;
60 static int n_token_next_start = 0;
61 static int n_row = 0;
62 static bool last_was_newline = true;
63 static loc_t start_loc;
64 static loc_t last_loc;
65 static const char *read_ptr;
66 static const char *file_start;
67 static size_t file_sz;
68 static int n_errors = 0;
69 static const char *hint_str = NULL;
70 static int n_correct = 0;
71 static tokenq_t *tokenq;
72 static int tokenq_sz;
73 static int tokenq_head;
74 static int tokenq_tail;
75 static yylval_t last_lval;
76 static token_t opt_hist[8];
77 static int nopt_hist = 0;
78 static cond_state_t *cond_state = NULL;
79 static bool translate_on = true;
80 static bool parse_pragmas = false;
81
82 loc_t yylloc;
83 int yylex(void);
84
85 #define scan(...) _scan(1, __VA_ARGS__, -1)
86 #define expect(...) _expect(1, __VA_ARGS__, -1)
87 #define one_of(...) _one_of(1, __VA_ARGS__, -1)
88 #define not_at_token(...) ((peek() != tEOF) && !_scan(1, __VA_ARGS__, -1))
89 #define peek() peek_nth(1)
90
91 #define parse_error(loc, ...) do { \
92 if (n_correct >= RECOVER_THRESH) { \
93 error_at(loc, __VA_ARGS__); \
94 n_errors++; \
95 } \
96 } while (0)
97
98 #define RECOVER_THRESH 5
99 #define TRACE_PARSE 0
100 #define WARN_LOOKAHEAD 0
101 #define TRACE_RECOVERY 0
102
103 #define STD(x, y) (standard() >= (STD_##x) ? y : -1)
104
105 #if TRACE_PARSE
106 static int depth = 0;
107 #endif
108
109 typedef void (*add_func_t)(tree_t, tree_t);
110
111 typedef struct {
112 const char *old_hint;
113 loc_t old_start_loc;
114 } state_t;
115
116 #define EXTEND(s) \
117 __attribute__((cleanup(_pop_state))) const state_t _state = \
118 { hint_str, start_loc }; \
119 hint_str = s; \
120 _push_state(&_state);
121
122 #define BEGIN(s) \
123 EXTEND(s); \
124 start_loc = LOC_INVALID;
125
126 #define CURRENT_LOC _diff_loc(&start_loc, &last_loc)
127
128 static tree_t p_expression(void);
129 static tree_t p_sequential_statement(void);
130 static tree_t p_concurrent_statement(void);
131 static tree_t p_subprogram_declaration(tree_t spec);
132 static tree_t p_subprogram_body(tree_t spec);
133 static tree_t p_subprogram_specification(void);
134 static tree_t p_name(void);
135 static tree_t p_block_configuration(void);
136 static tree_t p_protected_type_body(void);
137 static bool p_cond_analysis_expr(void);
138
139 static bool consume(token_t tok);
140 static bool optional(token_t tok);
141
_pop_state(const state_t * s)142 static void _pop_state(const state_t *s)
143 {
144 #if TRACE_PARSE
145 depth--;
146 for (int i = 0; i < depth; i++)
147 printf(" ");
148 printf("<-- %s\n", hint_str);
149 #endif
150 hint_str = s->old_hint;
151 if (s->old_start_loc.first_line != LINE_INVALID)
152 start_loc = s->old_start_loc;
153 }
154
_push_state(const state_t * s)155 static void _push_state(const state_t *s)
156 {
157 #if TRACE_PARSE
158 for (int i = 0; i < depth; i++)
159 printf(" ");
160 printf("--> %s\n", hint_str);
161 depth++;
162 #endif
163 }
164
token_str(token_t tok)165 static const char *token_str(token_t tok)
166 {
167 static const char *token_strs[] = {
168 "end of file", "identifier", "entity", "is", "end", "generic", "port",
169 "constant", "component", "configuration", "architecture", "of", "begin",
170 "for", "type", "to", "all", "in", "out", "buffer", "bus", "unaffected",
171 "signal", "downto", "process", "postponed", "wait", "report", "(", ")",
172 ";", ":=", ":", ",", "integer", "string", "error", "inout", "linkage",
173 "variable", "if", "range", "subtype", "units", "package", "library",
174 "use", ".", "null", "'", "function", "impure", "return", "pure", "array",
175 "<>", "=>", "others", "assert", "severity", "on", "map", "then", "else",
176 "elsif", "body", "while", "loop", "after", "alias", "attribute",
177 "procedure", "exit", "next", "when", "case", "label", "group", "literal",
178 "|", "[", "]", "inertial", "transport", "reject", "bit string", "block",
179 "with", "select", "generate", "access", "file", "open", "real", "until",
180 "record", "new", "shared", "and", "or", "nand", "nor", "xor", "xnor",
181 "=", "/=", "<", "<=", ">", ">=", "+", "-", "&", "**", "/", "sll", "srl",
182 "sla", "sra", "rol", "ror", "mod", "rem", "abs", "not", "*", "guarded",
183 "reverse_range", "protected", "context", "`if", "`else", "`elsif", "`end",
184 "`error", "`warning", "translate_off", "translate_on", "pragma"
185 };
186
187 if ((size_t)tok >= ARRAY_LEN(token_strs))
188 return "???";
189 else
190 return token_strs[tok];
191 }
192
conditional_yylex(void)193 static token_t conditional_yylex(void)
194 {
195 const token_t token = yylex();
196
197 #if 0
198 printf("%s %s\n", (cond_state ? (cond_state->result ? "1" : "0") : "-"),
199 token_str(token));
200 #endif
201
202 switch (token) {
203 case tCONDIF:
204 {
205 BEGIN("conditional analysis directive");
206
207 cond_state_t *new = xmalloc(sizeof(cond_state_t));
208 new->loc = yylloc;
209 new->result = p_cond_analysis_expr();
210 new->next = cond_state;
211
212 consume(tTHEN);
213
214 new->loc.last_column = yylloc.last_column;
215 new->loc.last_line = yylloc.last_line;
216
217 cond_state = new;
218 return conditional_yylex();
219 }
220
221 case tCONDELSE:
222 {
223 BEGIN("conditional analysis directive");
224
225 if (cond_state == NULL)
226 parse_error(&yylloc, "unexpected $yellow$%s$$ outside conditional "
227 "analysis block", token_str(token));
228 else
229 cond_state->result = !(cond_state->result);
230
231 return conditional_yylex();
232 }
233
234 case tCONDEND:
235 {
236 BEGIN("conditional analysis directive");
237
238 if (cond_state == NULL)
239 parse_error(&yylloc, "unexpected $yellow$%s$$ outside conditional "
240 "analysis block", token_str(token));
241 else {
242 cond_state_t *old = cond_state;
243 cond_state = cond_state->next;
244 free(old);
245 }
246
247 optional(tIF);
248
249 return conditional_yylex();
250 }
251
252 case tCONDERROR:
253 case tCONDWARN:
254 {
255 if (cond_state == NULL || cond_state->result) {
256 BEGIN("conditional analysis directive");
257
258 loc_t loc = yylloc;
259 if (consume(tSTRING)) {
260 loc.last_column = yylloc.last_column;
261 loc.last_line = yylloc.last_line;
262
263 if (token == tCONDWARN)
264 warn_at(&loc, "%s", last_lval.s);
265 else
266 parse_error(&loc, "%s", last_lval.s);
267
268 free(last_lval.s);
269 }
270 }
271
272 return conditional_yylex();
273 }
274
275 case tSYNTHOFF:
276 {
277 BEGIN("synthesis translate_off");
278
279 if (opt_get_int("synthesis"))
280 translate_on = false;
281
282 return conditional_yylex();
283 }
284
285 case tSYNTHON:
286 {
287 BEGIN("synthesis translate_off");
288
289 translate_on = true;
290 return conditional_yylex();
291 }
292
293 case tEOF:
294 if (cond_state != NULL) {
295 parse_error(&(cond_state->loc), "unterminated conditional "
296 "analysis block");
297 n_correct = 0;
298 }
299 return tEOF;
300
301 default:
302 if (translate_on && (cond_state == NULL || cond_state->result)) {
303 if (token == tPRAGMA && !parse_pragmas)
304 return conditional_yylex();
305 else
306 return token;
307 }
308 else
309 return conditional_yylex();
310 }
311 }
312
peek_nth(int n)313 static token_t peek_nth(int n)
314 {
315 while (((tokenq_head - tokenq_tail) & (tokenq_sz - 1)) < n) {
316 // Calling conditional_yylex may recursively call this function
317 const token_t token = conditional_yylex();
318
319 int next = (tokenq_head + 1) & (tokenq_sz - 1);
320 if (unlikely(next == tokenq_tail)) {
321 const int newsz = tokenq_sz * 2;
322 tokenq_t *new = xmalloc(newsz * sizeof(tokenq_t));
323
324 tokenq_t *p = new;
325 for (int i = tokenq_tail; i != tokenq_head;
326 i = (i + 1) & (tokenq_sz - 1))
327 *p++ = tokenq[i];
328
329 free(tokenq);
330
331 tokenq = new;
332 tokenq_sz = newsz;
333 tokenq_head = p - new;
334 tokenq_tail = 0;
335
336 next = (tokenq_head + 1) & (tokenq_sz - 1);
337 }
338
339 extern yylval_t yylval;
340
341 tokenq[tokenq_head].token = token;
342 tokenq[tokenq_head].lval = yylval;
343 tokenq[tokenq_head].loc = yylloc;
344
345 tokenq_head = next;
346 }
347
348 const int pos = (tokenq_tail + n - 1) & (tokenq_sz - 1);
349 return tokenq[pos].token;
350 }
351
look_for(const look_params_t * params)352 static bool look_for(const look_params_t *params)
353 {
354 bool found = false;
355 token_t tok = -1;
356 int n, nest = 0;
357 for (n = 1; ;) {
358 tok = peek_nth(n++);
359 if ((tok == tEOF) || (tok == params->abort))
360 goto stop_looking;
361 else if (tok == params->nest_in)
362 nest++;
363
364 if (nest == params->depth) {
365 for (int i = 0; i < ARRAY_LEN(params->look); i++) {
366 if (tok == params->look[i]) {
367 found = true;
368 goto stop_looking;
369 }
370 }
371
372 for (int i = 0; i < ARRAY_LEN(params->stop); i++) {
373 if (tok == params->stop[i])
374 goto stop_looking;
375 }
376 }
377
378 if (tok == params->nest_out)
379 nest--;
380 }
381 stop_looking:
382
383 #if WARN_LOOKAHEAD > 0
384 if (n >= WARN_LOOKAHEAD)
385 warn_at(&(tokenq[tokenq_tail].loc), "look ahead depth %d", n);
386 #endif
387
388 return found;
389 }
390
drop_token(void)391 static void drop_token(void)
392 {
393 assert(tokenq_head != tokenq_tail);
394
395 if (start_loc.last_line == LINE_INVALID)
396 start_loc = tokenq[tokenq_tail].loc;
397
398 last_lval = tokenq[tokenq_tail].lval;
399 last_loc = tokenq[tokenq_tail].loc;
400
401 tokenq_tail = (tokenq_tail + 1) & (tokenq_sz - 1);
402
403 nopt_hist = 0;
404 }
405
drop_tokens_until(token_t tok)406 static void drop_tokens_until(token_t tok)
407 {
408 token_t next;
409 do {
410 next = peek();
411 drop_token();
412 } while ((tok != next) && (next != tEOF));
413
414 #if TRACE_RECOVERY
415 if (peek() != tEOF)
416 fmt_loc(stdout, &(tokenq[tokenq_tail].loc));
417 #endif
418 }
419
_vexpect(va_list ap)420 static void _vexpect(va_list ap)
421 {
422 LOCAL_TEXT_BUF tb = tb_new();
423
424 tb_printf(tb, "unexpected $yellow$%s$$ while parsing %s, "
425 "expecting ", token_str(peek()), hint_str);
426
427 bool first = true;
428
429 for (int i = 0; i < nopt_hist; i++) {
430 if (first)
431 tb_printf(tb, "one of ");
432 else
433 tb_printf(tb, ", ");
434
435 tb_printf(tb, "$yellow$%s$$", token_str(opt_hist[i]));
436
437 first = false;
438 }
439
440 int tok = va_arg(ap, int);
441 while (tok != -1) {
442 const int tmp = tok;
443 tok = va_arg(ap, int);
444
445 if (first && (tok != -1))
446 tb_printf(tb, "one of ");
447 else if (!first)
448 tb_printf(tb, (tok == -1) ? " or " : ", ");
449
450 tb_printf(tb, "$yellow$%s$$", token_str(tmp));
451
452 first = false;
453 }
454
455 if (n_correct >= RECOVER_THRESH) {
456 error_at(&(tokenq[tokenq_tail].loc), "%s", tb_get(tb));
457 n_errors++;
458 }
459
460 n_correct = 0;
461
462 drop_token();
463 }
464
_expect(int dummy,...)465 static void _expect(int dummy, ...)
466 {
467 va_list ap;
468 va_start(ap, dummy);
469 _vexpect(ap);
470 va_end(ap);
471 }
472
consume(token_t tok)473 static bool consume(token_t tok)
474 {
475 const token_t got = peek();
476 if (tok != got) {
477 expect(tok);
478 return false;
479 }
480 else {
481 n_correct++;
482 drop_token();
483 return true;
484 }
485 }
486
optional(token_t tok)487 static bool optional(token_t tok)
488 {
489 if (peek() == tok) {
490 consume(tok);
491 return true;
492 }
493 else {
494 if (nopt_hist < ARRAY_LEN(opt_hist))
495 opt_hist[nopt_hist++] = tok;
496 return false;
497 }
498 }
499
_scan(int dummy,...)500 static bool _scan(int dummy, ...)
501 {
502 va_list ap;
503 va_start(ap, dummy);
504
505 token_t p = peek();
506 bool found = false;
507
508 while (!found) {
509 const int tok = va_arg(ap, token_t);
510 if (tok == -1)
511 break;
512 else if (p == tok)
513 found = true;
514 }
515
516 va_end(ap);
517 return found;
518 }
519
_one_of(int dummy,...)520 static int _one_of(int dummy, ...)
521 {
522 va_list ap;
523 va_start(ap, dummy);
524
525 token_t p = peek();
526 bool found = false;
527
528 while (!found) {
529 const int tok = va_arg(ap, token_t);
530 if (tok == -1)
531 break;
532 else if (p == tok)
533 found = true;
534 }
535
536 va_end(ap);
537
538 if (found) {
539 consume(p);
540 return p;
541 }
542 else {
543 va_start(ap, dummy);
544 _vexpect(ap);
545 va_end(ap);
546
547 return -1;
548 }
549 }
550
_diff_loc(const loc_t * start,const loc_t * end)551 static const loc_t *_diff_loc(const loc_t *start, const loc_t *end)
552 {
553 static loc_t result;
554
555 result.first_line = start->first_line;
556 result.first_column = start->first_column;
557 result.last_line = end->last_line;
558 result.last_column = end->last_column;
559 result.file = start->file;
560 result.linebuf = start->linebuf;
561
562 return &result;
563 }
564
loc_to_ident(const loc_t * loc)565 static ident_t loc_to_ident(const loc_t *loc)
566 {
567 char sbuf[64];
568 checked_sprintf(sbuf, sizeof(sbuf), "line_%d", loc->first_line);
569
570 if (!ident_interned(sbuf))
571 return ident_new(sbuf);
572
573 LOCAL_TEXT_BUF tb = tb_new();
574 tb_printf(tb, "%sa", sbuf);
575
576 for (int i = 1; ident_interned(tb_get(tb)); i++) {
577 if (i % 26 != 0)
578 tb_backup(tb, 1);
579 tb_append(tb, 'a' + i % 26);
580 }
581
582 return ident_new(tb_get(tb));
583 }
584
set_label_and_loc(tree_t t,ident_t label,const loc_t * loc)585 static void set_label_and_loc(tree_t t, ident_t label, const loc_t *loc)
586 {
587 tree_set_loc(t, loc);
588
589 if (label == NULL)
590 label = loc_to_ident(loc);
591
592 tree_set_ident(t, label);
593 }
594
bit_str_to_literal(const char * str,const loc_t * loc)595 static tree_t bit_str_to_literal(const char *str, const loc_t *loc)
596 {
597 tree_t t = tree_new(T_LITERAL);
598 tree_set_loc(t, loc);
599 tree_set_subkind(t, L_STRING);
600
601 char base_ch = str[0];
602 int base;
603 switch (base_ch) {
604 case 'X': case 'x': base = 16; break;
605 case 'O': case 'o': base = 8; break;
606 case 'B': case 'b': base = 2; break;
607 default:
608 parse_error(loc, "invalid base '%c' for bit string", base_ch);
609 return t;
610 }
611
612 tree_t one = tree_new(T_REF);
613 tree_set_ident(one, ident_new("'1'"));
614 tree_set_loc(one, loc);
615
616 tree_t zero = tree_new(T_REF);
617 tree_set_ident(zero, ident_new("'0'"));
618 tree_set_loc(zero, loc);
619
620 for (const char *p = str + 2; *p != '\"'; p++) {
621 if (*p == '_')
622 continue;
623
624 int n = (isdigit((int)*p) ? (*p - '0')
625 : 10 + (isupper((int)*p) ? (*p - 'A') : (*p - 'a')));
626
627 if (n >= base) {
628 parse_error(loc, "invalid digit '%c' in bit string", *p);
629 return t;
630 }
631
632 for (int d = (base >> 1); d > 0; n = n % d, d >>= 1)
633 tree_add_char(t, (n / d) ? one : zero);
634 }
635
636 return t;
637 }
638
get_time(int64_t fs)639 static tree_t get_time(int64_t fs)
640 {
641 tree_t lit = tree_new(T_LITERAL);
642 tree_set_subkind(lit, L_INT);
643 tree_set_ival(lit, fs);
644
645 tree_t unit = tree_new(T_REF);
646 tree_set_ident(unit, ident_new("FS"));
647
648 tree_t f = tree_new(T_FCALL);
649 tree_set_ident(f, ident_new("\"*\""));
650
651 tree_t left = tree_new(T_PARAM);
652 tree_set_subkind(left, P_POS);
653 tree_set_value(left, lit);
654
655 tree_t right = tree_new(T_PARAM);
656 tree_set_subkind(right, P_POS);
657 tree_set_value(right, unit);
658
659 tree_add_param(f, left);
660 tree_add_param(f, right);
661
662 return f;
663 }
664
int_to_physical(tree_t t,tree_t unit)665 static tree_t int_to_physical(tree_t t, tree_t unit)
666 {
667 tree_t ref = tree_new(T_REF);
668 tree_set_ident(ref, tree_ident(unit));
669
670 tree_t fcall = tree_new(T_FCALL);
671 tree_set_loc(fcall, tree_loc(t));
672 tree_set_ident(fcall, ident_new("\"*\""));
673
674 tree_t a = tree_new(T_PARAM);
675 tree_set_subkind(a, P_POS);
676 tree_set_value(a, t);
677
678 tree_t b = tree_new(T_PARAM);
679 tree_set_subkind(b, P_POS);
680 tree_set_value(b, ref);
681
682 tree_add_param(fcall, a);
683 tree_add_param(fcall, b);
684
685 return fcall;
686 }
687
set_delay_mechanism(tree_t t,tree_t reject)688 static void set_delay_mechanism(tree_t t, tree_t reject)
689 {
690 if (reject == NULL) {
691 // Inertial delay with same value as waveform
692 // LRM 93 section 8.4 the rejection limit in this case is
693 // specified by the time expression of the first waveform
694 tree_t w = (tree_kind(t) == T_CASSIGN
695 ? tree_waveform(tree_cond(t, 0), 0)
696 : tree_waveform(t, 0));
697 if (tree_has_delay(w))
698 tree_set_reject(t, tree_delay(w));
699 }
700 else
701 tree_set_reject(t, reject);
702 }
703
get_cond_analysis_identifier(const char * name)704 static const char *get_cond_analysis_identifier(const char *name)
705 {
706 if (strcmp(name, "VHDL_VERSION") == 0)
707 return standard_text(standard());
708 else if (strcmp(name, "TOOL_TYPE") == 0)
709 return "SIMULATION";
710 else if (strcmp(name, "TOOL_VENDOR") == 0)
711 return PACKAGE_URL;
712 else if (strcmp(name, "TOOL_NAME") == 0)
713 return PACKAGE_NAME;
714 else if (strcmp(name, "TOOL_EDITION") == 0)
715 return "";
716 else if (strcmp(name, "TOOL_VERSION") == 0)
717 return PACKAGE_VERSION;
718 else
719 return NULL;
720 }
721
p_cond_analysis_relation(void)722 static bool p_cond_analysis_relation(void)
723 {
724 // ( conditional_analysis_expression )
725 // | not ( conditional_analysis_expression )
726 // | conditional_analysis_identifier = string_literal
727 // | conditional_analysis_identifier /= string_literal
728 // | conditional_analysis_identifier < string_literal
729 // | conditional_analysis_identifier <= string_literal
730 // | conditional_analysis_identifier > string_literal
731 // | conditional_analysis_identifier >= string_literal
732
733 BEGIN("conditional analysis relation");
734
735 bool result = false;
736 switch (one_of(tLPAREN, tNOT, tID)) {
737 case tLPAREN:
738 result = p_cond_analysis_expr();
739 consume(tRPAREN);
740 break;
741
742 case tNOT:
743 result = !p_cond_analysis_expr();
744 break;
745
746 case tID:
747 {
748 char *name = last_lval.s;
749 token_t rel = one_of(tEQ, tNEQ, tLT, tLE, tGT, tGE);
750
751 if (consume(tSTRING)) {
752 const char *value = get_cond_analysis_identifier(name);
753 if (value == NULL)
754 parse_error(CURRENT_LOC, "undefined conditional analysis "
755 "identifier %s", name);
756 else {
757 char *cmp = last_lval.s + 1;
758 cmp[strlen(cmp) - 1] = '\0';
759
760 switch (rel) {
761 case tEQ:
762 result = strcmp(value, cmp) == 0;
763 break;
764 case tNEQ:
765 result = strcmp(value, cmp) != 0;
766 break;
767 case tLT:
768 result = strcmp(value, cmp) < 0;
769 break;
770 case tLE:
771 result = strcmp(value, cmp) <= 0;
772 break;
773 case tGT:
774 result = strcmp(value, cmp) > 0;
775 break;
776 case tGE:
777 result = strcmp(value, cmp) >= 0;
778 break;
779 default:
780 break;
781 }
782 }
783
784 free(last_lval.s);
785 }
786
787 free(name);
788 }
789 break;
790 }
791
792 return result;
793 }
794
p_cond_analysis_expr(void)795 static bool p_cond_analysis_expr(void)
796 {
797 // conditional_analysis_relation
798 // | conditional_analysis_relation { and conditional_analysis_relation }
799 // | conditional_analysis_relation { or conditional_analysis_relation }
800 // | conditional_analysis_relation { xor conditional_analysis_relation }
801 // | conditioanl_analysis_relation { xnor conditional_analysis_relation }
802
803 BEGIN("conditional analysis expression");
804
805 const bool lhs = p_cond_analysis_relation();
806
807 switch (peek()) {
808 case tAND:
809 consume(tAND);
810 return p_cond_analysis_relation() && lhs;
811 case tOR:
812 consume(tOR);
813 return p_cond_analysis_relation() || lhs;
814 case tXOR:
815 consume(tXOR);
816 return p_cond_analysis_relation() ^ lhs;
817 case tXNOR:
818 consume(tXNOR);
819 return !(p_cond_analysis_relation() ^ lhs);
820 default:
821 return lhs;
822 }
823 }
824
p_identifier(void)825 static ident_t p_identifier(void)
826 {
827 // basic_identifier | extended_identifier
828
829 if (consume(tID)) {
830 char *s = last_lval.s;
831 ident_t i = ident_new(s);
832 free(s);
833 return i;
834 }
835 else
836 return ident_new("error");
837 }
838
p_selected_identifier(void)839 static ident_t p_selected_identifier(void)
840 {
841 // identifier { . identifier }
842
843 ident_t id = p_identifier();
844 while (optional(tDOT))
845 id = ident_prefix(id, p_identifier(), '.');
846
847 return id;
848 }
849
p_identifier_list(void)850 static ident_list_t *p_identifier_list(void)
851 {
852 // identifier { , identifier }
853
854 ident_list_t *result = NULL;
855
856 ident_list_add(&result, p_identifier());
857
858 while (optional(tCOMMA))
859 ident_list_push(&result, p_identifier());
860
861 return result;
862 }
863
p_operator_symbol(void)864 static ident_t p_operator_symbol(void)
865 {
866 // string_literal
867
868 consume(tSTRING);
869
870 char *s = last_lval.s;
871 for (char *p = s; *p != '\0'; p++)
872 *p = tolower((int)*p);
873 ident_t id = ident_new(s);
874 free(s);
875
876 return id;
877 }
878
p_library_clause(tree_t unit)879 static void p_library_clause(tree_t unit)
880 {
881 // library logical_name_list ;
882
883 BEGIN("library clause");
884
885 consume(tLIBRARY);
886
887 LOCAL_IDENT_LIST ids = p_identifier_list();
888
889 consume(tSEMI);
890
891 for (ident_list_t *it = ids; it != NULL; it = it->next) {
892 tree_t l = tree_new(T_LIBRARY);
893 tree_set_ident(l, it->ident);
894 tree_set_loc(l, CURRENT_LOC);
895
896 tree_add_context(unit, l);
897 }
898 }
899
p_use_clause(tree_t unit,add_func_t addf)900 static void p_use_clause(tree_t unit, add_func_t addf)
901 {
902 // use selected_name { , selected_name } ;
903
904 // TODO: the structure of this is a hangover from the old Bison parser
905
906 BEGIN("use clause");
907
908 consume(tUSE);
909
910 do {
911 tree_t u = tree_new(T_USE);
912
913 ident_t i1 = p_identifier();
914 consume(tDOT);
915
916 switch (peek()) {
917 case tID:
918 tree_set_ident(u, ident_prefix(i1, p_identifier(), '.'));
919
920 if (optional(tDOT)) {
921 switch (peek()) {
922 case tID:
923 tree_set_ident2(u, p_identifier());
924 break;
925
926 case tSTRING:
927 tree_set_ident2(u, p_operator_symbol());
928 break;
929
930 case tALL:
931 consume(tALL);
932 tree_set_ident2(u, all_i);
933 break;
934
935 default:
936 expect(tID, tSTRING, tALL);
937 }
938 }
939 break;
940
941 case tALL:
942 consume(tALL);
943 tree_set_ident(u, i1);
944 tree_set_ident2(u, all_i);
945 break;
946
947 default:
948 expect(tID, tALL);
949 }
950
951 tree_set_loc(u, CURRENT_LOC);
952 (*addf)(unit, u);
953 } while (optional(tCOMMA));
954
955 consume(tSEMI);
956 }
957
p_context_reference(tree_t unit)958 static void p_context_reference(tree_t unit)
959 {
960 // context selected_name { , selected_name } ;
961
962 BEGIN("context reference");
963
964 consume(tCONTEXT);
965
966 do {
967 tree_t c = tree_new(T_CTXREF);
968 tree_set_ident(c, p_selected_identifier());
969 tree_set_loc(c, CURRENT_LOC);
970
971 tree_add_context(unit, c);
972 } while (optional(tCOMMA));
973
974 consume(tSEMI);
975 }
976
p_pragma(void)977 static tree_t p_pragma(void)
978 {
979 // A pragma is a special comment such as
980 // -- lint_off ....
981 // The contents of the comment are stored in a special T_PRAGMA node for
982 // processing by external tools.
983
984 consume(tPRAGMA);
985
986 extern char *yytext;
987
988 tree_t pragma = tree_new(T_PRAGMA);
989 tree_set_text(pragma, yytext);
990 return pragma;
991 }
992
p_context_item(tree_t unit)993 static void p_context_item(tree_t unit)
994 {
995 // library_clause | use_clause | 2008: context_reference
996
997 BEGIN("context item");
998
999 switch (peek()) {
1000 case tLIBRARY:
1001 p_library_clause(unit);
1002 break;
1003
1004 case tUSE:
1005 p_use_clause(unit, tree_add_context);
1006 break;
1007
1008 case tCONTEXT:
1009 p_context_reference(unit);
1010 break;
1011
1012 case tPRAGMA:
1013 tree_add_context(unit, p_pragma());
1014 break;
1015
1016 default:
1017 expect(tLIBRARY, tUSE, tCONTEXT);
1018 }
1019 }
1020
p_context_clause(tree_t unit)1021 static void p_context_clause(tree_t unit)
1022 {
1023 // { context_item }
1024
1025 BEGIN("context clause");
1026
1027 while (scan(tLIBRARY, tUSE, tCONTEXT, tPRAGMA)) {
1028 if (peek() == tCONTEXT && peek_nth(3) == tIS)
1029 break;
1030 else
1031 p_context_item(unit);
1032 }
1033 }
1034
p_mode(void)1035 static port_mode_t p_mode(void)
1036 {
1037 // in | out | inout | buffer | linkage
1038
1039 switch (one_of(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE)) {
1040 case tIN:
1041 return PORT_IN;
1042 case tOUT:
1043 return PORT_OUT;
1044 case tINOUT:
1045 return PORT_INOUT;
1046 case tBUFFER:
1047 return PORT_BUFFER;
1048 case tLINKAGE:
1049 return PORT_LINKAGE;
1050 default:
1051 return PORT_INVALID;
1052 }
1053 }
1054
p_range(tree_t left)1055 static range_t p_range(tree_t left)
1056 {
1057 // attribute_name | simple_expression direction simple_expression
1058
1059 EXTEND("range");
1060
1061 range_t r = {};
1062
1063 switch (one_of(tTO, tDOWNTO)) {
1064 case tTO:
1065 r.kind = RANGE_TO;
1066 r.left = left;
1067 r.right = p_expression();
1068 break;
1069
1070 case tDOWNTO:
1071 r.kind = RANGE_DOWNTO;
1072 r.left = left;
1073 r.right = p_expression();
1074 break;
1075 }
1076
1077 return r;
1078 }
1079
p_range_constraint(void)1080 static tree_t p_range_constraint(void)
1081 {
1082 // range range
1083
1084 BEGIN("range constraint");
1085
1086 consume(tRANGE);
1087
1088 tree_t t = tree_new(T_CONSTRAINT);
1089 tree_set_subkind(t, C_RANGE);
1090
1091 tree_t expr1 = p_expression();
1092 switch (peek()) {
1093 case tTO:
1094 case tDOWNTO:
1095 tree_add_range(t, p_range(expr1));
1096 break;
1097 default:
1098 {
1099 range_t r = {
1100 .kind = RANGE_EXPR,
1101 .left = expr1,
1102 .right = NULL
1103 };
1104 tree_add_range(t, r);
1105 }
1106 }
1107
1108 tree_set_loc(t, CURRENT_LOC);
1109 return t;
1110 }
1111
p_discrete_range(void)1112 static range_t p_discrete_range(void)
1113 {
1114 // subtype_indication | range
1115
1116 BEGIN("discrete range");
1117
1118 tree_t expr1 = p_expression();
1119
1120 switch (peek()) {
1121 case tTO:
1122 case tDOWNTO:
1123 case tTICK:
1124 return p_range(expr1);
1125
1126 case tRANGE:
1127 {
1128 if (tree_kind(expr1) != T_REF)
1129 assert(false); // XXX: FIXME
1130
1131 type_t type = type_new(T_UNRESOLVED);
1132 type_set_ident(type, tree_ident(expr1));
1133
1134 consume(tRANGE);
1135 range_t r = p_range(p_expression());
1136 if (r.left != NULL)
1137 tree_set_type(r.left, type);
1138 if (r.right != NULL)
1139 tree_set_type(r.right, type);
1140
1141 return r;
1142 }
1143
1144 default:
1145 {
1146 range_t r = {
1147 .kind = RANGE_EXPR,
1148 .left = expr1,
1149 .right = NULL
1150 };
1151 return r;
1152 }
1153 }
1154 }
1155
p_slice_name(tree_t prefix)1156 static tree_t p_slice_name(tree_t prefix)
1157 {
1158 // prefix ( discrete_range )
1159
1160 EXTEND("slice name");
1161
1162 tree_t t = tree_new(T_ARRAY_SLICE);
1163 tree_set_value(t, prefix);
1164
1165 consume(tLPAREN);
1166 tree_add_range(t, p_discrete_range());
1167 consume(tRPAREN);
1168
1169 tree_set_loc(t, CURRENT_LOC);
1170 return t;
1171 }
1172
p_formal_part(void)1173 static tree_t p_formal_part(void)
1174 {
1175 // formal_designator
1176 // | name ( formal_designator )
1177 // | type_mark ( formal_designator )
1178
1179 BEGIN("formal part");
1180
1181 return p_name();
1182 }
1183
p_actual_part(void)1184 static tree_t p_actual_part(void)
1185 {
1186 // actual_designator
1187 // | name ( actual_designator )
1188 // | type_mark ( actual_designator )
1189
1190 BEGIN("actual part");
1191
1192 if (optional(tOPEN)) {
1193 tree_t t = tree_new(T_OPEN);
1194 tree_set_loc(t, CURRENT_LOC);
1195 return t;
1196 }
1197
1198 // If the actual part takes either the second or third form above then the
1199 // argument to the function call is the actual designator but only if the
1200 // call is to a named function rather than an operator
1201 // This is import for identifying conversion functions later
1202 const token_t next = peek();
1203 const bool had_name = (next == tID || next == tSTRING);
1204
1205 tree_t designator = p_expression();
1206
1207 const bool could_be_conversion =
1208 had_name
1209 && tree_kind(designator) == T_FCALL
1210 && tree_params(designator) == 1;
1211
1212 if (could_be_conversion)
1213 tree_set_flag(designator, TREE_F_CONVERSION);
1214
1215 return designator;
1216 }
1217
p_association_element(tree_t map,add_func_t addf)1218 static void p_association_element(tree_t map, add_func_t addf)
1219 {
1220 // [ formal_part => ] actual_part
1221
1222 BEGIN("association element");
1223
1224 tree_t p = tree_new(T_PARAM);
1225
1226 const look_params_t lookp = {
1227 .look = { tASSOC },
1228 .stop = { tCOMMA, tRPAREN },
1229 .abort = tSEMI,
1230 .nest_in = tLPAREN,
1231 .nest_out = tRPAREN,
1232 .depth = 0
1233 };
1234
1235 if (look_for(&lookp)) {
1236 tree_set_subkind(p, P_NAMED);
1237 tree_set_name(p, p_formal_part());
1238
1239 consume(tASSOC);
1240 }
1241 else
1242 tree_set_subkind(p, P_POS);
1243
1244 tree_set_value(p, p_actual_part());
1245 tree_set_loc(p, CURRENT_LOC);
1246
1247 (*addf)(map, p);
1248 }
1249
p_association_list(tree_t map,add_func_t addf)1250 static void p_association_list(tree_t map, add_func_t addf)
1251 {
1252 // association_element { , association_element }
1253
1254 p_association_element(map, addf);
1255
1256 while (optional(tCOMMA))
1257 p_association_element(map, addf);
1258 }
1259
p_actual_parameter_part(tree_t call)1260 static void p_actual_parameter_part(tree_t call)
1261 {
1262 // association_list
1263
1264 BEGIN("actual parameter part");
1265
1266 p_association_list(call, tree_add_param);
1267 }
1268
p_function_call(tree_t name)1269 static tree_t p_function_call(tree_t name)
1270 {
1271 // name [ ( actual_parameter_part ) ]
1272
1273 EXTEND("function call");
1274
1275 tree_change_kind(name, T_FCALL);
1276
1277 consume(tLPAREN);
1278 p_actual_parameter_part(name);
1279 consume(tRPAREN);
1280
1281 tree_set_loc(name, CURRENT_LOC);
1282 return name;
1283 }
1284
p_attribute_name(tree_t prefix)1285 static tree_t p_attribute_name(tree_t prefix)
1286 {
1287 // prefix [ signature ] ' attribute_designator [ ( expression ) ]
1288
1289 EXTEND("attribute name");
1290
1291 consume(tTICK);
1292
1293 tree_t t = tree_new(T_ATTR_REF);
1294 tree_set_name(t, prefix);
1295
1296 if (optional(tRANGE))
1297 tree_set_ident(t, ident_new("RANGE"));
1298 else if (optional(tREVRANGE))
1299 tree_set_ident(t, ident_new("REVERSE_RANGE"));
1300 else
1301 tree_set_ident(t, p_identifier());
1302
1303 if (optional(tLPAREN)) {
1304 add_param(t, p_expression(), P_POS, NULL);
1305 consume(tRPAREN);
1306 }
1307
1308 tree_set_loc(t, CURRENT_LOC);
1309 return t;
1310 }
1311
p_selected_name(tree_t prefix)1312 static tree_t p_selected_name(tree_t prefix)
1313 {
1314 // prefix . suffix
1315
1316 EXTEND("selected name");
1317
1318 consume(tDOT);
1319
1320 ident_t suffix = NULL;
1321 switch (peek()) {
1322 case tID:
1323 suffix = p_identifier();
1324 break;
1325
1326 case tSTRING:
1327 suffix = p_operator_symbol();
1328 break;
1329
1330 case tALL:
1331 {
1332 consume(tALL);
1333
1334 tree_t all = tree_new(T_ALL);
1335 tree_set_loc(all, CURRENT_LOC);
1336 tree_set_value(all, prefix);
1337
1338 return all;
1339 }
1340
1341 default:
1342 expect(tID, tALL);
1343 return prefix;
1344 }
1345
1346 if (tree_kind(prefix) == T_REF) {
1347 ident_t joined = ident_prefix(tree_ident(prefix), suffix, '.');
1348 tree_set_ident(prefix, joined);
1349 return prefix;
1350 }
1351 else {
1352 tree_t rref = tree_new(T_RECORD_REF);
1353 tree_set_value(rref, prefix);
1354 tree_set_ident(rref, suffix);
1355 tree_set_loc(rref, CURRENT_LOC);
1356 return rref;
1357 }
1358 }
1359
p_indexed_name(tree_t prefix)1360 static tree_t p_indexed_name(tree_t prefix)
1361 {
1362 // prefix ( expression { , expression } )
1363
1364 EXTEND("indexed name");
1365
1366 tree_t t = tree_new(T_ARRAY_REF);
1367 tree_set_value(t, prefix);
1368
1369 consume(tLPAREN);
1370
1371 do {
1372 add_param(t, p_expression(), P_POS, NULL);
1373 } while (optional(tCOMMA));
1374
1375 consume(tRPAREN);
1376
1377 tree_set_loc(t, CURRENT_LOC);
1378 return t;
1379 }
1380
p_name(void)1381 static tree_t p_name(void)
1382 {
1383 // simple_name | operator_symbol | selected_name | indexed_name
1384 // | slice_name | attribute_name
1385
1386 BEGIN("name");
1387
1388 ident_t id = NULL;
1389
1390 switch (peek()) {
1391 case tSTRING:
1392 id = p_operator_symbol();
1393 break;
1394
1395 case tID:
1396 id = p_identifier();
1397 break;
1398
1399 default:
1400 expect(tSTRING, tID);
1401 return tree_new(T_OPEN);
1402 }
1403
1404 tree_t name = tree_new(T_REF);
1405 tree_set_ident(name, id);
1406 tree_set_loc(name, CURRENT_LOC);
1407
1408 for (;;) {
1409 switch (peek()) {
1410 case tLPAREN:
1411 break;
1412
1413 case tDOT:
1414 name = p_selected_name(name);
1415 tree_set_loc(name, CURRENT_LOC);
1416 continue;
1417
1418 case tTICK:
1419 if (peek_nth(2) == tLPAREN)
1420 return name; // Qualified expression
1421 name = p_attribute_name(name);
1422 continue;
1423
1424 default:
1425 return name;
1426 }
1427
1428 // Either a function call, indexed name, or selected name
1429
1430 const look_params_t lookp = {
1431 .look = { tDOWNTO, tTO, tRANGE, tREVRANGE },
1432 .stop = { tRPAREN, tCOMMA },
1433 .abort = tSEMI,
1434 .nest_in = tLPAREN,
1435 .nest_out = tRPAREN,
1436 .depth = 1
1437 };
1438
1439 if (look_for(&lookp))
1440 name = p_slice_name(name);
1441 else if (tree_kind(name) == T_REF)
1442 name = p_function_call(name);
1443 else
1444 name = p_indexed_name(name);
1445 }
1446 }
1447
p_type_mark(void)1448 static type_t p_type_mark(void)
1449 {
1450 // name
1451
1452 BEGIN("type mark");
1453
1454 ident_t name = p_identifier();
1455 while (optional(tDOT))
1456 name = ident_prefix(name, p_identifier(), '.');
1457
1458 type_t t = type_new(T_UNRESOLVED);
1459 type_set_ident(t, name);
1460 return t;
1461 }
1462
p_index_constraint(type_t type)1463 static tree_t p_index_constraint(type_t type)
1464 {
1465 // ( discrete_range { , discrete_range } )
1466
1467 BEGIN("index constraint");
1468
1469 consume(tLPAREN);
1470
1471 tree_t t = tree_new(T_CONSTRAINT);
1472 tree_set_subkind(t, C_INDEX);
1473 do {
1474 tree_add_range(t, p_discrete_range());
1475 } while (optional(tCOMMA));
1476
1477 consume(tRPAREN);
1478
1479 tree_set_loc(t, CURRENT_LOC);
1480 return t;
1481 }
1482
p_constraint(type_t type)1483 static void p_constraint(type_t type)
1484 {
1485 // range_constraint | index_constraint
1486
1487 switch (peek()) {
1488 case tRANGE:
1489 type_set_constraint(type, p_range_constraint());
1490 break;
1491
1492 case tLPAREN:
1493 type_set_constraint(type, p_index_constraint(type));
1494 break;
1495
1496 default:
1497 expect(tRANGE);
1498 }
1499 }
1500
p_subtype_indication(void)1501 static type_t p_subtype_indication(void)
1502 {
1503 // [ name ] type_mark [ constraint ]
1504
1505 BEGIN("subtype indication");
1506
1507 bool made_subtype = false;
1508 type_t type = NULL;
1509 if ((peek() == tID) && (peek_nth(2) == tID)) {
1510 type = type_new(T_SUBTYPE);
1511 made_subtype = true;
1512
1513 tree_t rname = p_name();
1514 // XXX: check name is resolution_function_name
1515 type_set_resolution(type, rname);
1516
1517 type_t base = p_type_mark();
1518 type_set_base(type, base);
1519 }
1520 else
1521 type = p_type_mark();
1522
1523 if (scan(tRANGE, tLPAREN)) {
1524 if (!made_subtype) {
1525 type_t sub = type_new(T_SUBTYPE);
1526 type_set_base(sub, type);
1527
1528 type = sub;
1529 }
1530
1531 p_constraint(type);
1532 }
1533
1534 return type;
1535 }
1536
p_abstract_literal(void)1537 static tree_t p_abstract_literal(void)
1538 {
1539 // decimal_literal | based_literal
1540
1541 BEGIN("abstract literal");
1542
1543 tree_t t = tree_new(T_LITERAL);
1544
1545 switch (one_of(tINT, tREAL)) {
1546 case tINT:
1547 tree_set_subkind(t, L_INT);
1548 tree_set_ival(t, last_lval.n);
1549 break;
1550
1551 case tREAL:
1552 tree_set_subkind(t, L_REAL);
1553 tree_set_dval(t, last_lval.d);
1554 break;
1555 }
1556
1557 tree_set_loc(t, CURRENT_LOC);
1558 return t;
1559 }
1560
p_physical_literal(tree_t mult)1561 static tree_t p_physical_literal(tree_t mult)
1562 {
1563 // [ abstract_literal ] name
1564
1565 EXTEND("physical literal");
1566
1567 tree_t unit = tree_new(T_REF);
1568 tree_set_ident(unit, p_identifier());
1569 tree_set_loc(unit, CURRENT_LOC);
1570
1571 if (mult != NULL) {
1572 tree_t t = tree_new(T_FCALL);
1573 tree_set_loc(t, CURRENT_LOC);
1574 tree_set_ident(t, ident_new("\"*\""));
1575
1576 add_param(t, mult, P_POS, NULL);
1577 add_param(t, unit, P_POS, NULL);
1578
1579 return t;
1580 }
1581 else
1582 return unit;
1583 }
1584
p_numeric_literal(void)1585 static tree_t p_numeric_literal(void)
1586 {
1587 // abstract_literal | physical_literal
1588
1589 BEGIN("numeric literal");
1590
1591 tree_t abs = NULL;
1592 if (scan(tINT, tREAL))
1593 abs = p_abstract_literal();
1594
1595 if (peek() == tID)
1596 return p_physical_literal(abs);
1597 else
1598 return abs;
1599 }
1600
p_literal(void)1601 static tree_t p_literal(void)
1602 {
1603 // numeric_literal | enumeration_literal | string_literal
1604 // | bit_string_literal | null
1605
1606 BEGIN("literal");
1607
1608 switch (peek()) {
1609 case tNULL:
1610 {
1611 consume(tNULL);
1612
1613 tree_t t = tree_new(T_LITERAL);
1614 tree_set_loc(t, CURRENT_LOC);
1615 tree_set_subkind(t, L_NULL);
1616 return t;
1617 }
1618
1619 case tINT:
1620 case tREAL:
1621 return p_numeric_literal();
1622
1623 case tSTRING:
1624 {
1625 consume(tSTRING);
1626
1627 char *p = last_lval.s;
1628 size_t len = strlen(p);
1629 tree_t t = str_to_literal(p + 1, p + len - 1, NULL);
1630 tree_set_loc(t, CURRENT_LOC);
1631 free(p);
1632
1633 return t;
1634 }
1635
1636 case tBITSTRING:
1637 {
1638 consume(tBITSTRING);
1639
1640 tree_t t = bit_str_to_literal(last_lval.s, CURRENT_LOC);
1641 free(last_lval.s);
1642 return t;
1643 }
1644
1645 default:
1646 expect(tNULL, tINT, tREAL);
1647 return tree_new(T_OPEN);
1648 }
1649 }
1650
p_choice(tree_t parent)1651 static void p_choice(tree_t parent)
1652 {
1653 // simple_expression | discrete_range | simple_name | others
1654
1655 BEGIN("choice");
1656
1657 tree_t t = tree_new(T_ASSOC);
1658
1659 if (optional(tOTHERS))
1660 tree_set_subkind(t, A_OTHERS);
1661 else {
1662 const look_params_t lookp = {
1663 .look = { tDOWNTO, tTO, tRANGE, tREVRANGE },
1664 .stop = { tRPAREN, tCOMMA, tASSOC, tBAR },
1665 .abort = tSEMI,
1666 .nest_in = tLPAREN,
1667 .nest_out = tRPAREN,
1668 .depth = 0
1669 };
1670
1671 if (look_for(&lookp)) {
1672 tree_set_subkind(t, A_RANGE);
1673 tree_add_range(t, p_discrete_range());
1674 }
1675 else {
1676 tree_set_subkind(t, A_NAMED);
1677 tree_set_name(t, p_expression());
1678 }
1679 }
1680
1681 tree_set_loc(t, CURRENT_LOC);
1682 tree_add_assoc(parent, t);
1683 }
1684
p_choices(tree_t parent)1685 static void p_choices(tree_t parent)
1686 {
1687 // choices ::= choice { | choice }
1688
1689 BEGIN("choices");
1690
1691 p_choice(parent);
1692
1693 while (optional(tBAR))
1694 p_choice(parent);
1695 }
1696
p_element_association(tree_t agg)1697 static void p_element_association(tree_t agg)
1698 {
1699 // [ choices => ] expression
1700
1701 BEGIN("element association");
1702
1703 const look_params_t lookp = {
1704 .look = { tASSOC },
1705 .stop = { tCOMMA, tRPAREN },
1706 .abort = tSEMI,
1707 .nest_in = tLPAREN,
1708 .nest_out = tRPAREN,
1709 .depth = 0
1710 };
1711
1712 if (look_for(&lookp)) {
1713 const int nstart = tree_assocs(agg);
1714 p_choices(agg);
1715
1716 consume(tASSOC);
1717
1718 tree_t value = p_expression();
1719 const int nassocs = tree_assocs(agg);
1720 for (int i = nstart; i < nassocs; i++)
1721 tree_set_value(tree_assoc(agg, i), value);
1722 }
1723 else {
1724 tree_t t = tree_new(T_ASSOC);
1725 tree_set_subkind(t, A_POS);
1726 tree_set_value(t, p_expression());
1727 tree_set_loc(t, CURRENT_LOC);
1728
1729 tree_add_assoc(agg, t);
1730 }
1731 }
1732
p_aggregate(void)1733 static tree_t p_aggregate(void)
1734 {
1735 // ( element_association { , element_association } )
1736
1737 BEGIN("aggregate");
1738
1739 tree_t t = tree_new(T_AGGREGATE);
1740
1741 consume(tLPAREN);
1742
1743 do {
1744 p_element_association(t);
1745 } while (optional(tCOMMA));
1746
1747 consume(tRPAREN);
1748
1749 tree_set_loc(t, CURRENT_LOC);
1750 return t;
1751 }
1752
p_qualified_expression(tree_t name)1753 static tree_t p_qualified_expression(tree_t name)
1754 {
1755 // type_mark ' ( expression ) | type_mark ' aggregate
1756
1757 EXTEND("qualified expression");
1758
1759 tree_t t = tree_new(T_QUALIFIED);
1760
1761 if (tree_kind(name) != T_REF)
1762 assert(false); // XXX: FIXME
1763 else
1764 tree_set_ident(t, tree_ident(name));
1765
1766 consume(tTICK);
1767
1768 const look_params_t lookp = {
1769 .look = { tCOMMA, tASSOC },
1770 .stop = { tRPAREN },
1771 .abort = tSEMI,
1772 .nest_in = tLPAREN,
1773 .nest_out = tRPAREN,
1774 .depth = 1
1775 };
1776
1777 if (look_for(&lookp))
1778 tree_set_value(t, p_aggregate());
1779 else {
1780 consume(tLPAREN);
1781 tree_set_value(t, p_expression());
1782 consume(tRPAREN);
1783 }
1784 tree_set_loc(t, CURRENT_LOC);
1785
1786 return t;
1787 }
1788
p_allocator(void)1789 static tree_t p_allocator(void)
1790 {
1791 // new subtype_indication | new qualified_expression
1792
1793 BEGIN("allocator");
1794
1795 consume(tNEW);
1796
1797 tree_t new = tree_new(T_NEW);
1798 tree_set_value(new, p_expression());
1799 tree_set_loc(new, CURRENT_LOC);
1800
1801 return new;
1802 }
1803
p_primary(void)1804 static tree_t p_primary(void)
1805 {
1806 // name | literal | aggregate | function_call | qualified_expression
1807 // | type_conversion | allocator | ( expression )
1808
1809 BEGIN("primary");
1810
1811 switch (peek()) {
1812 case tLPAREN:
1813 {
1814 const look_params_t lookp = {
1815 .look = { tCOMMA, tASSOC },
1816 .stop = { tRPAREN },
1817 .abort = tSEMI,
1818 .nest_in = tLPAREN,
1819 .nest_out = tRPAREN,
1820 .depth = 1
1821 };
1822
1823 if (look_for(&lookp))
1824 return p_aggregate();
1825 else {
1826 consume(tLPAREN);
1827 tree_t sub = p_expression();
1828 consume(tRPAREN);
1829 return sub;
1830 }
1831 }
1832
1833 case tINT:
1834 case tREAL:
1835 case tNULL:
1836 case tBITSTRING:
1837 return p_literal();
1838
1839 case tSTRING:
1840 return (peek_nth(2) == tLPAREN) ? p_name() : p_literal();
1841
1842 case tID:
1843 {
1844 tree_t name = p_name();
1845 switch (peek()) {
1846 case tTICK:
1847 return p_qualified_expression(name);
1848 default:
1849 return name;
1850 }
1851 }
1852
1853 case tNEW:
1854 return p_allocator();
1855
1856 default:
1857 expect(tLPAREN, tINT, tREAL, tNULL, tID, tSTRING, tBITSTRING, tNEW);
1858 return tree_new(T_OPEN);
1859 }
1860 }
1861
p_factor(void)1862 static tree_t p_factor(void)
1863 {
1864 // primary [ ** primary ] | abs primary | not primary
1865
1866 BEGIN("factor");
1867
1868 ident_t op = NULL;
1869 switch (peek()) {
1870 case tNOT:
1871 consume(tNOT);
1872 op = ident_new("\"not\"");
1873 break;
1874
1875 case tABS:
1876 consume(tABS);
1877 op = ident_new("\"abs\"");
1878 break;
1879
1880 default:
1881 break;
1882 }
1883
1884 tree_t operand = p_primary();
1885
1886 if (op != NULL) {
1887 tree_t t = tree_new(T_FCALL);
1888 tree_set_loc(t, CURRENT_LOC);
1889 tree_set_ident(t, op);
1890 add_param(t, operand, P_POS, NULL);
1891
1892 return t;
1893 }
1894 else if (optional(tPOWER)) {
1895 tree_t second = p_primary();
1896
1897 tree_t t = tree_new(T_FCALL);
1898 tree_set_loc(t, CURRENT_LOC);
1899 tree_set_ident(t, ident_new("\"**\""));
1900 add_param(t, operand, P_POS, NULL);
1901 add_param(t, second, P_POS, NULL);
1902
1903 return t;
1904 }
1905 else
1906 return operand;
1907 }
1908
p_multiplying_operator(void)1909 static ident_t p_multiplying_operator(void)
1910 {
1911 switch (one_of(tTIMES, tOVER, tMOD, tREM)) {
1912 case tTIMES:
1913 return ident_new("\"*\"");
1914 case tOVER:
1915 return ident_new("\"/\"");
1916 case tMOD:
1917 return ident_new("\"mod\"");
1918 case tREM:
1919 return ident_new("\"rem\"");
1920 default:
1921 return ident_new("error");
1922 }
1923 }
1924
p_term(void)1925 static tree_t p_term(void)
1926 {
1927 // factor { multiplying_operator factor }
1928
1929 BEGIN("term");
1930
1931 tree_t term = p_factor();
1932
1933 while (scan(tTIMES, tOVER, tMOD, tREM)) {
1934 ident_t op = p_multiplying_operator();
1935 tree_t left = term;
1936 tree_t right = p_factor();
1937
1938 term = tree_new(T_FCALL);
1939 tree_set_ident(term, op);
1940 tree_set_loc(term, CURRENT_LOC);
1941
1942 add_param(term, left, P_POS, NULL);
1943 add_param(term, right, P_POS, NULL);
1944 }
1945
1946 return term;
1947 }
1948
p_adding_operator(void)1949 static ident_t p_adding_operator(void)
1950 {
1951 switch (one_of(tPLUS, tMINUS, tAMP)) {
1952 case tPLUS:
1953 return ident_new("\"+\"");
1954 case tMINUS:
1955 return ident_new("\"-\"");
1956 case tAMP:
1957 return ident_new("\"&\"");
1958 default:
1959 return ident_new("error");
1960 }
1961 }
1962
p_sign(void)1963 static ident_t p_sign(void)
1964 {
1965 switch (one_of(tPLUS, tMINUS)) {
1966 case tPLUS:
1967 return ident_new("\"+\"");
1968 case tMINUS:
1969 return ident_new("\"-\"");
1970 default:
1971 return ident_new("error");
1972 }
1973 }
1974
p_simple_expression(void)1975 static tree_t p_simple_expression(void)
1976 {
1977 // [ sign ] term { adding_operator term }
1978
1979 BEGIN("simple expression");
1980
1981 ident_t sign = NULL;
1982 if (scan(tPLUS, tMINUS))
1983 sign = p_sign();
1984
1985 tree_t expr = p_term();
1986
1987 if (sign != NULL) {
1988 tree_t tmp = tree_new(T_FCALL);
1989 tree_set_ident(tmp, sign);
1990 tree_set_loc(tmp, CURRENT_LOC);
1991
1992 add_param(tmp, expr, P_POS, NULL);
1993
1994 expr = tmp;
1995 }
1996
1997 while (scan(tPLUS, tMINUS, tAMP)) {
1998 tree_t left = expr;
1999
2000 if (optional(tAMP))
2001 expr = tree_new(T_CONCAT);
2002 else {
2003 expr = tree_new(T_FCALL);
2004 tree_set_ident(expr, p_adding_operator());
2005 }
2006
2007 tree_t right = p_term();
2008 tree_set_loc(expr, CURRENT_LOC);
2009
2010 add_param(expr, left, P_POS, NULL);
2011 add_param(expr, right, P_POS, NULL);
2012 }
2013
2014 return expr;
2015 }
2016
p_shift_operator(void)2017 static ident_t p_shift_operator(void)
2018 {
2019 switch (one_of(tSLL, tSRL, tSLA, tSRA, tROL, tROR)) {
2020 case tSLL:
2021 return ident_new("\"sll\"");
2022 case tSRL:
2023 return ident_new("\"srl\"");
2024 case tSLA:
2025 return ident_new("\"sla\"");
2026 case tSRA:
2027 return ident_new("\"sra\"");
2028 case tROL:
2029 return ident_new("\"rol\"");
2030 case tROR:
2031 return ident_new("\"ror\"");
2032 default:
2033 return ident_new("error");
2034 }
2035 }
2036
p_shift_expression(void)2037 static tree_t p_shift_expression(void)
2038 {
2039 // simple_expression [ shift_operator simple_expression ]
2040
2041 BEGIN("shift expression");
2042
2043 tree_t shift = p_simple_expression();
2044
2045 while (scan(tSLL, tSRL, tSLA, tSRA, tROL, tROR)) {
2046 ident_t op = p_shift_operator();
2047 tree_t left = shift;
2048 tree_t right = p_simple_expression();
2049
2050 shift = tree_new(T_FCALL);
2051 tree_set_ident(shift, op);
2052 tree_set_loc(shift, CURRENT_LOC);
2053
2054 add_param(shift, left, P_POS, NULL);
2055 add_param(shift, right, P_POS, NULL);
2056 }
2057
2058 return shift;
2059 }
2060
p_relational_operator(void)2061 static ident_t p_relational_operator(void)
2062 {
2063 switch (one_of(tEQ, tNEQ, tLT, tLE, tGT, tGE)) {
2064 case tEQ:
2065 return ident_new("\"=\"");
2066 case tNEQ:
2067 return ident_new("\"/=\"");
2068 case tLT:
2069 return ident_new("\"<\"");
2070 case tLE:
2071 return ident_new("\"<=\"");
2072 case tGT:
2073 return ident_new("\">\"");
2074 case tGE:
2075 return ident_new("\">=\"");
2076 default:
2077 return ident_new("error");
2078 }
2079 }
2080
p_relation(void)2081 static tree_t p_relation(void)
2082 {
2083 // shift_expression [ relational_operator shift_expression ]
2084
2085 BEGIN("relation");
2086
2087 tree_t rel = p_shift_expression();
2088
2089 while (scan(tEQ, tNEQ, tLT, tLE, tGT, tGE)) {
2090 ident_t op = p_relational_operator();
2091 tree_t left = rel;
2092 tree_t right = p_shift_expression();
2093
2094 rel = tree_new(T_FCALL);
2095 tree_set_ident(rel, op);
2096 tree_set_loc(rel, CURRENT_LOC);
2097
2098 add_param(rel, left, P_POS, NULL);
2099 add_param(rel, right, P_POS, NULL);
2100 }
2101
2102 return rel;
2103 }
2104
p_expression(void)2105 static tree_t p_expression(void)
2106 {
2107 // relation { and relation } | relation { or relation }
2108 // | relation { xor relation } | relation [ nand relation ]
2109 // | relation [ nor relation ] | relation { xnor relation }
2110
2111 BEGIN("expression");
2112
2113 tree_t expr = p_relation();
2114
2115 int loop_limit = (scan(tNOR, tNAND) ? 1 : INT_MAX);
2116
2117 while (loop_limit-- && scan(tAND, tOR, tXOR, tNAND, tNOR, tXNOR)) {
2118 ident_t op;
2119 switch (one_of(tAND, tOR, tXOR, tNAND, tNOR, tXNOR)) {
2120 case tAND: op = ident_new("\"and\""); break;
2121 case tOR: op = ident_new("\"or\""); break;
2122 case tXOR: op = ident_new("\"xor\""); break;
2123 case tNAND: op = ident_new("\"nand\""); break;
2124 case tNOR: op = ident_new("\"nor\""); break;
2125 case tXNOR: op = ident_new("\"xnor\""); break;
2126 default:
2127 op = ident_new("error");
2128 }
2129
2130 tree_t left = expr;
2131 tree_t right = p_relation();
2132
2133 expr = tree_new(T_FCALL);
2134 tree_set_ident(expr, op);
2135 tree_set_loc(expr, CURRENT_LOC);
2136
2137 add_param(expr, left, P_POS, NULL);
2138 add_param(expr, right, P_POS, NULL);
2139 }
2140
2141 return expr;
2142 }
2143
p_interface_constant_declaration(tree_t parent,add_func_t addf)2144 static void p_interface_constant_declaration(tree_t parent, add_func_t addf)
2145 {
2146 // [ constant ] identifier_list : [ in ] subtype_indication [ := expression ]
2147
2148 BEGIN("interface constant declaration");
2149
2150 optional(tCONSTANT);
2151
2152 LOCAL_IDENT_LIST ids = p_identifier_list();
2153
2154 consume(tCOLON);
2155
2156 // The grammar only allows IN here but we are more leniant to allow the
2157 // semantic checker to generate a more helpful error message
2158 port_mode_t mode = PORT_IN;
2159 if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2160 mode = p_mode();
2161
2162 type_t type = p_subtype_indication();
2163
2164 tree_t init = NULL;
2165 if (optional(tASSIGN))
2166 init = p_expression();
2167
2168 const loc_t *loc = CURRENT_LOC;
2169
2170 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2171 tree_t d = tree_new(T_PORT_DECL);
2172 tree_set_ident(d, it->ident);
2173 tree_set_loc(d, loc);
2174 tree_set_subkind(d, mode);
2175 tree_set_type(d, type);
2176 tree_set_class(d, C_CONSTANT);
2177
2178 if (init != NULL)
2179 tree_set_value(d, init);
2180
2181 (*addf)(parent, d);
2182 }
2183 }
2184
p_interface_signal_declaration(tree_t parent,add_func_t addf)2185 static void p_interface_signal_declaration(tree_t parent, add_func_t addf)
2186 {
2187 // [signal] identifier_list : [ mode ] subtype_indication [ bus ]
2188 // [ := expression ]
2189
2190 BEGIN("interface signal declaration");
2191
2192 optional(tSIGNAL);
2193 LOCAL_IDENT_LIST ids = p_identifier_list();
2194 consume(tCOLON);
2195
2196 port_mode_t mode = PORT_IN;
2197 if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2198 mode = p_mode();
2199
2200 type_t type = p_subtype_indication();
2201
2202 optional(tBUS);
2203
2204 tree_t init = NULL;
2205 if (optional(tASSIGN))
2206 init = p_expression();
2207
2208 const loc_t *loc = CURRENT_LOC;
2209
2210 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2211 tree_t d = tree_new(T_PORT_DECL);
2212 tree_set_ident(d, it->ident);
2213 tree_set_loc(d, loc);
2214 tree_set_subkind(d, mode);
2215 tree_set_type(d, type);
2216 tree_set_class(d, C_SIGNAL);
2217
2218 if (init != NULL)
2219 tree_set_value(d, init);
2220
2221 (*addf)(parent, d);
2222 }
2223 }
2224
p_interface_variable_declaration(tree_t parent,class_t def_class,add_func_t addf)2225 static void p_interface_variable_declaration(tree_t parent, class_t def_class, add_func_t addf)
2226 {
2227 // [variable] identifier_list : [ mode ] subtype_indication [ := expression ]
2228
2229 BEGIN("interface variable declaration");
2230
2231 if (optional(tVARIABLE))
2232 def_class = C_VARIABLE;
2233
2234 LOCAL_IDENT_LIST ids = p_identifier_list();
2235 consume(tCOLON);
2236
2237 port_mode_t mode = PORT_IN;
2238 if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2239 mode = p_mode();
2240
2241 type_t type = p_subtype_indication();
2242
2243 tree_t init = NULL;
2244 if (optional(tASSIGN))
2245 init = p_expression();
2246
2247 const loc_t *loc = CURRENT_LOC;
2248
2249 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2250 tree_t d = tree_new(T_PORT_DECL);
2251 tree_set_ident(d, it->ident);
2252 tree_set_loc(d, loc);
2253 tree_set_subkind(d, mode);
2254 tree_set_type(d, type);
2255 tree_set_class(d, def_class);
2256
2257 if (init != NULL)
2258 tree_set_value(d, init);
2259
2260 (*addf)(parent, d);
2261 }
2262 }
2263
p_interface_file_declaration(tree_t parent,add_func_t addf)2264 static void p_interface_file_declaration(tree_t parent, add_func_t addf)
2265 {
2266 // file identifier_list : subtype_indication
2267
2268 BEGIN("interface file declaration");
2269
2270 consume(tFILE);
2271
2272 LOCAL_IDENT_LIST ids = p_identifier_list();
2273
2274 consume(tCOLON);
2275
2276 type_t type = p_subtype_indication();
2277
2278 const loc_t *loc = CURRENT_LOC;
2279 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2280 tree_t d = tree_new(T_PORT_DECL);
2281 tree_set_ident(d, it->ident);
2282 tree_set_loc(d, loc);
2283 tree_set_subkind(d, PORT_IN);
2284 tree_set_type(d, type);
2285 tree_set_class(d, C_FILE);
2286
2287 (*addf)(parent, d);
2288 }
2289 }
2290
p_interface_declaration(class_t def_class,tree_t parent,add_func_t addf)2291 static void p_interface_declaration(class_t def_class, tree_t parent,
2292 add_func_t addf)
2293 {
2294 // interface_constant_declaration | interface_signal_declaration
2295 // | interface_variable_declaration | interface_file_declaration
2296
2297 BEGIN("interface declaration");
2298
2299 const token_t p = peek();
2300 switch (p) {
2301 case tCONSTANT:
2302 p_interface_constant_declaration(parent, addf);
2303 break;
2304
2305 case tSIGNAL:
2306 p_interface_signal_declaration(parent, addf);
2307 break;
2308
2309 case tVARIABLE:
2310 p_interface_variable_declaration(parent, C_VARIABLE, addf);
2311 break;
2312
2313 case tFILE:
2314 p_interface_file_declaration(parent, addf);
2315 break;
2316
2317 case tID:
2318 {
2319 switch (def_class) {
2320 case C_CONSTANT:
2321 p_interface_constant_declaration(parent, addf);
2322 break;
2323
2324 case C_SIGNAL:
2325 p_interface_signal_declaration(parent, addf);
2326 break;
2327
2328 case C_VARIABLE:
2329 case C_DEFAULT:
2330 p_interface_variable_declaration(parent, def_class, addf);
2331 break;
2332
2333 default:
2334 assert(false);
2335 }
2336 }
2337 break;
2338
2339 default:
2340 expect(tCONSTANT, tSIGNAL, tVARIABLE, tFILE, tID);
2341 }
2342 }
2343
p_interface_element(class_t def_class,tree_t parent,add_func_t addf)2344 static void p_interface_element(class_t def_class, tree_t parent,
2345 add_func_t addf)
2346 {
2347 // interface_declaration
2348
2349 BEGIN("interface element");
2350
2351 p_interface_declaration(def_class, parent, addf);
2352 }
2353
p_interface_list(class_t def_class,tree_t parent,add_func_t addf)2354 static void p_interface_list(class_t def_class, tree_t parent, add_func_t addf)
2355 {
2356 // interface_element { ; interface_element }
2357
2358 BEGIN("interface list");
2359
2360 p_interface_element(def_class, parent, addf);
2361
2362 while (optional(tSEMI))
2363 p_interface_element(def_class, parent, addf);
2364 }
2365
p_port_list(tree_t parent)2366 static void p_port_list(tree_t parent)
2367 {
2368 // port_list ::= interface_list
2369
2370 BEGIN("port list");
2371
2372 p_interface_list(C_SIGNAL, parent, tree_add_port);
2373 }
2374
p_port_clause(tree_t parent)2375 static void p_port_clause(tree_t parent)
2376 {
2377 // port ( port_list ) ;
2378
2379 BEGIN("port clause");
2380
2381 consume(tPORT);
2382 consume(tLPAREN);
2383
2384 p_port_list(parent);
2385
2386 consume(tRPAREN);
2387 consume(tSEMI);
2388 }
2389
p_generic_list(tree_t parent)2390 static void p_generic_list(tree_t parent)
2391 {
2392 // generic_list ::= interface_list
2393
2394 BEGIN("generic list");
2395
2396 p_interface_list(C_CONSTANT, parent, tree_add_generic);
2397 }
2398
p_generic_clause(tree_t parent)2399 static void p_generic_clause(tree_t parent)
2400 {
2401 // generic ( generic_list ) ;
2402
2403 BEGIN("generic clause");
2404
2405 consume(tGENERIC);
2406 consume(tLPAREN);
2407
2408 p_generic_list(parent);
2409
2410 consume(tRPAREN);
2411 consume(tSEMI);
2412 }
2413
p_entity_header(tree_t entity)2414 static void p_entity_header(tree_t entity)
2415 {
2416 // [ generic_clause ] [ port_clause ]
2417
2418 BEGIN("entity header");
2419
2420 if (scan(tGENERIC))
2421 p_generic_clause(entity);
2422
2423 if (scan(tPORT))
2424 p_port_clause(entity);
2425 }
2426
p_attribute_declaration(void)2427 static tree_t p_attribute_declaration(void)
2428 {
2429 // attribute identifier : type_mark ;
2430
2431 BEGIN("attribute declaration");
2432
2433 tree_t t = tree_new(T_ATTR_DECL);
2434
2435 consume(tATTRIBUTE);
2436 tree_set_ident(t, p_identifier());
2437 consume(tCOLON);
2438 tree_set_type(t, p_type_mark());
2439 consume(tSEMI);
2440
2441 tree_set_loc(t, CURRENT_LOC);
2442 return t;
2443 }
2444
p_entity_class(void)2445 static class_t p_entity_class(void)
2446 {
2447 // entity | procedure | type | signal | label | group | architecture
2448 // | function | subtype | variable | literal | file | configuration
2449 // | package | constant | component | units
2450
2451 BEGIN("entity class");
2452
2453 switch (one_of(tENTITY, tPROCEDURE, tTYPE, tSIGNAL, tLABEL, tGROUP,
2454 tARCHITECTURE, tFUNCTION, tSUBTYPE, tVARIABLE, tLITERAL,
2455 tFILE, tCONFIGURATION, tPACKAGE, tCONSTANT, tCOMPONENT,
2456 tUNITS)) {
2457 case tENTITY:
2458 return C_ENTITY;
2459 case tPROCEDURE:
2460 return C_PROCEDURE;
2461 case tTYPE:
2462 return C_TYPE;
2463 case tSIGNAL:
2464 return C_SIGNAL;
2465 case tLABEL:
2466 return C_LABEL;
2467 case tGROUP:
2468 return C_DEFAULT;
2469 case tARCHITECTURE:
2470 return C_ARCHITECTURE;
2471 case tFUNCTION:
2472 return C_FUNCTION;
2473 case tSUBTYPE:
2474 return C_SUBTYPE;
2475 case tVARIABLE:
2476 return C_VARIABLE;
2477 case tLITERAL:
2478 return C_LITERAL;
2479 case tFILE:
2480 return C_FILE;
2481 case tCONFIGURATION:
2482 return C_CONFIGURATION;
2483 case tPACKAGE:
2484 return C_PACKAGE;
2485 case tCONSTANT:
2486 return C_CONSTANT;
2487 case tCOMPONENT:
2488 return C_COMPONENT;
2489 case tUNITS:
2490 return C_UNITS;
2491 default:
2492 return C_DEFAULT;
2493 }
2494 }
2495
p_entity_specification(class_t * class)2496 static ident_list_t *p_entity_specification(class_t *class)
2497 {
2498 // entity_name_list : entity_class
2499
2500 BEGIN("entity specification");
2501
2502 ident_list_t *ids = p_identifier_list();
2503
2504 consume(tCOLON);
2505
2506 *class = p_entity_class();
2507 return ids;
2508 }
2509
p_attribute_specification(tree_t parent,add_func_t addf)2510 static void p_attribute_specification(tree_t parent, add_func_t addf)
2511 {
2512 // attribute attribute_designator of entity_specification is expression ;
2513
2514 BEGIN("attribute specification");
2515
2516 consume(tATTRIBUTE);
2517 ident_t head = p_identifier();
2518 consume(tOF);
2519
2520 class_t class;
2521 LOCAL_IDENT_LIST ids = p_entity_specification(&class);
2522
2523 consume(tIS);
2524
2525 tree_t value = p_expression();
2526
2527 consume(tSEMI);
2528
2529 const loc_t *loc = CURRENT_LOC;
2530
2531 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2532 tree_t t = tree_new(T_ATTR_SPEC);
2533 tree_set_loc(t, loc);
2534 tree_set_class(t, class);
2535 tree_set_ident(t, head);
2536 tree_set_ident2(t, it->ident);
2537 tree_set_value(t, value);
2538
2539 (*addf)(parent, t);
2540 }
2541 }
2542
p_integer_type_definition(range_t r)2543 static type_t p_integer_type_definition(range_t r)
2544 {
2545 // range_constraint
2546
2547 EXTEND("integer type definition");
2548
2549 type_t t = type_new(T_INTEGER);
2550 type_add_dim(t, r);
2551 return t;
2552 }
2553
p_real_type_definition(range_t r)2554 static type_t p_real_type_definition(range_t r)
2555 {
2556 // range_constraint
2557
2558 EXTEND("real type definition");
2559
2560 type_t t = type_new(T_REAL);
2561 type_add_dim(t, r);
2562 return t;
2563 }
2564
p_base_unit_declaration(void)2565 static tree_t p_base_unit_declaration(void)
2566 {
2567 // identifier ;
2568
2569 BEGIN("base unit declaration");
2570
2571 ident_t id = p_identifier();
2572 consume(tSEMI);
2573
2574 tree_t mult = tree_new(T_LITERAL);
2575 tree_set_loc(mult, CURRENT_LOC);
2576 tree_set_subkind(mult, L_INT);
2577 tree_set_ival(mult, 1);
2578
2579 tree_t t = tree_new(T_UNIT_DECL);
2580 tree_set_loc(t, CURRENT_LOC);
2581 tree_set_value(t, mult);
2582 tree_set_ident(t, id);
2583
2584 return t;
2585 }
2586
p_secondary_unit_declaration(void)2587 static tree_t p_secondary_unit_declaration(void)
2588 {
2589 // identifier = physical_literal ;
2590
2591 BEGIN("secondary unit declaration");
2592
2593 ident_t id = p_identifier();
2594 consume(tEQ);
2595 tree_t value = p_physical_literal(p_abstract_literal());
2596 consume(tSEMI);
2597
2598 tree_t u = tree_new(T_UNIT_DECL);
2599 tree_set_ident(u, id);
2600 tree_set_value(u, value);
2601 tree_set_loc(u, CURRENT_LOC);
2602
2603 return u;
2604 }
2605
p_physical_type_definition(range_t r)2606 static type_t p_physical_type_definition(range_t r)
2607 {
2608 // range_constraint units base_unit_declaration
2609 // { secondary_unit_declaration } end units [ name ]
2610
2611 EXTEND("physical type definition");
2612
2613 type_t t = type_new(T_PHYSICAL);
2614
2615 consume(tUNITS);
2616
2617 tree_t base = p_base_unit_declaration();
2618 type_add_unit(t, base);
2619
2620 r.left = int_to_physical(r.left, base);
2621 r.right = int_to_physical(r.right, base);
2622 type_add_dim(t, r);
2623
2624 while (scan(tINT, tREAL, tID)) {
2625 tree_t unit = p_secondary_unit_declaration();
2626 type_add_unit(t, unit);
2627 }
2628
2629 consume(tEND);
2630 consume(tUNITS);
2631
2632 if (peek() == tID) {
2633 ident_t id = p_identifier();
2634 (void)id; // XXX: test this
2635 }
2636
2637 return t;
2638 }
2639
p_enumeration_literal(void)2640 static tree_t p_enumeration_literal(void)
2641 {
2642 // identifier | character_literal
2643
2644 BEGIN("enumeration literal");
2645
2646 tree_t t = tree_new(T_ENUM_LIT);
2647 tree_set_ident(t, p_identifier());
2648 tree_set_loc(t, CURRENT_LOC);
2649
2650 return t;
2651 }
2652
p_enumeration_type_definition(void)2653 static type_t p_enumeration_type_definition(void)
2654 {
2655 // ( enumeration_literal { , enumeration_literal } )
2656
2657 BEGIN("enumeration type definition");
2658
2659 type_t t = type_new(T_ENUM);
2660
2661 consume(tLPAREN);
2662
2663 unsigned pos = 0;
2664 do {
2665 tree_t lit = p_enumeration_literal();
2666 tree_set_pos(lit, pos++);
2667 tree_set_type(lit, t);
2668 type_enum_add_literal(t, lit);
2669 } while (optional(tCOMMA));
2670
2671 consume(tRPAREN);
2672
2673 return t;
2674 }
2675
p_scalar_type_definition(void)2676 static type_t p_scalar_type_definition(void)
2677 {
2678 // enumeration_type_definition | integer_type_definition
2679 // | floating_type_definition | physical_type_definition
2680
2681 BEGIN("scalar type definition");
2682
2683 switch (peek()) {
2684 case tRANGE:
2685 {
2686 range_t r = tree_range(p_range_constraint(), 0);
2687
2688 if (peek() == tUNITS)
2689 return p_physical_type_definition(r);
2690 else {
2691 const bool real = ((r.left != NULL)
2692 && (tree_kind(r.left) == T_LITERAL)
2693 && (tree_subkind(r.left) == L_REAL))
2694 || ((r.right != NULL)
2695 && (tree_kind(r.right) == T_LITERAL)
2696 && (tree_subkind(r.right) == L_REAL));
2697
2698 if (real)
2699 return p_real_type_definition(r);
2700 else
2701 return p_integer_type_definition(r);
2702 }
2703 }
2704
2705 case tLPAREN:
2706 return p_enumeration_type_definition();
2707
2708 default:
2709 expect(tRANGE);
2710 return type_new(T_NONE);
2711 }
2712 }
2713
p_access_type_definition(void)2714 static type_t p_access_type_definition(void)
2715 {
2716 // access subtype_indication
2717
2718 BEGIN("access type definition");
2719
2720 consume(tACCESS);
2721
2722 type_t t = type_new(T_ACCESS);
2723 type_set_access(t, p_subtype_indication());
2724
2725 return t;
2726 }
2727
p_file_type_definition(void)2728 static type_t p_file_type_definition(void)
2729 {
2730 // file of type_mark
2731
2732 BEGIN("file type definition");
2733
2734 consume(tFILE);
2735 consume(tOF);
2736
2737 type_t t = type_new(T_FILE);
2738 type_set_file(t, p_type_mark());
2739
2740 return t;
2741 }
2742
p_element_declaration(type_t rec)2743 static void p_element_declaration(type_t rec)
2744 {
2745 // identifier_list : element_subtype_definition ;
2746
2747 BEGIN("element declaration");
2748
2749 LOCAL_IDENT_LIST ids = p_identifier_list();
2750
2751 consume(tCOLON);
2752
2753 type_t type = p_subtype_indication();
2754
2755 consume(tSEMI);
2756
2757 for (ident_list_t *it = ids; it != NULL; it = it->next) {
2758 tree_t f = tree_new(T_FIELD_DECL);
2759 tree_set_ident(f, it->ident);
2760 tree_set_type(f, type);
2761 tree_set_loc(f, CURRENT_LOC);
2762
2763 type_add_field(rec, f);
2764 }
2765 }
2766
p_record_type_definition(void)2767 static type_t p_record_type_definition(void)
2768 {
2769 // record element_declaration { element_declaration } end record
2770 // [ simple_name ]
2771
2772 BEGIN("record type definition");
2773
2774 consume(tRECORD);
2775
2776 type_t r = type_new(T_RECORD);
2777
2778 do {
2779 p_element_declaration(r);
2780 } while (peek() == tID);
2781
2782 consume(tEND);
2783 consume(tRECORD);
2784
2785 if (peek() == tID) {
2786 ident_t id = p_identifier();
2787 (void)id; // XXX: test this
2788 }
2789
2790 return r;
2791 }
2792
p_index_subtype_definition(void)2793 static type_t p_index_subtype_definition(void)
2794 {
2795 // type_mark range <>
2796
2797 BEGIN("index subtype definition");
2798
2799 type_t t = p_type_mark();
2800
2801 consume(tRANGE);
2802 consume(tBOX);
2803
2804 return t;
2805 }
2806
p_unconstrained_array_definition(void)2807 static type_t p_unconstrained_array_definition(void)
2808 {
2809 // array ( index_subtype_definition { , index_subtype_definition } )
2810 // of subtype_indication
2811
2812 BEGIN("unconstrained array definition");
2813
2814 consume(tARRAY);
2815 consume(tLPAREN);
2816
2817 type_t t = type_new(T_UARRAY);
2818 do {
2819 type_add_index_constr(t, p_index_subtype_definition());
2820 } while (optional(tCOMMA));
2821
2822 consume(tRPAREN);
2823 consume(tOF);
2824
2825 type_set_elem(t, p_subtype_indication());
2826 return t;
2827 }
2828
p_constrained_array_definition(void)2829 static type_t p_constrained_array_definition(void)
2830 {
2831 // array index_constraint of element_subtype_indication
2832
2833 BEGIN("constrained array definition");
2834
2835 consume(tARRAY);
2836
2837 type_t t = type_new(T_CARRAY);
2838 tree_t tmp = p_index_constraint(t); // XXXX
2839 for (int i = 0; i < tree_ranges(tmp); i++)
2840 type_add_dim(t, tree_range(tmp, i));
2841
2842 consume(tOF);
2843
2844 type_set_elem(t, p_subtype_indication());
2845 return t;
2846 }
2847
p_array_type_definition(void)2848 static type_t p_array_type_definition(void)
2849 {
2850 // unconstrained_array_definition | constrained_array_definition
2851
2852 BEGIN("array type definition");
2853
2854 const look_params_t lookp = {
2855 .look = { tBOX },
2856 .stop = { tRPAREN },
2857 .abort = tSEMI,
2858 .nest_in = tLPAREN,
2859 .nest_out = tRPAREN,
2860 .depth = 1
2861 };
2862
2863 if (look_for(&lookp))
2864 return p_unconstrained_array_definition();
2865 else
2866 return p_constrained_array_definition();
2867 }
2868
p_composite_type_definition(void)2869 static type_t p_composite_type_definition(void)
2870 {
2871 // array_type_definition | record_type_definition
2872
2873 BEGIN("composite type definition");
2874
2875 switch (peek()) {
2876 case tRECORD:
2877 return p_record_type_definition();
2878
2879 case tARRAY:
2880 return p_array_type_definition();
2881
2882 default:
2883 expect(tRECORD, tARRAY);
2884 return type_new(T_NONE);
2885 }
2886 }
2887
p_protected_type_declarative_item(type_t type)2888 static void p_protected_type_declarative_item(type_t type)
2889 {
2890 // subprogram_declaration | 2008: subprogram_instantiation_declaration
2891 // | attribute_specification | use_clause
2892
2893 BEGIN("protected type declarative item");
2894
2895 switch (peek()) {
2896 case tATTRIBUTE:
2897 p_attribute_specification((tree_t)type, (add_func_t)type_add_unit);
2898 break;
2899
2900 case tUSE:
2901 p_use_clause((tree_t)type, (add_func_t)type_add_unit);
2902 break;
2903
2904 case tFUNCTION:
2905 case tPROCEDURE:
2906 case tIMPURE:
2907 case tPURE:
2908 {
2909 tree_t spec = p_subprogram_specification();
2910 type_add_decl(type, p_subprogram_declaration(spec));
2911 }
2912 break;
2913
2914 default:
2915 expect(tATTRIBUTE, tUSE, tFUNCTION, tPROCEDURE, tIMPURE, tPURE);
2916 }
2917 }
2918
p_protected_type_declarative_part(type_t type)2919 static void p_protected_type_declarative_part(type_t type)
2920 {
2921 // { protected_type_declarative_item }
2922
2923 BEGIN("protected type declarative part");
2924
2925 while (not_at_token(tEND))
2926 p_protected_type_declarative_item(type);
2927 }
2928
p_protected_type_declaration(void)2929 static type_t p_protected_type_declaration(void)
2930 {
2931 // protected protected_type_declarative_part end protected [ simple_name ]
2932
2933 BEGIN("protected type declaration");
2934
2935 consume(tPROTECTED);
2936
2937 type_t type = type_new(T_PROTECTED);
2938
2939 p_protected_type_declarative_part(type);
2940
2941 consume(tEND);
2942 consume(tPROTECTED);
2943
2944 if (peek() == tID)
2945 type_set_ident(type, p_identifier());
2946
2947 return type;
2948 }
2949
p_protected_type_definition(void)2950 static type_t p_protected_type_definition(void)
2951 {
2952 // protected_type_declaration | protected_type_body
2953
2954 BEGIN("protected type definition");
2955
2956 // Protected type bodies are trees rather than types and so handled
2957 // elsewhere to simplify the parser
2958
2959 return p_protected_type_declaration();
2960 }
2961
p_type_definition(void)2962 static type_t p_type_definition(void)
2963 {
2964 // scalar_type_definition | composite_type_definition
2965 // | access_type_definition | file_type_definition
2966 // | 2000: protected_type_definition
2967
2968 BEGIN("type definition");
2969
2970 switch (peek()) {
2971 case tRANGE:
2972 case tLPAREN:
2973 return p_scalar_type_definition();
2974
2975 case tACCESS:
2976 return p_access_type_definition();
2977
2978 case tFILE:
2979 return p_file_type_definition();
2980
2981 case tRECORD:
2982 case tARRAY:
2983 return p_composite_type_definition();
2984
2985 case tPROTECTED:
2986 return p_protected_type_definition();
2987
2988 default:
2989 expect(tRANGE, tACCESS, tFILE, tRECORD, STD(00, tPROTECTED));
2990 return type_new(T_NONE);
2991 }
2992 }
2993
p_full_type_declaration(ident_t id)2994 static type_t p_full_type_declaration(ident_t id)
2995 {
2996 // type identifier is type_definition ;
2997
2998 EXTEND("full type declaration");
2999
3000 consume(tIS);
3001
3002 type_t t = p_type_definition();
3003 type_set_ident(t, id);
3004
3005 consume(tSEMI);
3006
3007 return t;
3008 }
3009
p_incomplete_type_declaration(ident_t id)3010 static type_t p_incomplete_type_declaration(ident_t id)
3011 {
3012 // type identifier ;
3013
3014 EXTEND("incomplete type declaration");
3015
3016 consume(tSEMI);
3017
3018 type_t t = type_new(T_INCOMPLETE);
3019 type_set_ident(t, id);
3020
3021 return t;
3022 }
3023
p_type_declaration(void)3024 static tree_t p_type_declaration(void)
3025 {
3026 // full_type_declaration | incomplete_type_declaration
3027
3028 BEGIN("type declaration");
3029
3030 consume(tTYPE);
3031
3032 ident_t id = p_identifier();
3033
3034 // Protected type bodies are broken out here to avoid having to
3035 // return a dummy type for them in p_full_type_declaration
3036
3037 const bool is_prot_body =
3038 (peek_nth(1) == tIS)
3039 && (peek_nth(2) == tPROTECTED)
3040 && (peek_nth(3) == tBODY);
3041
3042 if (is_prot_body) {
3043 consume(tIS);
3044 tree_t body = p_protected_type_body();
3045 consume(tSEMI);
3046
3047 if (tree_has_ident(body)) {
3048 if (tree_ident(body) != id)
3049 parse_error(CURRENT_LOC, "expected protected body trailing label "
3050 "to match %s", istr(id));
3051 }
3052 else
3053 tree_set_ident(body, id);
3054
3055 return body;
3056 }
3057 else {
3058 type_t type;
3059 if (peek() == tSEMI)
3060 type = p_incomplete_type_declaration(id);
3061 else
3062 type = p_full_type_declaration(id);
3063
3064 type_set_ident(type, id);
3065
3066 tree_t t = tree_new(T_TYPE_DECL);
3067 tree_set_ident(t, id);
3068 tree_set_type(t, type);
3069 tree_set_loc(t, CURRENT_LOC);
3070
3071 return t;
3072 }
3073 }
3074
p_subtype_declaration(void)3075 static tree_t p_subtype_declaration(void)
3076 {
3077 // subtype identifier is subtype_indication ;
3078
3079 BEGIN("subtype declaration");
3080
3081 consume(tSUBTYPE);
3082 ident_t id = p_identifier();
3083 consume(tIS);
3084 type_t sub = p_subtype_indication();
3085 consume(tSEMI);
3086
3087 if (type_kind(sub) != T_SUBTYPE) {
3088 // Case where subtype_indication did not impose any
3089 // constraint so we must create the subtype object here
3090 type_t new = type_new(T_SUBTYPE);
3091 type_set_base(new, sub);
3092
3093 sub = new;
3094 }
3095 type_set_ident(sub, id);
3096
3097 tree_t t = tree_new(T_TYPE_DECL);
3098 tree_set_ident(t, id);
3099 tree_set_type(t, sub);
3100 tree_set_loc(t, CURRENT_LOC);
3101
3102 return t;
3103 }
3104
p_constant_declaration(tree_t parent)3105 static void p_constant_declaration(tree_t parent)
3106 {
3107 // constant identifier_list : subtype_indication [ := expression ] ;
3108
3109 BEGIN("constant declaration");
3110
3111 consume(tCONSTANT);
3112
3113 LOCAL_IDENT_LIST ids = p_identifier_list();
3114
3115 consume(tCOLON);
3116
3117 type_t type = p_subtype_indication();
3118
3119 tree_t init = NULL;
3120 if (optional(tASSIGN))
3121 init = p_expression();
3122
3123 consume(tSEMI);
3124
3125 for (ident_list_t *it = ids; it != NULL; it = it->next) {
3126 tree_t t = tree_new(T_CONST_DECL);
3127 tree_set_ident(t, it->ident);
3128 tree_set_type(t, type);
3129 tree_set_loc(t, CURRENT_LOC);
3130 if (init != NULL)
3131 tree_set_value(t, init);
3132
3133 tree_add_decl(parent, t);
3134 }
3135 }
3136
p_assertion(void)3137 static tree_t p_assertion(void)
3138 {
3139 // assert condition [ report expression ] [ severity expression ]
3140
3141 BEGIN("assertion");
3142
3143 tree_t s = tree_new(T_ASSERT);
3144
3145 consume(tASSERT);
3146
3147 tree_set_value(s, p_expression());
3148
3149 if (optional(tREPORT))
3150 tree_set_message(s, p_expression());
3151
3152 if (optional(tSEVERITY))
3153 tree_set_severity(s, p_expression());
3154 else {
3155 tree_t sev = tree_new(T_REF);
3156 tree_set_ident(sev, ident_new("ERROR"));
3157
3158 tree_set_severity(s, sev);
3159 }
3160
3161 tree_set_loc(s, CURRENT_LOC);
3162 return s;
3163 }
3164
p_concurrent_assertion_statement(ident_t label)3165 static tree_t p_concurrent_assertion_statement(ident_t label)
3166 {
3167 // [ label : ] [ postponed ] assertion ;
3168
3169 BEGIN("concurrent assertion statement");
3170
3171 const bool postponed = optional(tPOSTPONED);
3172
3173 tree_t s = p_assertion();
3174 tree_change_kind(s, T_CASSERT);
3175
3176 consume(tSEMI);
3177
3178 const loc_t *loc = CURRENT_LOC;
3179 tree_set_loc(s, loc);
3180
3181 if (label == NULL)
3182 label = loc_to_ident(loc);
3183 tree_set_ident(s, label);
3184
3185 if (postponed)
3186 tree_set_flag(s, TREE_F_POSTPONED);
3187
3188 return s;
3189 }
3190
p_designator(void)3191 static ident_t p_designator(void)
3192 {
3193 // identifier | operator_symbol
3194
3195 BEGIN("designator");
3196
3197 switch (peek()) {
3198 case tID:
3199 return p_identifier();
3200 case tSTRING:
3201 return p_operator_symbol();
3202 default:
3203 expect(tID, tSTRING);
3204 return ident_new("error");
3205 }
3206 }
3207
p_subprogram_specification(void)3208 static tree_t p_subprogram_specification(void)
3209 {
3210 // procedure designator [ ( formal_parameter_list ) ]
3211 // | [ pure | impure ] function designator [ ( formal_parameter_list ) ]
3212 // return type_mark
3213
3214 BEGIN("subprogram specification");
3215
3216 tree_t t = NULL;
3217 type_t type = NULL;
3218
3219 bool impure = false;
3220 if (optional(tIMPURE))
3221 impure = true;
3222 else if (optional(tPURE))
3223 ;
3224
3225 switch (one_of(tFUNCTION, tPROCEDURE)) {
3226 case tFUNCTION:
3227 t = tree_new(T_FUNC_DECL);
3228 type = type_new(T_FUNC);
3229 break;
3230
3231 case tPROCEDURE:
3232 t = tree_new(T_PROC_DECL);
3233 type = type_new(T_PROC);
3234 break;
3235
3236 default:
3237 return tree_new(T_FUNC_DECL);
3238 }
3239
3240 tree_set_type(t, type);
3241 tree_set_ident(t, p_designator());
3242
3243 type_set_ident(type, tree_ident(t));
3244
3245 if (impure)
3246 tree_set_flag(t, TREE_F_IMPURE);
3247
3248 if (optional(tLPAREN)) {
3249 //const class_t class =
3250 // (tree_kind(t) == T_FUNC_DECL) ? C_CONSTANT : C_VARIABLE;
3251 p_interface_list(C_DEFAULT, t, tree_add_port);
3252 consume(tRPAREN);
3253 }
3254
3255 if (tree_kind(t) == T_FUNC_DECL) {
3256 consume(tRETURN);
3257 type_set_result(type, p_type_mark());
3258 }
3259
3260 tree_set_loc(t, CURRENT_LOC);
3261 return t;
3262 }
3263
p_variable_declaration(tree_t parent)3264 static void p_variable_declaration(tree_t parent)
3265 {
3266 // [ shared ] variable identifier_list : subtype_indication
3267 // [ := expression ] ;
3268
3269 BEGIN("variable declaration");
3270
3271 const bool shared = optional(tSHARED);
3272
3273 consume(tVARIABLE);
3274
3275 LOCAL_IDENT_LIST ids = p_identifier_list();
3276
3277 consume(tCOLON);
3278
3279 type_t type = p_subtype_indication();
3280
3281 tree_t init = NULL;
3282 if (optional(tASSIGN))
3283 init = p_expression();
3284
3285 consume(tSEMI);
3286
3287 const loc_t *loc = CURRENT_LOC;
3288
3289 for (ident_list_t *it = ids; it != NULL; it = it->next) {
3290 tree_t t = tree_new(T_VAR_DECL);
3291 tree_set_loc(t, loc);
3292 tree_set_ident(t, it->ident);
3293 tree_set_type(t, type);
3294
3295 if (init != NULL)
3296 tree_set_value(t, init);
3297
3298 if (shared)
3299 tree_set_flag(t, TREE_F_SHARED);
3300
3301 tree_add_decl(parent, t);
3302 }
3303 }
3304
p_signal_declaration(tree_t parent)3305 static void p_signal_declaration(tree_t parent)
3306 {
3307 // signal identifier_list : subtype_indication [ signal_kind ]
3308 // [ := expression ] ;
3309
3310 BEGIN("signal declaration");
3311
3312 consume(tSIGNAL);
3313
3314 LOCAL_IDENT_LIST ids = p_identifier_list();
3315
3316 consume(tCOLON);
3317
3318 type_t type = p_subtype_indication();
3319
3320 // [ signal_kind ]
3321
3322 tree_t init = NULL;
3323 if (optional(tASSIGN))
3324 init = p_expression();
3325
3326 consume(tSEMI);
3327
3328 const loc_t *loc = CURRENT_LOC;
3329
3330 for (ident_list_t *it = ids; it != NULL; it = it->next) {
3331 tree_t t = tree_new(T_SIGNAL_DECL);
3332 tree_set_loc(t, loc);
3333 tree_set_ident(t, it->ident);
3334 tree_set_type(t, type);
3335
3336 if (init != NULL)
3337 tree_set_value(t, init);
3338
3339 tree_add_decl(parent, t);
3340 }
3341 }
3342
p_signature(void)3343 static type_t p_signature(void)
3344 {
3345 // [ [ type_mark { , type_mark } ] [ return type_mark ] ]
3346
3347 BEGIN("signature");
3348
3349 const look_params_t lookp = {
3350 .look = { tRETURN },
3351 .stop = { tRSQUARE },
3352 .abort = tSEMI
3353 };
3354
3355 type_t type = type_new(look_for(&lookp) ? T_FUNC : T_PROC);
3356
3357 consume(tLSQUARE);
3358
3359 if (not_at_token(tRETURN, tRSQUARE)) {
3360 type_add_param(type, p_type_mark());
3361 while (optional(tCOMMA))
3362 type_add_param(type, p_type_mark());
3363 }
3364
3365 if (optional(tRETURN))
3366 type_set_result(type, p_type_mark());
3367
3368 consume(tRSQUARE);
3369
3370 return type;
3371 }
3372
p_alias_declaration(void)3373 static tree_t p_alias_declaration(void)
3374 {
3375 // alias alias_designator [ : subtype_indication ] is name [ signature ] ;
3376
3377 BEGIN("alias declaration");
3378
3379 tree_t t = tree_new(T_ALIAS);
3380
3381 bool has_subtype_indication = false;
3382 consume(tALIAS);
3383 tree_set_ident(t, p_identifier());
3384 if (optional(tCOLON)) {
3385 tree_set_type(t, p_subtype_indication());
3386 has_subtype_indication = true;
3387 }
3388 consume(tIS);
3389 tree_set_value(t, p_name());
3390
3391 if (peek() == tLSQUARE) {
3392 tree_set_type(t, p_signature());
3393 if (has_subtype_indication)
3394 parse_error(CURRENT_LOC, "alias declaration may not contain both a "
3395 "signature and a subtype indication");
3396 }
3397
3398 consume(tSEMI);
3399
3400 tree_set_loc(t, CURRENT_LOC);
3401 return t;
3402 }
3403
p_file_open_information(tree_t * mode,tree_t * name)3404 static void p_file_open_information(tree_t *mode, tree_t *name)
3405 {
3406 // [ open expression ] is file_logical_name
3407
3408 BEGIN("file open information");
3409
3410 if (optional(tOPEN))
3411 *mode = p_expression();
3412 else
3413 *mode = NULL;
3414
3415 if (optional(tIS)) {
3416 if ((*mode == NULL) && scan(tIN, tOUT)) {
3417 // VHDL-87 compatibility
3418 switch (one_of(tIN, tOUT)) {
3419 case tIN:
3420 *mode = tree_new(T_REF);
3421 tree_set_ident(*mode, ident_new("READ_MODE"));
3422 break;
3423
3424 case tOUT:
3425 *mode = tree_new(T_REF);
3426 tree_set_ident(*mode, ident_new("WRITE_MODE"));
3427 break;
3428 }
3429 }
3430
3431 *name = p_expression();
3432
3433 if (*mode == NULL) {
3434 *mode = tree_new(T_REF);
3435 tree_set_ident(*mode, ident_new("READ_MODE"));
3436 }
3437 }
3438 else
3439 *name = NULL;
3440 }
3441
p_file_declaration(tree_t parent)3442 static void p_file_declaration(tree_t parent)
3443 {
3444 // file identifier_list : subtype_indication [ file_open_information ] ;
3445
3446 BEGIN("file declaration");
3447
3448 consume(tFILE);
3449
3450 LOCAL_IDENT_LIST ids = p_identifier_list();
3451
3452 consume(tCOLON);
3453
3454 type_t type = p_subtype_indication();
3455
3456 tree_t mode, name;
3457 p_file_open_information(&mode, &name);
3458
3459 consume(tSEMI);
3460
3461 for (ident_list_t *it = ids; it != NULL; it = it->next) {
3462 tree_t t = tree_new(T_FILE_DECL);
3463 tree_set_ident(t, it->ident);
3464 tree_set_type(t, type);
3465 if (name != NULL) {
3466 tree_set_file_mode(t, mode);
3467 tree_set_value(t, name);
3468 }
3469 tree_set_loc(t, CURRENT_LOC);
3470
3471 tree_add_decl(parent, t);
3472 }
3473 }
3474
p_protected_type_body_declarative_item(tree_t body)3475 static void p_protected_type_body_declarative_item(tree_t body)
3476 {
3477 // subprogram_declaration | subprogram_body | type_declaration
3478 // | subtype_declaration | constant_declaration | variable_declaration
3479 // | file_declaration | alias_declaration | attribute_declaration
3480 // | attribute_specification | use_clause | group_template_declaration
3481 // | group_declaration
3482
3483 BEGIN("protected type body declarative item");
3484
3485 switch (peek()) {
3486 case tATTRIBUTE:
3487 if (peek_nth(3) == tOF)
3488 p_attribute_specification(body, tree_add_decl);
3489 else
3490 tree_add_decl(body, p_attribute_declaration());
3491 break;
3492
3493 case tTYPE:
3494 tree_add_decl(body, p_type_declaration());
3495 break;
3496
3497 case tSUBTYPE:
3498 tree_add_decl(body, p_subtype_declaration());
3499 break;
3500
3501 case tCONSTANT:
3502 p_constant_declaration(body);
3503 break;
3504
3505 case tALIAS:
3506 tree_add_decl(body, p_alias_declaration());
3507 break;
3508
3509 case tFUNCTION:
3510 case tPROCEDURE:
3511 case tIMPURE:
3512 case tPURE:
3513 {
3514 tree_t spec = p_subprogram_specification();
3515 if (peek() == tSEMI)
3516 tree_add_decl(body, p_subprogram_declaration(spec));
3517 else
3518 tree_add_decl(body, p_subprogram_body(spec));
3519 }
3520 break;
3521
3522 case tVARIABLE:
3523 p_variable_declaration(body);
3524 break;
3525
3526 case tUSE:
3527 p_use_clause(body, tree_add_decl);
3528 break;
3529
3530 case tFILE:
3531 p_file_declaration(body);
3532 break;
3533
3534 default:
3535 expect(tATTRIBUTE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3536 tIMPURE, tPURE, tALIAS, tVARIABLE, tUSE, tFILE);
3537 }
3538 }
3539
p_protected_type_body_declarative_part(tree_t body)3540 static void p_protected_type_body_declarative_part(tree_t body)
3541 {
3542 // { protected_type_body_declarative_item }
3543
3544 BEGIN("protected type body declarative part");
3545
3546 while (not_at_token(tEND))
3547 p_protected_type_body_declarative_item(body);
3548 }
3549
p_protected_type_body(void)3550 static tree_t p_protected_type_body(void)
3551 {
3552 // protected body protected_type_body_declarative_part end protected body
3553 // [ simple name ]
3554
3555 BEGIN("protected type body");
3556
3557 consume(tPROTECTED);
3558 consume(tBODY);
3559
3560 tree_t body = tree_new(T_PROT_BODY);
3561 p_protected_type_body_declarative_part(body);
3562
3563 consume(tEND);
3564 consume(tPROTECTED);
3565 consume(tBODY);
3566
3567 if (peek() == tID)
3568 tree_set_ident(body, p_identifier());
3569
3570 tree_set_loc(body, CURRENT_LOC);
3571 return body;
3572 }
3573
p_entity_declarative_item(tree_t entity)3574 static void p_entity_declarative_item(tree_t entity)
3575 {
3576 // subprogram_declaration | subprogram_body | type_declaration
3577 // | subtype_declaration | constant_declaration | signal_declaration
3578 // | shared_variable_declaration | file_declaration | alias_declaration
3579 // | attribute_declaration | attribute_specification
3580 // | disconnection_specification | use_clause | group_template_declaration
3581 // | group_declaration
3582
3583 BEGIN("entity declarative item");
3584
3585 switch (peek()) {
3586 case tATTRIBUTE:
3587 if (peek_nth(3) == tOF)
3588 p_attribute_specification(entity, tree_add_decl);
3589 else
3590 tree_add_decl(entity, p_attribute_declaration());
3591 break;
3592
3593 case tTYPE:
3594 tree_add_decl(entity, p_type_declaration());
3595 break;
3596
3597 case tSUBTYPE:
3598 tree_add_decl(entity, p_subtype_declaration());
3599 break;
3600
3601 case tCONSTANT:
3602 p_constant_declaration(entity);
3603 break;
3604
3605 case tALIAS:
3606 tree_add_decl(entity, p_alias_declaration());
3607 break;
3608
3609 case tFUNCTION:
3610 case tPROCEDURE:
3611 case tIMPURE:
3612 case tPURE:
3613 {
3614 tree_t spec = p_subprogram_specification();
3615 if (peek() == tSEMI)
3616 tree_add_decl(entity, p_subprogram_declaration(spec));
3617 else
3618 tree_add_decl(entity, p_subprogram_body(spec));
3619 }
3620 break;
3621
3622 case tUSE:
3623 p_use_clause(entity, tree_add_decl);
3624 break;
3625
3626 default:
3627 expect(tATTRIBUTE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3628 tIMPURE, tPURE, tALIAS, tUSE);
3629 }
3630 }
3631
p_entity_declarative_part(tree_t entity)3632 static void p_entity_declarative_part(tree_t entity)
3633 {
3634 // { entity_declarative_item }
3635
3636 BEGIN("entity declarative part");
3637
3638 while (not_at_token(tEND, tBEGIN))
3639 p_entity_declarative_item(entity);
3640 }
3641
p_subprogram_declarative_item(tree_t sub)3642 static void p_subprogram_declarative_item(tree_t sub)
3643 {
3644 // subprogram_declaration | subprogram_body | type_declaration
3645 // | subtype_declaration | constant_declaration | variable_declaration
3646 // | file_declaration | alias_declaration | attribute_declaration
3647 // | attribute_specification | use_clause | group_template_declaration
3648 // | group_declaration
3649
3650 BEGIN("subprogram delcarative item");
3651
3652 switch (peek()) {
3653 case tVARIABLE:
3654 p_variable_declaration(sub);
3655 break;
3656
3657 case tTYPE:
3658 tree_add_decl(sub, p_type_declaration());
3659 break;
3660
3661 case tALIAS:
3662 tree_add_decl(sub, p_alias_declaration());
3663 break;
3664
3665 case tCONSTANT:
3666 p_constant_declaration(sub);
3667 break;
3668
3669 case tFUNCTION:
3670 case tPROCEDURE:
3671 case tIMPURE:
3672 case tPURE:
3673 {
3674 tree_t spec = p_subprogram_specification();
3675 if (peek() == tSEMI)
3676 tree_add_decl(sub, p_subprogram_declaration(spec));
3677 else
3678 tree_add_decl(sub, p_subprogram_body(spec));
3679 }
3680 break;
3681
3682 case tATTRIBUTE:
3683 if (peek_nth(3) == tOF)
3684 p_attribute_specification(sub, tree_add_decl);
3685 else
3686 tree_add_decl(sub, p_attribute_declaration());
3687 break;
3688
3689 case tSUBTYPE:
3690 tree_add_decl(sub, p_subtype_declaration());
3691 break;
3692
3693 case tUSE:
3694 p_use_clause(sub, tree_add_decl);
3695 break;
3696
3697 case tFILE:
3698 p_file_declaration(sub);
3699 break;
3700
3701 default:
3702 expect(tVARIABLE, tTYPE, tALIAS, tCONSTANT, tFUNCTION, tPROCEDURE,
3703 tIMPURE, tPURE, tATTRIBUTE, tSUBTYPE, tUSE, tFILE);
3704 }
3705 }
3706
p_subprogram_declarative_part(tree_t sub)3707 static void p_subprogram_declarative_part(tree_t sub)
3708 {
3709 // { subprogram_declarative_item }
3710
3711 BEGIN("subprogram declarative part");
3712
3713 while (not_at_token(tBEGIN))
3714 p_subprogram_declarative_item(sub);
3715 }
3716
p_sequence_of_statements(tree_t parent,add_func_t addf)3717 static void p_sequence_of_statements(tree_t parent, add_func_t addf)
3718 {
3719 // { sequential_statement }
3720
3721 BEGIN("sequence of statements");
3722
3723 while (not_at_token(tEND, tELSE, tELSIF, tWHEN))
3724 (*addf)(parent, p_sequential_statement());
3725 }
3726
p_trailing_label(ident_t label)3727 static void p_trailing_label(ident_t label)
3728 {
3729 // [ label ]
3730
3731 if ((peek() == tID) || (peek() == tSTRING)) {
3732 ident_t trailing = p_designator();
3733 if (label == NULL)
3734 parse_error(&last_loc, "unexpected trailing label for %s without "
3735 "label", hint_str);
3736 else if (trailing != label)
3737 parse_error(&last_loc, "expected trailing %s label to match %s",
3738 hint_str, istr(label));
3739 }
3740 }
3741
p_subprogram_body(tree_t spec)3742 static tree_t p_subprogram_body(tree_t spec)
3743 {
3744 // subprogram_specification is subprogram_declarative_part begin
3745 // subprogram_statement_part end [ subprogram_kind ] [ designator ] ;
3746
3747 EXTEND("subprogram body");
3748
3749 consume(tIS);
3750
3751 const tree_kind_t kind =
3752 (tree_kind(spec) == T_FUNC_DECL) ? T_FUNC_BODY : T_PROC_BODY;
3753 tree_change_kind(spec, kind);
3754
3755 p_subprogram_declarative_part(spec);
3756
3757 consume(tBEGIN);
3758
3759 p_sequence_of_statements(spec, tree_add_stmt);
3760
3761 consume(tEND);
3762
3763 switch (peek()) {
3764 case tFUNCTION:
3765 consume(tFUNCTION);
3766 // XXX: check is function;
3767 break;
3768
3769 case tPROCEDURE:
3770 consume(tPROCEDURE);
3771 // XXX: check is procedure
3772 break;
3773
3774 default:
3775 break;
3776 }
3777
3778 p_trailing_label(tree_ident(spec));
3779 consume(tSEMI);
3780
3781 tree_set_loc(spec, CURRENT_LOC);
3782 return spec;
3783 }
3784
p_subprogram_declaration(tree_t spec)3785 static tree_t p_subprogram_declaration(tree_t spec)
3786 {
3787 // subprogram_specification ;
3788
3789 EXTEND("subprogram declaration");
3790
3791 consume(tSEMI);
3792 return spec;
3793 }
3794
p_sensitivity_list(tree_t proc)3795 static void p_sensitivity_list(tree_t proc)
3796 {
3797 // name { , name }
3798
3799 BEGIN("sensitivity list");
3800
3801 tree_add_trigger(proc, p_name());
3802
3803 while (optional(tCOMMA))
3804 tree_add_trigger(proc, p_name());
3805 }
3806
p_process_declarative_item(tree_t proc)3807 static void p_process_declarative_item(tree_t proc)
3808 {
3809 // subprogram_declaration | subprogram_body | type_declaration
3810 // | subtype_declaration | constant_declaration | variable_declaration
3811 // | file_declaration | alias_declaration | attribute_declaration
3812 // | attribute_specification | use_clause | group_template_declaration
3813 // | group_declaration
3814
3815 BEGIN("process declarative item");
3816
3817 switch (peek()) {
3818 case tVARIABLE:
3819 p_variable_declaration(proc);
3820 break;
3821
3822 case tTYPE:
3823 tree_add_decl(proc, p_type_declaration());
3824 break;
3825
3826 case tSUBTYPE:
3827 tree_add_decl(proc, p_subtype_declaration());
3828 break;
3829
3830 case tCONSTANT:
3831 p_constant_declaration(proc);
3832 break;
3833
3834 case tFUNCTION:
3835 case tPROCEDURE:
3836 case tIMPURE:
3837 case tPURE:
3838 {
3839 tree_t spec = p_subprogram_specification();
3840 if (peek() == tSEMI)
3841 tree_add_decl(proc, p_subprogram_declaration(spec));
3842 else
3843 tree_add_decl(proc, p_subprogram_body(spec));
3844 }
3845 break;
3846
3847 case tATTRIBUTE:
3848 if (peek_nth(3) == tOF)
3849 p_attribute_specification(proc, tree_add_decl);
3850 else
3851 tree_add_decl(proc, p_attribute_declaration());
3852 break;
3853
3854 case tUSE:
3855 p_use_clause(proc, tree_add_decl);
3856 break;
3857
3858 case tALIAS:
3859 tree_add_decl(proc, p_alias_declaration());
3860 break;
3861
3862 case tFILE:
3863 p_file_declaration(proc);
3864 break;
3865
3866 default:
3867 expect(tVARIABLE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3868 tIMPURE, tPURE, tATTRIBUTE, tUSE, tALIAS, tFILE);
3869 }
3870 }
3871
p_process_declarative_part(tree_t proc)3872 static void p_process_declarative_part(tree_t proc)
3873 {
3874 // { process_declarative_item }
3875
3876 BEGIN("process declarative part");
3877
3878 while (not_at_token(tBEGIN))
3879 p_process_declarative_item(proc);
3880 }
3881
p_process_statement_part(tree_t proc)3882 static void p_process_statement_part(tree_t proc)
3883 {
3884 // { sequential_statement }
3885
3886 BEGIN("process statement part");
3887
3888 p_sequence_of_statements(proc, tree_add_stmt);
3889 }
3890
p_process_statement(ident_t label)3891 static tree_t p_process_statement(ident_t label)
3892 {
3893 // [ process_label : ] [ postponed ] process [ ( sensitivity_list ) ] [ is ]
3894 // process_declarative_part begin process_statement_part end [ postponed ]
3895 // process [ label ] ;
3896
3897 EXTEND("process statement");
3898
3899 tree_t t = tree_new(T_PROCESS);
3900
3901 const bool postponed = optional(tPOSTPONED);
3902
3903 consume(tPROCESS);
3904
3905 if (optional(tLPAREN)) {
3906 p_sensitivity_list(t);
3907 consume(tRPAREN);
3908 }
3909
3910 optional(tIS);
3911
3912 p_process_declarative_part(t);
3913
3914 consume(tBEGIN);
3915
3916 p_process_statement_part(t);
3917
3918 consume(tEND);
3919 if (postponed)
3920 optional(tPOSTPONED);
3921 consume(tPROCESS);
3922 p_trailing_label(label);
3923 consume(tSEMI);
3924
3925 const loc_t *loc = CURRENT_LOC;
3926 tree_set_loc(t, loc);
3927
3928 if (label == NULL) {
3929 label = loc_to_ident(loc);
3930 tree_set_flag(t, TREE_F_SYNTHETIC_NAME);
3931 }
3932 tree_set_ident(t, label);
3933
3934 if (postponed)
3935 tree_set_flag(t, TREE_F_POSTPONED);
3936
3937 return t;
3938 }
3939
p_entity_statement(void)3940 static tree_t p_entity_statement(void)
3941 {
3942 // concurrent_assertion_statement | concurrent_procedure_call_statement
3943 // | process_statement
3944
3945 BEGIN("entity statement");
3946
3947 ident_t label = NULL;
3948 if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
3949 label = p_identifier();
3950 consume(tCOLON);
3951 }
3952
3953 switch (peek()) {
3954 case tASSERT:
3955 return p_concurrent_assertion_statement(label);
3956
3957 case tPROCESS:
3958 return p_process_statement(label);
3959
3960 case tPOSTPONED:
3961 if (peek_nth(2) == tASSERT)
3962 return p_concurrent_assertion_statement(label);
3963 else
3964 return p_process_statement(label);
3965
3966 default:
3967 expect(tASSERT, tPOSTPONED);
3968 return tree_new(T_NULL);
3969 }
3970 }
3971
p_entity_statement_part(tree_t entity)3972 static void p_entity_statement_part(tree_t entity)
3973 {
3974 // { entity_statement }
3975
3976 BEGIN("entity statement part");
3977
3978 while (not_at_token(tEND))
3979 tree_add_stmt(entity, p_entity_statement());
3980 }
3981
p_entity_declaration(tree_t unit)3982 static void p_entity_declaration(tree_t unit)
3983 {
3984 // entity identifier is entity_header entity_declarative_part
3985 // [ begin entity_statement_part ] end [ entity ] [ entity_simple_name ] ;
3986
3987 BEGIN("entity declaration");
3988
3989 tree_change_kind(unit, T_ENTITY);
3990
3991 consume(tENTITY);
3992
3993 ident_t id = p_identifier();
3994 tree_set_ident(unit, id);
3995
3996 consume(tIS);
3997
3998 p_entity_header(unit);
3999 p_entity_declarative_part(unit);
4000
4001 if (optional(tBEGIN))
4002 p_entity_statement_part(unit);
4003
4004 consume(tEND);
4005 optional(tENTITY);
4006 p_trailing_label(id);
4007 consume(tSEMI);
4008
4009 tree_set_loc(unit, CURRENT_LOC);
4010 }
4011
p_component_declaration(void)4012 static tree_t p_component_declaration(void)
4013 {
4014 // component identifier [ is ] [ generic_clause ] [ port_clause ]
4015 // end component [ simple_name ] ;
4016
4017 BEGIN("component declaration");
4018
4019 tree_t c = tree_new(T_COMPONENT);
4020
4021 consume(tCOMPONENT);
4022 tree_set_ident(c, p_identifier());
4023 optional(tIS);
4024
4025 if (peek() == tGENERIC)
4026 p_generic_clause(c);
4027
4028 if (peek() == tPORT)
4029 p_port_clause(c);
4030
4031 consume(tEND);
4032 consume(tCOMPONENT);
4033 p_trailing_label(tree_ident(c));
4034 consume(tSEMI);
4035
4036 tree_set_loc(c, CURRENT_LOC);
4037 return c;
4038 }
4039
p_package_declarative_item(tree_t pack)4040 static void p_package_declarative_item(tree_t pack)
4041 {
4042 // subprogram_declaration | type_declaration | subtype_declaration
4043 // | constant_declaration | signal_declaration
4044 // | shared_variable_declaration | file_declaration | alias_declaration
4045 // | component_declaration | attribute_declaration
4046 // | attribute_specification | disconnection_specification | use_clause
4047 // | group_template_declaration | group_declaration
4048 //
4049
4050 BEGIN("package declarative item");
4051
4052 switch (peek()) {
4053 case tTYPE:
4054 tree_add_decl(pack, p_type_declaration());
4055 break;
4056
4057 case tFUNCTION:
4058 case tPROCEDURE:
4059 case tIMPURE:
4060 case tPURE:
4061 {
4062 tree_t spec = p_subprogram_specification();
4063 if (peek() == tSEMI)
4064 tree_add_decl(pack, p_subprogram_declaration(spec));
4065 else
4066 tree_add_decl(pack, p_subprogram_body(spec));
4067 }
4068 break;
4069
4070 case tSUBTYPE:
4071 tree_add_decl(pack, p_subtype_declaration());
4072 break;
4073
4074 case tSIGNAL:
4075 p_signal_declaration(pack);
4076 break;
4077
4078 case tATTRIBUTE:
4079 if (peek_nth(3) == tOF)
4080 p_attribute_specification(pack, tree_add_decl);
4081 else
4082 tree_add_decl(pack, p_attribute_declaration());
4083 break;
4084
4085 case tCONSTANT:
4086 p_constant_declaration(pack);
4087 break;
4088
4089 case tCOMPONENT:
4090 tree_add_decl(pack, p_component_declaration());
4091 break;
4092
4093 case tFILE:
4094 p_file_declaration(pack);
4095 break;
4096
4097 case tSHARED:
4098 p_variable_declaration(pack);
4099 break;
4100
4101 case tALIAS:
4102 tree_add_decl(pack, p_alias_declaration());
4103 break;
4104
4105 case tUSE:
4106 p_use_clause(pack, tree_add_decl);
4107 break;
4108
4109 default:
4110 expect(tTYPE, tFUNCTION, tPROCEDURE, tIMPURE, tPURE, tSUBTYPE, tSIGNAL,
4111 tATTRIBUTE, tCONSTANT, tCOMPONENT, tFILE, tSHARED, tALIAS, tUSE);
4112 }
4113 }
4114
p_package_declarative_part(tree_t pack)4115 static void p_package_declarative_part(tree_t pack)
4116 {
4117 // { package_declarative_item }
4118
4119 BEGIN("package declarative part");
4120
4121 while (not_at_token(tEND))
4122 p_package_declarative_item(pack);
4123 }
4124
p_package_declaration(tree_t unit)4125 static void p_package_declaration(tree_t unit)
4126 {
4127 // package identifier is package_declarative_part end [ package ]
4128 // [ simple_name ] ;
4129
4130 BEGIN("package declaration");
4131
4132 consume(tPACKAGE);
4133
4134 tree_change_kind(unit, T_PACKAGE);
4135 tree_set_ident(unit, p_identifier());
4136
4137 consume(tIS);
4138
4139 p_package_declarative_part(unit);
4140
4141 consume(tEND);
4142 optional(tPACKAGE);
4143 p_trailing_label(tree_ident(unit));
4144 consume(tSEMI);
4145
4146 tree_set_loc(unit, CURRENT_LOC);
4147 }
4148
p_instantiation_list(void)4149 static ident_list_t *p_instantiation_list(void)
4150 {
4151 // label { , label } | others | all
4152
4153 switch (peek()) {
4154 case tID:
4155 return p_identifier_list();
4156
4157 case tOTHERS:
4158 consume(tOTHERS);
4159 return NULL;
4160
4161 case tALL:
4162 {
4163 consume(tALL);
4164
4165 ident_list_t *result = NULL;
4166 ident_list_add(&result, all_i);
4167 return result;
4168 }
4169
4170 default:
4171 expect(tID, tOTHERS, tALL);
4172 return NULL;
4173 }
4174 }
4175
p_component_specification(ident_t * comp_name)4176 static ident_list_t *p_component_specification(ident_t *comp_name)
4177 {
4178 // instantiation_list : name
4179
4180 BEGIN("component specification");
4181
4182 ident_list_t *ids = p_instantiation_list();
4183 consume(tCOLON);
4184 *comp_name = p_identifier();
4185
4186 return ids;
4187 }
4188
p_port_map_aspect(tree_t inst)4189 static void p_port_map_aspect(tree_t inst)
4190 {
4191 // port map ( association_list )
4192
4193 BEGIN("port map aspect");
4194
4195 consume(tPORT);
4196 consume(tMAP);
4197 consume(tLPAREN);
4198
4199 p_association_list(inst, tree_add_param);
4200
4201 consume(tRPAREN);
4202 }
4203
p_generic_map_aspect(tree_t inst)4204 static void p_generic_map_aspect(tree_t inst)
4205 {
4206 // generic map ( association_list )
4207
4208 BEGIN("generic map aspect");
4209
4210 consume(tGENERIC);
4211 consume(tMAP);
4212 consume(tLPAREN);
4213
4214 p_association_list(inst, tree_add_genmap);
4215
4216 consume(tRPAREN);
4217 }
4218
p_entity_aspect(void)4219 static tree_t p_entity_aspect(void)
4220 {
4221 // entity name [ ( identifier) ] | configuration name | open
4222
4223 switch (one_of(tENTITY, tCONFIGURATION, tOPEN)) {
4224 case tENTITY:
4225 {
4226 tree_t bind = tree_new(T_BINDING);
4227 tree_set_class(bind, C_ENTITY);
4228 tree_set_ident(bind, p_selected_identifier());
4229 if (optional(tLPAREN)) {
4230 tree_set_ident2(bind, p_identifier());
4231 consume(tRPAREN);
4232 }
4233
4234 return bind;
4235 }
4236
4237 case tCONFIGURATION:
4238 {
4239 tree_t bind = tree_new(T_BINDING);
4240 tree_set_class(bind, C_CONFIGURATION);
4241 tree_set_ident(bind, p_selected_identifier());
4242
4243 return bind;
4244 }
4245
4246 case tOPEN:
4247 default:
4248 return NULL;
4249 }
4250 }
4251
p_binding_indication(void)4252 static tree_t p_binding_indication(void)
4253 {
4254 // [ use entity_aspect ] [ generic_map_aspect ] [ port_map_aspect ]
4255
4256 BEGIN("binding indication");
4257
4258 tree_t bind = NULL;
4259 if (optional(tUSE))
4260 bind = p_entity_aspect();
4261 else
4262 bind = tree_new(T_BINDING);
4263
4264 if (peek() == tGENERIC) {
4265 assert(bind != NULL); // XXX: check for open here
4266 p_generic_map_aspect(bind);
4267 }
4268
4269 if (peek() == tPORT) {
4270 assert(bind != NULL); // XXX: check for open here
4271 p_port_map_aspect(bind);
4272 }
4273
4274 if (bind != NULL)
4275 tree_set_loc(bind, CURRENT_LOC);
4276
4277 return bind;
4278 }
4279
p_configuration_specification(tree_t parent)4280 static void p_configuration_specification(tree_t parent)
4281 {
4282 // for component_specification binding_indication ;
4283
4284 BEGIN("configuration specification");
4285
4286 consume(tFOR);
4287
4288 ident_t comp_name;
4289 LOCAL_IDENT_LIST ids = p_component_specification(&comp_name);
4290
4291 tree_t bind = p_binding_indication();
4292 consume(tSEMI);
4293
4294 const loc_t *loc = CURRENT_LOC;
4295
4296 if (ids != NULL) {
4297 for (ident_list_t *it = ids; it != NULL; it = it->next) {
4298 tree_t t = tree_new(T_SPEC);
4299 tree_set_loc(t, loc);
4300 tree_set_ident(t, it->ident);
4301 tree_set_ident2(t, comp_name);
4302 tree_set_value(t, bind);
4303
4304 tree_add_decl(parent, t);
4305 }
4306 }
4307 else {
4308 // Instantiation list was "others"
4309 tree_t t = tree_new(T_SPEC);
4310 tree_set_loc(t, loc);
4311 tree_set_ident2(t, comp_name);
4312 tree_set_value(t, bind);
4313
4314 tree_add_decl(parent, t);
4315 }
4316 }
4317
p_configuration_declarative_part(tree_t unit)4318 static void p_configuration_declarative_part(tree_t unit)
4319 {
4320 // use_clause | attribute_specification | group_declaration
4321
4322 BEGIN("configuration declarative part");
4323
4324 switch (peek()) {
4325 case tUSE:
4326 p_use_clause(unit, tree_add_decl);
4327 break;
4328
4329 case tATTRIBUTE:
4330 p_attribute_specification(unit, tree_add_decl);
4331 break;
4332
4333 default:
4334 expect(tUSE, tATTRIBUTE);
4335 }
4336 }
4337
p_component_configuration(tree_t unit)4338 static void p_component_configuration(tree_t unit)
4339 {
4340 // for component_specification [ binding_indication ; ]
4341 // [ block_configuration ] end for ;
4342
4343 BEGIN("component configuration");
4344
4345 consume(tFOR);
4346
4347 ident_t comp_name;
4348 LOCAL_IDENT_LIST ids = p_component_specification(&comp_name);
4349
4350 // TODO: should be optional
4351 tree_t bind = p_binding_indication();
4352 consume(tSEMI);
4353
4354 const loc_t *loc = CURRENT_LOC;
4355
4356 if (ids != NULL) {
4357 for (ident_list_t *it = ids; it != NULL; it = it->next) {
4358 tree_t t = tree_new(T_SPEC);
4359 tree_set_loc(t, loc);
4360 tree_set_ident(t, it->ident);
4361 tree_set_ident2(t, comp_name);
4362 tree_set_value(t, bind);
4363
4364 tree_add_decl(unit, t);
4365 }
4366 }
4367 else {
4368 // Instantiation list was "others"
4369 tree_t t = tree_new(T_SPEC);
4370 tree_set_loc(t, loc);
4371 tree_set_ident2(t, comp_name);
4372 tree_set_value(t, bind);
4373
4374 tree_add_decl(unit, t);
4375 }
4376
4377 // TODO: optional block_configuration
4378
4379 consume(tEND);
4380 consume(tFOR);
4381 consume(tSEMI);
4382 }
4383
p_configuration_item(tree_t unit)4384 static void p_configuration_item(tree_t unit)
4385 {
4386 // block_configuration | component_configuration
4387
4388 BEGIN("configuration item");
4389
4390 const token_t third = peek_nth(3);
4391 if ((third == tCOLON) || (third == tCOMMA))
4392 p_component_configuration(unit);
4393 else
4394 tree_add_decl(unit, p_block_configuration());
4395 }
4396
p_index_specification(void)4397 static void p_index_specification(void)
4398 {
4399 // discrete_range | expression
4400
4401 const look_params_t lookp = {
4402 .look = { tDOWNTO, tTO, tRANGE, tREVRANGE },
4403 .stop = { tRPAREN, tCOMMA, tASSOC, tBAR },
4404 .abort = tSEMI,
4405 .nest_in = tLPAREN,
4406 .nest_out = tRPAREN,
4407 .depth = 0
4408 };
4409
4410 if (look_for(&lookp)) {
4411 p_discrete_range();
4412 }
4413 else {
4414 p_expression();
4415 }
4416 }
4417
p_block_specification(tree_t unit)4418 static void p_block_specification(tree_t unit)
4419 {
4420 // label | label [ ( index_specification ) ]
4421
4422 BEGIN("block specification");
4423
4424 tree_set_ident(unit, p_identifier());
4425
4426 if (optional(tLPAREN)) {
4427 p_index_specification();
4428 consume(tRPAREN);
4429 }
4430 }
4431
p_block_configuration(void)4432 static tree_t p_block_configuration(void)
4433 {
4434 // for block_specification { use_clause } { configuration_item } end for ;
4435
4436 BEGIN("block configuration");
4437
4438 consume(tFOR);
4439
4440 tree_t b = tree_new(T_BLOCK_CONFIG);
4441
4442 p_block_specification(b);
4443
4444 while (not_at_token(tEND))
4445 p_configuration_item(b);
4446
4447 consume(tEND);
4448 consume(tFOR);
4449 consume(tSEMI);
4450
4451 return b;
4452 }
4453
p_configuration_declaration(tree_t unit)4454 static void p_configuration_declaration(tree_t unit)
4455 {
4456 // configuration identifier of name is configuration_declarative_part
4457 // block_configuration end [ configuration ] [ simple_name ] ;
4458
4459 BEGIN("configuration declaration");
4460
4461 consume(tCONFIGURATION);
4462
4463 tree_change_kind(unit, T_CONFIGURATION);
4464 tree_set_ident(unit, p_identifier());
4465
4466 consume(tOF);
4467
4468 tree_set_ident2(unit, p_identifier());
4469
4470 consume(tIS);
4471
4472 while (not_at_token(tFOR))
4473 p_configuration_declarative_part(unit);
4474
4475 tree_add_decl(unit, p_block_configuration());
4476
4477 consume(tEND);
4478 optional(tCONFIGURATION);
4479 p_trailing_label(tree_ident(unit));
4480 consume(tSEMI);
4481
4482 tree_set_loc(unit, CURRENT_LOC);
4483 }
4484
p_context_declaration(tree_t unit)4485 static void p_context_declaration(tree_t unit)
4486 {
4487 // 2008: context identifier is context_clause end [ context ]
4488 // [ context_simple_name ] ;
4489
4490 BEGIN("context declaration");
4491
4492 consume(tCONTEXT);
4493
4494 tree_change_kind(unit, T_CONTEXT);
4495 tree_set_ident(unit, p_identifier());
4496
4497 consume(tIS);
4498
4499 // LRM 08 section 13.1 forbids preceeding context clause
4500 if (tree_contexts(unit) != 2) // Implicit WORK and STD
4501 parse_error(tree_loc(tree_context(unit, 2)), "context clause preceeding "
4502 "context declaration must be empty");
4503
4504 p_context_clause(unit);
4505
4506 consume(tEND);
4507 optional(tCONTEXT);
4508 p_trailing_label(tree_ident(unit));
4509 consume(tSEMI);
4510
4511 tree_set_loc(unit, CURRENT_LOC);
4512 }
4513
p_primary_unit(tree_t unit)4514 static void p_primary_unit(tree_t unit)
4515 {
4516 // entity_declaration | configuration_declaration | package_declaration
4517
4518 BEGIN("primary unit");
4519
4520 switch (peek()) {
4521 case tENTITY:
4522 p_entity_declaration(unit);
4523 break;
4524
4525 case tPACKAGE:
4526 p_package_declaration(unit);
4527 break;
4528
4529 case tCONFIGURATION:
4530 p_configuration_declaration(unit);
4531 break;
4532
4533 case tCONTEXT:
4534 p_context_declaration(unit);
4535 break;
4536
4537 default:
4538 expect(tENTITY, tPACKAGE, tCONFIGURATION);
4539 }
4540 }
4541
p_block_declarative_item(tree_t parent)4542 static void p_block_declarative_item(tree_t parent)
4543 {
4544 // subprogram_declaration | subprogram_body | type_declaration
4545 // | subtype_declaration | constant_declaration | signal_declaration
4546 // | shared_variable_declaration | file_declaration | alias_declaration
4547 // | component_declaration | attribute_declaration
4548 // | attribute_specification | configuration_specification
4549 // | disconnection_specification | use_clause | group_template_declaration
4550 // | group_declaration
4551
4552 BEGIN("block declarative item");
4553
4554 switch (peek()) {
4555 case tSIGNAL:
4556 p_signal_declaration(parent);
4557 break;
4558
4559 case tTYPE:
4560 tree_add_decl(parent, p_type_declaration());
4561 break;
4562
4563 case tSUBTYPE:
4564 tree_add_decl(parent, p_subtype_declaration());
4565 break;
4566
4567 case tFILE:
4568 p_file_declaration(parent);
4569 break;
4570
4571 case tCONSTANT:
4572 p_constant_declaration(parent);
4573 break;
4574
4575 case tFUNCTION:
4576 case tPROCEDURE:
4577 case tIMPURE:
4578 case tPURE:
4579 {
4580 tree_t spec = p_subprogram_specification();
4581 if (peek() == tSEMI)
4582 tree_add_decl(parent, p_subprogram_declaration(spec));
4583 else
4584 tree_add_decl(parent, p_subprogram_body(spec));
4585 }
4586 break;
4587
4588 case tALIAS:
4589 tree_add_decl(parent, p_alias_declaration());
4590 break;
4591
4592 case tATTRIBUTE:
4593 if (peek_nth(3) == tOF)
4594 p_attribute_specification(parent, tree_add_decl);
4595 else
4596 tree_add_decl(parent, p_attribute_declaration());
4597 break;
4598
4599 case tFOR:
4600 p_configuration_specification(parent);
4601 break;
4602
4603 case tCOMPONENT:
4604 tree_add_decl(parent, p_component_declaration());
4605 break;
4606
4607 case tUSE:
4608 p_use_clause(parent, tree_add_decl);
4609 break;
4610
4611 case tSHARED:
4612 p_variable_declaration(parent);
4613 break;
4614
4615 default:
4616 expect(tSIGNAL, tTYPE, tSUBTYPE, tFILE, tCONSTANT, tFUNCTION, tIMPURE,
4617 tPURE, tPROCEDURE, tALIAS, tATTRIBUTE, tFOR, tCOMPONENT, tUSE,
4618 tSHARED);
4619 }
4620 }
4621
p_target(tree_t name)4622 static tree_t p_target(tree_t name)
4623 {
4624 // name | aggregate
4625
4626 BEGIN("target");
4627
4628 if (name == NULL) {
4629 if (peek() == tLPAREN)
4630 return p_aggregate();
4631 else
4632 return p_name();
4633 }
4634 else
4635 return name;
4636 }
4637
p_variable_assignment_statement(ident_t label,tree_t name)4638 static tree_t p_variable_assignment_statement(ident_t label, tree_t name)
4639 {
4640 // [ label : ] target := expression ;
4641
4642 EXTEND("variable assignment statement");
4643
4644 tree_t t = tree_new(T_VAR_ASSIGN);
4645
4646 tree_set_target(t, p_target(name));
4647
4648 consume(tASSIGN);
4649
4650 tree_set_value(t, p_expression());
4651
4652 consume(tSEMI);
4653
4654 const loc_t *loc = CURRENT_LOC;
4655 tree_set_loc(t, loc);
4656
4657 if (label == NULL)
4658 label = loc_to_ident(loc);
4659 tree_set_ident(t, label);
4660
4661 return t;
4662 }
4663
p_waveform_element(void)4664 static tree_t p_waveform_element(void)
4665 {
4666 // expression [ after expression ] | null [ after expression ]
4667
4668 BEGIN("waveform element");
4669
4670 tree_t w = tree_new(T_WAVEFORM);
4671 tree_set_value(w, p_expression());
4672
4673 if (optional(tAFTER))
4674 tree_set_delay(w, p_expression());
4675
4676 tree_set_loc(w, CURRENT_LOC);
4677
4678 return w;
4679 }
4680
p_waveform(tree_t stmt)4681 static void p_waveform(tree_t stmt)
4682 {
4683 // waveform_element { , waveform_element } | unaffected
4684
4685 BEGIN("waveform");
4686
4687 if (optional(tUNAFFECTED))
4688 return;
4689
4690 tree_add_waveform(stmt, p_waveform_element());
4691
4692 while (optional(tCOMMA))
4693 tree_add_waveform(stmt, p_waveform_element());
4694 }
4695
p_delay_mechanism(void)4696 static tree_t p_delay_mechanism(void)
4697 {
4698 // transport | [ reject expression ] inertial
4699
4700 BEGIN("delay mechanism");
4701
4702 switch (peek()) {
4703 case tTRANSPORT:
4704 consume(tTRANSPORT);
4705 return get_time(0);
4706
4707 case tREJECT:
4708 {
4709 consume(tREJECT);
4710 tree_t t = p_expression();
4711 consume(tINERTIAL);
4712 return t;
4713 }
4714
4715 case tINERTIAL:
4716 consume(tINERTIAL);
4717 return NULL;
4718
4719 default:
4720 return NULL;
4721 }
4722 }
4723
p_signal_assignment_statement(ident_t label,tree_t name)4724 static tree_t p_signal_assignment_statement(ident_t label, tree_t name)
4725 {
4726 // [ label : ] target <= [ delay_mechanism ] waveform ;
4727
4728 EXTEND("signal assignment statement");
4729
4730 tree_t t = tree_new(T_SIGNAL_ASSIGN);
4731
4732 tree_set_target(t, p_target(name));
4733
4734 consume(tLE);
4735
4736 tree_t reject = p_delay_mechanism();
4737
4738 p_waveform(t);
4739
4740 consume(tSEMI);
4741
4742 set_delay_mechanism(t, reject);
4743 set_label_and_loc(t, label, CURRENT_LOC);
4744 return t;
4745 }
4746
p_sensitivity_clause(tree_t wait)4747 static void p_sensitivity_clause(tree_t wait)
4748 {
4749 // on sensitivity_list
4750
4751 BEGIN("sensitivity clause");
4752
4753 consume(tON);
4754 p_sensitivity_list(wait);
4755 }
4756
p_condition_clause(tree_t wait)4757 static void p_condition_clause(tree_t wait)
4758 {
4759 // until condition
4760
4761 BEGIN("condition clause");
4762
4763 consume(tUNTIL);
4764 tree_set_value(wait, p_expression());
4765 }
4766
p_timeout_clause(tree_t wait)4767 static void p_timeout_clause(tree_t wait)
4768 {
4769 // for expression
4770
4771 BEGIN("timeout clause");
4772
4773 consume(tFOR);
4774 tree_set_delay(wait, p_expression());
4775 }
4776
p_wait_statement(ident_t label)4777 static tree_t p_wait_statement(ident_t label)
4778 {
4779 // [ label : ] wait [ sensitivity_clause ] [ condition_clause ]
4780 // [ timeout_clause ] ;
4781
4782 EXTEND("wait statement");
4783
4784 tree_t t = tree_new(T_WAIT);
4785
4786 consume(tWAIT);
4787
4788 if (peek() == tON)
4789 p_sensitivity_clause(t);
4790
4791 if (peek() == tUNTIL)
4792 p_condition_clause(t);
4793
4794 if (peek() == tFOR)
4795 p_timeout_clause(t);
4796
4797 consume(tSEMI);
4798
4799 set_label_and_loc(t, label, CURRENT_LOC);
4800 return t;
4801 }
4802
p_assertion_statement(ident_t label)4803 static tree_t p_assertion_statement(ident_t label)
4804 {
4805 // [ label : ] assertion ;
4806
4807 EXTEND("assertion statement");
4808
4809 tree_t t = p_assertion();
4810 consume(tSEMI);
4811
4812 set_label_and_loc(t, label, CURRENT_LOC);
4813 return t;
4814 }
4815
p_report_statement(ident_t label)4816 static tree_t p_report_statement(ident_t label)
4817 {
4818 // [ label : ] report expression [ severity expression ] ;
4819
4820 EXTEND("report statement");
4821
4822 tree_t t = tree_new(T_ASSERT);
4823
4824 consume(tREPORT);
4825
4826 tree_set_message(t, p_expression());
4827
4828 if (optional(tSEVERITY))
4829 tree_set_severity(t, p_expression());
4830 else {
4831 tree_t sev = tree_new(T_REF);
4832 tree_set_ident(sev, ident_new("NOTE"));
4833
4834 tree_set_severity(t, sev);
4835 }
4836
4837 consume(tSEMI);
4838
4839 tree_add_attr_int(t, ident_new("is_report"), 1);
4840
4841 set_label_and_loc(t, label, CURRENT_LOC);
4842 return t;
4843 }
4844
p_if_statement(ident_t label)4845 static tree_t p_if_statement(ident_t label)
4846 {
4847 // [ label : ] if condition then sequence_of_statements
4848 // { elsif condition then sequence_of_statements }
4849 // [ else sequence_of_statements ] end if [ label ] ;
4850
4851 EXTEND("if statement");
4852
4853 tree_t t = tree_new(T_IF);
4854
4855 consume(tIF);
4856
4857 tree_set_value(t, p_expression());
4858
4859 consume(tTHEN);
4860
4861 p_sequence_of_statements(t, tree_add_stmt);
4862
4863 tree_t tail = t;
4864
4865 while (optional(tELSIF)) {
4866 tree_t elsif = tree_new(T_IF);
4867 tree_set_ident(elsif, ident_uniq("elsif"));
4868 tree_set_value(elsif, p_expression());
4869
4870 consume(tTHEN);
4871
4872 p_sequence_of_statements(elsif, tree_add_stmt);
4873
4874 tree_set_loc(elsif, CURRENT_LOC);
4875
4876 tree_add_else_stmt(tail, elsif);
4877 tail = elsif;
4878 }
4879
4880 if (optional(tELSE))
4881 p_sequence_of_statements(tail, tree_add_else_stmt);
4882
4883 consume(tEND);
4884 consume(tIF);
4885 p_trailing_label(label);
4886 consume(tSEMI);
4887
4888 set_label_and_loc(t, label, CURRENT_LOC);
4889 return t;
4890 }
4891
p_null_statement(ident_t label)4892 static tree_t p_null_statement(ident_t label)
4893 {
4894 // [ label : ] null ;
4895
4896 EXTEND("null statement");
4897
4898 consume(tNULL);
4899 consume(tSEMI);
4900
4901 tree_t t = tree_new(T_NULL);
4902 set_label_and_loc(t, label, CURRENT_LOC);
4903 return t;
4904 }
4905
p_parameter_specification(tree_t loop)4906 static void p_parameter_specification(tree_t loop)
4907 {
4908 // identifier in discrete_range
4909
4910 BEGIN("paremeter specification");
4911
4912 tree_set_ident2(loop, p_identifier());
4913
4914 consume(tIN);
4915
4916 tree_add_range(loop, p_discrete_range());
4917 }
4918
p_iteration_scheme(void)4919 static tree_t p_iteration_scheme(void)
4920 {
4921 // while condition | for parameter_specification
4922
4923 BEGIN("iteration scheme");
4924
4925 if (optional(tWHILE)) {
4926 tree_t t = tree_new(T_WHILE);
4927 tree_set_value(t, p_expression());
4928 return t;
4929 }
4930 else if (optional(tFOR)) {
4931 tree_t t = tree_new(T_FOR);
4932 p_parameter_specification(t);
4933 return t;
4934 }
4935 else {
4936 tree_t true_ref = tree_new(T_REF);
4937 tree_set_ident(true_ref, ident_new("TRUE"));
4938
4939 tree_t t = tree_new(T_WHILE);
4940 tree_set_value(t, true_ref);
4941 return t;
4942 }
4943 }
4944
p_loop_statement(ident_t label)4945 static tree_t p_loop_statement(ident_t label)
4946 {
4947 // [ loop_label : ] [ iteration_scheme ] loop sequence_of_statements
4948 // end loop [ loop_label ] ;
4949
4950 BEGIN("loop statement");
4951
4952 tree_t t = p_iteration_scheme();
4953
4954 consume(tLOOP);
4955
4956 p_sequence_of_statements(t, tree_add_stmt);
4957
4958 consume(tEND);
4959 consume(tLOOP);
4960 p_trailing_label(label);
4961 consume(tSEMI);
4962
4963 set_label_and_loc(t, label, CURRENT_LOC);
4964 return t;
4965 }
4966
p_return_statement(ident_t label)4967 static tree_t p_return_statement(ident_t label)
4968 {
4969 // [ label : ] return [ expression ] ;
4970
4971 EXTEND("return statement");
4972
4973 consume(tRETURN);
4974
4975 tree_t t = tree_new(T_RETURN);
4976
4977 if (peek() != tSEMI)
4978 tree_set_value(t, p_expression());
4979
4980 consume(tSEMI);
4981
4982 set_label_and_loc(t, label, CURRENT_LOC);
4983 return t;
4984 }
4985
p_exit_statement(ident_t label)4986 static tree_t p_exit_statement(ident_t label)
4987 {
4988 // [ label : ] exit [ label ] [ when condition ] ;
4989
4990 EXTEND("exit statement");
4991
4992 consume(tEXIT);
4993
4994 tree_t t = tree_new(T_EXIT);
4995
4996 if (peek() == tID)
4997 tree_set_ident2(t, p_identifier());
4998
4999 if (optional(tWHEN))
5000 tree_set_value(t, p_expression());
5001
5002 consume(tSEMI);
5003
5004 set_label_and_loc(t, label, CURRENT_LOC);
5005 return t;
5006 }
5007
p_next_statement(ident_t label)5008 static tree_t p_next_statement(ident_t label)
5009 {
5010 // [ label : ] next [ label ] [ when condition ] ;
5011
5012 EXTEND("next statement");
5013
5014 consume(tNEXT);
5015
5016 tree_t t = tree_new(T_NEXT);
5017
5018 if (peek() == tID)
5019 tree_set_ident2(t, p_identifier());
5020
5021 if (optional(tWHEN))
5022 tree_set_value(t, p_expression());
5023
5024 consume(tSEMI);
5025
5026 set_label_and_loc(t, label, CURRENT_LOC);
5027 return t;
5028 }
5029
p_procedure_call_statement(ident_t label,tree_t name)5030 static tree_t p_procedure_call_statement(ident_t label, tree_t name)
5031 {
5032 // [ label : ] procedure_call ;
5033
5034 EXTEND("procedure call statement");
5035
5036 consume(tSEMI);
5037
5038 tree_change_kind(name, T_PCALL);
5039 tree_set_ident2(name, tree_ident(name));
5040 set_label_and_loc(name, label, CURRENT_LOC);
5041 return name;
5042 }
5043
p_case_statement_alternative(tree_t stmt)5044 static void p_case_statement_alternative(tree_t stmt)
5045 {
5046 // when choices => sequence_of_statements
5047
5048 BEGIN("case statement alternative");
5049
5050 consume(tWHEN);
5051
5052 const int nstart = tree_assocs(stmt);
5053 p_choices(stmt);
5054
5055 consume(tASSOC);
5056
5057 tree_t b = tree_new(T_BLOCK);
5058 tree_set_ident(b, loc_to_ident(CURRENT_LOC));
5059 p_sequence_of_statements(b, tree_add_stmt);
5060
5061 const int nassocs = tree_assocs(stmt);
5062 for (int i = nstart; i < nassocs; i++)
5063 tree_set_value(tree_assoc(stmt, i), b);
5064 }
5065
p_case_statement(ident_t label)5066 static tree_t p_case_statement(ident_t label)
5067 {
5068 // [ label : ] case expression is case_statement_alternative
5069 // { case_statement_alternative } end case [ label ] ;
5070
5071 EXTEND("case statement");
5072
5073 consume(tCASE);
5074
5075 tree_t t = tree_new(T_CASE);
5076 tree_set_value(t, p_expression());
5077
5078 consume(tIS);
5079
5080 do {
5081 p_case_statement_alternative(t);
5082 } while (peek() == tWHEN);
5083
5084 consume(tEND);
5085 consume(tCASE);
5086 p_trailing_label(label);
5087 consume(tSEMI);
5088
5089 set_label_and_loc(t, label, CURRENT_LOC);
5090 return t;
5091 }
5092
p_sequential_statement(void)5093 static tree_t p_sequential_statement(void)
5094 {
5095 // wait_statement | assertion_statement | report_statement
5096 // | signal_assignment_statement | variable_assignment_statement
5097 // | procedure_call_statement | if_statement | case_statement
5098 // | loop_statement | next_statement | exit_statement | return_statement
5099 // | null_statement
5100
5101 BEGIN("sequential statement");
5102
5103 if (peek() == tPRAGMA)
5104 return p_pragma();
5105
5106 ident_t label = NULL;
5107 if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
5108 label = p_identifier();
5109 consume(tCOLON);
5110 }
5111
5112 switch (peek()) {
5113 case tWAIT:
5114 return p_wait_statement(label);
5115
5116 case tASSERT:
5117 return p_assertion_statement(label);
5118
5119 case tREPORT:
5120 return p_report_statement(label);
5121
5122 case tIF:
5123 return p_if_statement(label);
5124
5125 case tNULL:
5126 return p_null_statement(label);
5127
5128 case tRETURN:
5129 return p_return_statement(label);
5130
5131 case tCASE:
5132 return p_case_statement(label);
5133
5134 case tWHILE:
5135 case tLOOP:
5136 case tFOR:
5137 return p_loop_statement(label);
5138
5139 case tEXIT:
5140 return p_exit_statement(label);
5141
5142 case tNEXT:
5143 return p_next_statement(label);
5144
5145 case tID:
5146 break;
5147
5148 case tLPAREN:
5149 {
5150 tree_t agg = p_aggregate();
5151
5152 switch (peek()) {
5153 case tASSIGN:
5154 return p_variable_assignment_statement(label, agg);
5155
5156 case tLE:
5157 return p_signal_assignment_statement(label, agg);
5158
5159 default:
5160 expect(tASSIGN, tLE);
5161 return tree_new(T_NULL);
5162 }
5163 }
5164
5165 default:
5166 expect(tWAIT, tID);
5167 drop_tokens_until(tSEMI);
5168 return tree_new(T_NULL);
5169 }
5170
5171 tree_t name = p_name();
5172
5173 switch (peek()) {
5174 case tASSIGN:
5175 return p_variable_assignment_statement(label, name);
5176
5177 case tLE:
5178 return p_signal_assignment_statement(label, name);
5179
5180 case tSEMI:
5181 return p_procedure_call_statement(label, name);
5182
5183 default:
5184 expect(tASSIGN, tLE, tSEMI);
5185 drop_tokens_until(tSEMI);
5186 return tree_new(T_NULL);
5187 }
5188 }
5189
p_instantiated_unit(void)5190 static tree_t p_instantiated_unit(void)
5191 {
5192 // [ component ] name
5193 // | entity name [ ( identifier ) ]
5194 // | configuration name
5195
5196 BEGIN("instantiated unit");
5197
5198 tree_t t = tree_new(T_INSTANCE);
5199
5200 switch (peek()) {
5201 case tENTITY:
5202 consume(tENTITY);
5203 tree_set_class(t, C_ENTITY);
5204 break;
5205
5206 case tCONFIGURATION:
5207 consume(tCONFIGURATION);
5208 tree_set_class(t, C_CONFIGURATION);
5209 break;
5210
5211 case tCOMPONENT:
5212 consume(tCOMPONENT);
5213 // Fall-through
5214
5215 default:
5216 tree_set_class(t, C_COMPONENT);
5217 }
5218
5219 tree_set_ident2(t, p_selected_identifier());
5220
5221 if ((tree_class(t) == C_ENTITY) && optional(tLPAREN)) {
5222 tree_set_ident2(t, ident_prefix(tree_ident2(t), p_identifier(), '-'));
5223 consume(tRPAREN);
5224 }
5225
5226 return t;
5227 }
5228
p_component_instantiation_statement(ident_t label)5229 static tree_t p_component_instantiation_statement(ident_t label)
5230 {
5231 // label : instantiated_unit [ generic_map_aspect ] [ port_map_aspect ] ;
5232
5233 EXTEND("component instantiation statement");
5234
5235 tree_t t = p_instantiated_unit();
5236 tree_set_ident(t, label);
5237
5238 if (peek() == tGENERIC)
5239 p_generic_map_aspect(t);
5240
5241 if (peek() == tPORT)
5242 p_port_map_aspect(t);
5243
5244 consume(tSEMI);
5245
5246 if (label == NULL)
5247 parse_error(CURRENT_LOC, "component instantiation statement must "
5248 "have a label");
5249
5250 tree_set_loc(t, CURRENT_LOC);
5251 return t;
5252 }
5253
p_options(tree_t stmt)5254 static tree_t p_options(tree_t stmt)
5255 {
5256 // [ guarded ] [ delay_mechanism ]
5257
5258 BEGIN("options");
5259
5260 if (optional(tGUARDED))
5261 tree_set_flag(stmt, TREE_F_GUARDED);
5262
5263 return p_delay_mechanism();
5264 }
5265
p_conditional_waveforms(tree_t stmt)5266 static void p_conditional_waveforms(tree_t stmt)
5267 {
5268 // { waveform when condition else } waveform [ when condition ]
5269
5270 BEGIN("conditional waveforms");
5271
5272 for (;;) {
5273 tree_t c = tree_new(T_COND);
5274 p_waveform(c);
5275 tree_set_loc(c, CURRENT_LOC);
5276
5277 tree_add_cond(stmt, c);
5278
5279 if (optional(tWHEN)) {
5280 tree_set_value(c, p_expression());
5281
5282 if (!optional(tELSE))
5283 break;
5284 }
5285 else
5286 break;
5287 }
5288 }
5289
p_conditional_signal_assignment(void)5290 static tree_t p_conditional_signal_assignment(void)
5291 {
5292 // target <= options conditional_waveforms ;
5293
5294 BEGIN("conditional signal assignment");
5295
5296 tree_t t = tree_new(T_CASSIGN);
5297 tree_set_target(t, p_target(NULL));
5298
5299 consume(tLE);
5300
5301 tree_t reject = p_options(t);
5302 p_conditional_waveforms(t);
5303
5304 const int nconds = tree_conds(t);
5305 for (int i = 0; i < nconds; i++)
5306 set_delay_mechanism(tree_cond(t, i), reject);
5307
5308 consume(tSEMI);
5309
5310 tree_set_loc(t, CURRENT_LOC);
5311 return t;
5312 }
5313
p_selected_waveforms(tree_t stmt)5314 static void p_selected_waveforms(tree_t stmt)
5315 {
5316 // { waveform when choices , } waveform when choices
5317
5318 BEGIN("selected waveforms");
5319
5320 do {
5321 tree_t a = tree_new(T_SIGNAL_ASSIGN);
5322 p_waveform(a);
5323
5324 consume(tWHEN);
5325
5326 const int nstart = tree_assocs(stmt);
5327 p_choices(stmt);
5328
5329 const int nassocs = tree_assocs(stmt);
5330 for (int i = nstart; i < nassocs; i++)
5331 tree_set_value(tree_assoc(stmt, i), a);
5332
5333 tree_set_loc(a, CURRENT_LOC);
5334 } while (optional(tCOMMA));
5335 }
5336
p_selected_signal_assignment(void)5337 static tree_t p_selected_signal_assignment(void)
5338 {
5339 // with expression select target <= options selected_waveforms ;
5340
5341 BEGIN("selected signal assignment");
5342
5343 consume(tWITH);
5344
5345 tree_t t = tree_new(T_SELECT);
5346 tree_set_value(t, p_expression());
5347
5348 consume(tSELECT);
5349 tree_t target = p_target(NULL);
5350 consume(tLE);
5351 tree_t reject = p_options(t);
5352 p_selected_waveforms(t);
5353 consume(tSEMI);
5354
5355 const int nassocs = tree_assocs(t);
5356 for (int i = 0; i < nassocs; i++) {
5357 tree_t s = tree_value(tree_assoc(t, i));
5358 tree_set_target(s, target);
5359 set_delay_mechanism(s, reject);
5360 }
5361
5362 tree_set_loc(t, CURRENT_LOC);
5363 return t;
5364 }
5365
p_concurrent_signal_assignment_statement(ident_t label)5366 static tree_t p_concurrent_signal_assignment_statement(ident_t label)
5367 {
5368 // [ label : ] [ postponed ] conditional_signal_assignment
5369 // | [ label : ] [ postponed ] selected_signal_assignment
5370
5371 EXTEND("concurrent signal assignment statement");
5372
5373 const bool postponed = optional(tPOSTPONED);
5374
5375 tree_t t = (peek() == tWITH)
5376 ? p_selected_signal_assignment()
5377 : p_conditional_signal_assignment();
5378
5379 const loc_t *loc = CURRENT_LOC;
5380 tree_set_loc(t, loc);
5381
5382 if (label == NULL)
5383 label = loc_to_ident(loc);
5384 tree_set_ident(t, label);
5385
5386 if (postponed)
5387 tree_set_flag(t, TREE_F_POSTPONED);
5388
5389 tree_set_loc(t, CURRENT_LOC);
5390 return t;
5391 }
5392
p_concurrent_procedure_call_statement(ident_t label)5393 static tree_t p_concurrent_procedure_call_statement(ident_t label)
5394 {
5395 // [ label : ] [ postponed ] procedure_call ;
5396
5397 EXTEND("concurrent procedure call statement");
5398
5399 const bool postponed = optional(tPOSTPONED);
5400
5401 tree_t t = p_name();
5402
5403 const tree_kind_t kind = tree_kind(t);
5404 if (kind != T_REF && kind != T_FCALL) {
5405 // This can only happen due to some earlier parsing error
5406 assert(n_errors > 0);
5407 return tree_new(T_CPCALL);
5408 }
5409
5410 tree_change_kind(t, T_CPCALL);
5411 tree_set_ident2(t, tree_ident(t));
5412
5413 consume(tSEMI);
5414
5415 if (postponed)
5416 tree_set_flag(t, TREE_F_POSTPONED);
5417
5418 const loc_t *loc = CURRENT_LOC;
5419 tree_set_loc(t, loc);
5420
5421 if (label == NULL)
5422 label = loc_to_ident(loc);
5423 tree_set_ident(t, label);
5424
5425 return t;
5426 }
5427
p_block_statement_part(tree_t arch)5428 static void p_block_statement_part(tree_t arch)
5429 {
5430 // { concurrent_statement }
5431
5432 BEGIN("block statement part");
5433
5434 while (not_at_token(tEND))
5435 tree_add_stmt(arch, p_concurrent_statement());
5436 }
5437
p_block_declarative_part(tree_t arch)5438 static void p_block_declarative_part(tree_t arch)
5439 {
5440 // { block_declarative_item }
5441
5442 BEGIN("block declarative part");
5443
5444 while (not_at_token(tBEGIN))
5445 p_block_declarative_item(arch);
5446 }
5447
p_block_statement(ident_t label)5448 static tree_t p_block_statement(ident_t label)
5449 {
5450 // label : block [ ( expression ) ] [ is ] block_header
5451 // block_declarative_part begin block_statement_part end block [ label ] ;
5452
5453 EXTEND("block statement");
5454
5455 tree_t b = tree_new(T_BLOCK);
5456 tree_set_ident(b, label);
5457
5458 consume(tBLOCK);
5459 optional(tIS);
5460 p_block_declarative_part(b);
5461 consume(tBEGIN);
5462 p_block_statement_part(b);
5463 consume(tEND);
5464 consume(tBLOCK);
5465 p_trailing_label(label);
5466 consume(tSEMI);
5467
5468 if (label == NULL)
5469 parse_error(CURRENT_LOC, "block statement must have a label");
5470
5471 tree_set_loc(b, CURRENT_LOC);
5472 return b;
5473 }
5474
p_generation_scheme(void)5475 static tree_t p_generation_scheme(void)
5476 {
5477 // for parameter_specification | if condition
5478
5479 BEGIN("generation scheme");
5480
5481 switch (one_of(tIF, tFOR)) {
5482 case tIF:
5483 {
5484 tree_t g = tree_new(T_IF_GENERATE);
5485 tree_set_value(g, p_expression());
5486 return g;
5487 }
5488
5489 case tFOR:
5490 {
5491 tree_t g = tree_new(T_FOR_GENERATE);
5492 p_parameter_specification(g);
5493 return g;
5494 }
5495
5496 default:
5497 return tree_new(T_IF_GENERATE);
5498 }
5499 }
5500
p_generate_statement(ident_t label)5501 static tree_t p_generate_statement(ident_t label)
5502 {
5503 // label : generation_scheme generate [ { block_declarative_item }
5504 // begin ] { concurrent_statement } end generate [ label ] ;
5505
5506 EXTEND("generate statement");
5507
5508 tree_t g = p_generation_scheme();
5509 tree_set_ident(g, label);
5510
5511 consume(tGENERATE);
5512
5513 if (scan(tSIGNAL, tTYPE, tSUBTYPE, tFILE, tCONSTANT, tFUNCTION, tIMPURE,
5514 tPURE, tALIAS, tATTRIBUTE, tBEGIN, tPROCEDURE, tFOR, tCOMPONENT,
5515 tUSE, tSHARED)) {
5516 while (not_at_token(tBEGIN))
5517 p_block_declarative_item(g);
5518 consume(tBEGIN);
5519 }
5520
5521 while (not_at_token(tEND))
5522 tree_add_stmt(g, p_concurrent_statement());
5523
5524 consume(tEND);
5525 consume(tGENERATE);
5526 p_trailing_label(label);
5527 consume(tSEMI);
5528
5529 if (label == NULL)
5530 parse_error(CURRENT_LOC, "generate statement must have a label");
5531
5532 tree_set_loc(g, CURRENT_LOC);
5533 return g;
5534 }
5535
p_concurrent_statement(void)5536 static tree_t p_concurrent_statement(void)
5537 {
5538 // block_statement | process_statement | concurrent_procedure_call_statement
5539 // | concurrent_assertion_statement
5540 // | concurrent_signal_assignment_statement
5541 // | component_instantiation_statement | generate_statement
5542
5543 BEGIN("concurrent statement");
5544
5545 if (peek() == tPRAGMA)
5546 return p_pragma();
5547
5548 ident_t label = NULL;
5549 if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
5550 label = p_identifier();
5551 consume(tCOLON);
5552 }
5553
5554 if (peek() == tID) {
5555 const token_t p2 = peek_nth(2);
5556 if (((label != NULL) && (p2 == tSEMI))
5557 || (p2 == tGENERIC) || (p2 == tPORT))
5558 return p_component_instantiation_statement(label);
5559 else {
5560 const look_params_t lookp = {
5561 .look = { tLE },
5562 .stop = { tSEMI },
5563 .nest_in = tLPAREN,
5564 .nest_out = tRPAREN,
5565 .depth = 0
5566 };
5567
5568 if (look_for(&lookp))
5569 return p_concurrent_signal_assignment_statement(label);
5570 else
5571 return p_concurrent_procedure_call_statement(label);
5572 }
5573 }
5574 else {
5575 switch (peek()) {
5576 case tPROCESS:
5577 return p_process_statement(label);
5578
5579 case tCOMPONENT:
5580 case tENTITY:
5581 case tCONFIGURATION:
5582 return p_component_instantiation_statement(label);
5583
5584 case tWITH:
5585 return p_concurrent_signal_assignment_statement(label);
5586
5587 case tASSERT:
5588 return p_concurrent_assertion_statement(label);
5589
5590 case tPOSTPONED:
5591 if (peek_nth(2) == tASSERT)
5592 return p_concurrent_assertion_statement(label);
5593 else
5594 return p_process_statement(label);
5595
5596 case tBLOCK:
5597 return p_block_statement(label);
5598
5599 case tIF:
5600 case tFOR:
5601 return p_generate_statement(label);
5602
5603 case tLPAREN:
5604 return p_concurrent_signal_assignment_statement(label);
5605
5606 default:
5607 expect(tPROCESS, tPOSTPONED, tCOMPONENT, tENTITY, tCONFIGURATION,
5608 tWITH, tASSERT, tBLOCK, tIF, tFOR);
5609 drop_tokens_until(tSEMI);
5610 return tree_new(T_BLOCK);
5611 }
5612 }
5613 }
5614
p_architecture_declarative_part(tree_t arch)5615 static void p_architecture_declarative_part(tree_t arch)
5616 {
5617 // { block_declarative_item }
5618
5619 BEGIN("architecture declarative part");
5620
5621 while (not_at_token(tBEGIN))
5622 p_block_declarative_item(arch);
5623 }
5624
p_architecture_statement_part(tree_t arch)5625 static void p_architecture_statement_part(tree_t arch)
5626 {
5627 // { concurrent_statement }
5628
5629 BEGIN("architecture statement part");
5630
5631 while (not_at_token(tEND))
5632 tree_add_stmt(arch, p_concurrent_statement());
5633 }
5634
p_architecture_body(tree_t unit)5635 static void p_architecture_body(tree_t unit)
5636 {
5637 // architecture identifier of entity_name is architecture_declarative_part
5638 // begin architecture_statement_part end [ architecture ]
5639 // [ architecture_simple_name ] ;
5640
5641 BEGIN("architecture body");
5642
5643 tree_change_kind(unit, T_ARCH);
5644
5645 consume(tARCHITECTURE);
5646 tree_set_ident(unit, p_identifier());
5647 consume(tOF);
5648 tree_set_ident2(unit, p_identifier());
5649 consume(tIS);
5650
5651 p_architecture_declarative_part(unit);
5652
5653 consume(tBEGIN);
5654
5655 p_architecture_statement_part(unit);
5656
5657 consume(tEND);
5658 optional(tARCHITECTURE);
5659 p_trailing_label(tree_ident(unit));
5660 consume(tSEMI);
5661
5662 tree_set_loc(unit, CURRENT_LOC);
5663 }
5664
p_package_body_declarative_item(tree_t parent)5665 static void p_package_body_declarative_item(tree_t parent)
5666 {
5667 // subprogram_declaration | subprogram_body | type_declaration
5668 // | subtype_declaration | constant_declaration
5669 // | shared_variable_declaration | file_declaration | alias_declaration
5670 // | use_clause | group_template_declaration | group_declaration
5671 //
5672 // 2008: subprogram_instantiation_declaration | attribute_declaration
5673 // | attribute_specification | package_instantiation_declaration
5674
5675 BEGIN("package body declarative item");
5676
5677 switch (peek()) {
5678 case tFUNCTION:
5679 case tPROCEDURE:
5680 case tIMPURE:
5681 case tPURE:
5682 {
5683 tree_t spec = p_subprogram_specification();
5684 if (peek() == tSEMI)
5685 tree_add_decl(parent, p_subprogram_declaration(spec));
5686 else
5687 tree_add_decl(parent, p_subprogram_body(spec));
5688 }
5689 break;
5690
5691 case tSHARED:
5692 p_variable_declaration(parent);
5693 break;
5694
5695 case tFILE:
5696 p_file_declaration(parent);
5697 break;
5698
5699 case tATTRIBUTE:
5700 if (standard() < STD_08)
5701 parse_error(CURRENT_LOC, "package body may not contain attribute "
5702 "declarations or specifications in VHDL-%s",
5703 standard_text(standard()));
5704 else {
5705 if (peek_nth(3) == tOF)
5706 p_attribute_specification(parent, tree_add_decl);
5707 else
5708 tree_add_decl(parent, p_attribute_declaration());
5709 }
5710 break;
5711
5712 case tTYPE:
5713 tree_add_decl(parent, p_type_declaration());
5714 break;
5715
5716 case tCONSTANT:
5717 p_constant_declaration(parent);
5718 break;
5719
5720 case tSUBTYPE:
5721 tree_add_decl(parent, p_subtype_declaration());
5722 break;
5723
5724 case tALIAS:
5725 tree_add_decl(parent, p_alias_declaration());
5726 break;
5727
5728 case tUSE:
5729 p_use_clause(parent, tree_add_decl);
5730 break;
5731
5732 default:
5733 expect(tFUNCTION, tPROCEDURE, tSHARED, tIMPURE, tPURE, tATTRIBUTE, tTYPE,
5734 tCONSTANT, tSUBTYPE, tFILE, tALIAS, tUSE);
5735 }
5736 }
5737
p_package_body_declarative_part(tree_t unit)5738 static void p_package_body_declarative_part(tree_t unit)
5739 {
5740 // { package_body_declarative_item }
5741
5742 BEGIN("package body declarative part");
5743
5744 while (not_at_token(tEND))
5745 p_package_body_declarative_item(unit);
5746 }
5747
p_package_body(tree_t unit)5748 static void p_package_body(tree_t unit)
5749 {
5750 // package body simple_name is package_body_declarative_part
5751 // end [ package body ] [ simple_name ] ;
5752
5753 BEGIN("package body");
5754
5755 consume(tPACKAGE);
5756 consume(tBODY);
5757
5758 tree_change_kind(unit, T_PACK_BODY);
5759 tree_set_ident(unit, p_identifier());
5760
5761 consume(tIS);
5762
5763 p_package_body_declarative_part(unit);
5764
5765 consume(tEND);
5766
5767 if (optional(tPACKAGE))
5768 consume(tBODY);
5769
5770 p_trailing_label(tree_ident(unit));
5771 consume(tSEMI);
5772
5773 tree_set_loc(unit, CURRENT_LOC);
5774 }
5775
p_secondary_unit(tree_t unit)5776 static void p_secondary_unit(tree_t unit)
5777 {
5778 // architecture_body | package_body
5779
5780 BEGIN("secondary unit");
5781
5782 switch (peek()) {
5783 case tARCHITECTURE:
5784 p_architecture_body(unit);
5785 break;
5786
5787 case tPACKAGE:
5788 p_package_body(unit);
5789 break;
5790
5791 default:
5792 expect(tARCHITECTURE, tPACKAGE);
5793 }
5794 }
5795
p_library_unit(tree_t unit)5796 static void p_library_unit(tree_t unit)
5797 {
5798 // primary_unit | secondary_unit
5799
5800 BEGIN("library unit");
5801
5802 switch (peek()) {
5803 case tENTITY:
5804 case tCONFIGURATION:
5805 case tCONTEXT:
5806 p_primary_unit(unit);
5807 break;
5808
5809 case tARCHITECTURE:
5810 p_secondary_unit(unit);
5811 break;
5812
5813 case tPACKAGE:
5814 if (peek_nth(2) == tBODY)
5815 p_secondary_unit(unit);
5816 else
5817 p_primary_unit(unit);
5818 break;
5819
5820 default:
5821 expect(tENTITY, tCONFIGURATION, tARCHITECTURE, tPACKAGE, tCONTEXT);
5822 }
5823 }
5824
p_design_unit(void)5825 static tree_t p_design_unit(void)
5826 {
5827 BEGIN("design unit");
5828
5829 tree_t unit = tree_new(T_DESIGN_UNIT);
5830
5831 tree_t std = tree_new(T_LIBRARY);
5832 tree_set_ident(std, std_i);
5833 tree_add_context(unit, std);
5834
5835 tree_t work = tree_new(T_LIBRARY);
5836 tree_set_ident(work, lib_name(lib_work()));
5837 tree_add_context(unit, work);
5838
5839 p_context_clause(unit);
5840 p_library_unit(unit);
5841
5842 return unit;
5843 }
5844
begin_token(char * tok)5845 void begin_token(char *tok)
5846 {
5847 const char *newline = strrchr(tok, '\n');
5848 int n_token_start, n_token_length;
5849 if (newline != NULL) {
5850 n_token_start = 0;
5851 n_token_length = strlen(tok) - (newline - tok);
5852 n_token_next_start = n_token_length - 1;
5853 }
5854 else {
5855 n_token_start = n_token_next_start;
5856 n_token_length = strlen(tok);
5857 n_token_next_start += n_token_length;
5858 }
5859
5860 const int last_col = n_token_start + n_token_length - 1;
5861
5862 yylloc.first_line = MIN(n_row, LINE_INVALID);
5863 yylloc.first_column = MIN(n_token_start, COLUMN_INVALID);
5864 yylloc.last_line = MIN(n_row, LINE_INVALID);
5865 yylloc.last_column = MIN(last_col, COLUMN_INVALID);
5866 yylloc.file = perm_file_name;
5867 yylloc.linebuf = perm_linebuf;
5868 }
5869
get_next_char(char * b,int max_buffer)5870 int get_next_char(char *b, int max_buffer)
5871 {
5872 if (last_was_newline) {
5873 n_row += 1;
5874 perm_linebuf = read_ptr;
5875 last_was_newline = false;
5876 }
5877
5878 const bool eof = read_ptr >= file_start + file_sz;
5879 if (eof)
5880 return 0;
5881 else
5882 *b = *read_ptr++;
5883
5884 if (perm_linebuf == NULL)
5885 perm_linebuf = read_ptr;
5886
5887 if (*b == '\n')
5888 last_was_newline = true;
5889
5890 return *b == 0 ? 0 : 1;
5891 }
5892
input_from_file(const char * file)5893 void input_from_file(const char *file)
5894 {
5895 int fd = open(file, O_RDONLY);
5896 if (fd < 0)
5897 fatal_errno("opening %s", file);
5898
5899 struct stat buf;
5900 if (fstat(fd, &buf) != 0)
5901 fatal_errno("fstat");
5902
5903 if (!S_ISREG(buf.st_mode))
5904 fatal("opening %s: not a regular file", file);
5905
5906 file_sz = buf.st_size;
5907
5908 if (file_sz > 0)
5909 file_start = map_file(fd, file_sz);
5910 else
5911 file_start = NULL;
5912
5913 read_ptr = file_start;
5914 last_was_newline = true;
5915 perm_file_name = ident_new(file);
5916 n_row = 0;
5917 n_token_next_start = 0;
5918 translate_on = true;
5919 parse_pragmas = opt_get_int("parse-pragmas");
5920
5921 if (tokenq == NULL) {
5922 tokenq_sz = 128;
5923 tokenq = xmalloc(tokenq_sz * sizeof(tokenq_t));
5924 }
5925
5926 tokenq_head = tokenq_tail = 0;
5927 }
5928
parse(void)5929 tree_t parse(void)
5930 {
5931 int old_errors = n_errors;
5932 n_correct = RECOVER_THRESH;
5933
5934 if (peek() == tEOF)
5935 return NULL;
5936
5937 tree_t unit = p_design_unit();
5938
5939 while (cond_state != NULL) {
5940 cond_state_t *tmp = cond_state->next;
5941 free(cond_state);
5942 cond_state = tmp;
5943 }
5944
5945 if (n_errors > old_errors)
5946 return NULL;
5947 else
5948 return unit;
5949 }
5950
parse_errors(void)5951 int parse_errors(void)
5952 {
5953 return n_errors;
5954 }
5955
reset_parse_errors(void)5956 void reset_parse_errors(void)
5957 {
5958 n_errors = 0;
5959 }
5960