circom/parser/jaz.jison
parser/jaz.jisonRaw
1/* description: Construct AST for jaz language. */
2
3/* lexical grammar */
4%lex
5
6%%
7
8\s+ { /* skip whitespace */ }
9\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ { /* console.log("MULTILINE COMMENT: "+yytext); */ }
10\/\/.* { /* console.log("SINGLE LINE COMMENT: "+yytext); */ }
11var { return 'var'; }
12signal { return 'signal'; }
13private { return 'private'; }
14input { return 'input'; }
15output { return 'output'; }
16linearCombination { return 'linearCombination'; }
17component { return 'component'; }
18template { return 'template'; }
19function { return 'function'; }
20if { return 'if'; }
21else { return 'else'; }
22for { return 'for'; }
23while { return 'while'; }
24do { return 'do'; }
25return { return 'return'; }
26include { return 'include'; }
270x[0-9A-Fa-f]* { return 'HEXNUMBER'; }
28[0-9]+ { return 'DECNUMBER'; }
29[a-zA-Z][a-zA-Z$_0-9]* { return 'IDENTIFIER'; }
30\"[^"]+\" { yytext = yytext.slice(1,-1); return 'STRING'; }
31\=\=\> { return '==>'; }
32\<\=\= { return '<=='; }
33\-\-\> { return '-->'; }
34\<\-\- { return '<--'; }
35\=\=\= { return '==='; }
36\>\>\= { return '>>='; }
37\<\<\= { return '<<='; }
38\&\& { return '&&'; }
39\|\| { return '||'; }
40\=\= { return '=='; }
41\<\= { return '<='; }
42\>\= { return '>='; }
43\!\= { return '!='; }
44\>\> { return '>>'; }
45\<\< { return '<<'; }
46\*\* { return '**'; }
47\+\+ { return '++'; }
48\-\- { return '--'; }
49\+\= { return '+='; }
50\-\= { return '-='; }
51\*\= { return '*='; }
52\/\= { return '/='; }
53\%\= { return '%='; }
54\|\= { return '|='; }
55\&\= { return '&='; }
56\^\= { return '^='; }
57\= { return '='; }
58\+ { return '+'; }
59\- { return '-'; }
60\* { return '*'; }
61\/ { return '/'; }
62\% { return '%'; }
63\^ { return '^'; }
64\& { return '&'; }
65\| { return '|'; }
66\! { return '!'; }
67\< { return '<'; }
68\> { return '>'; }
69\! { return '!'; }
70\? { return '?'; }
71\: { return ':'; }
72\( { return '('; }
73\) { return ')'; }
74\[ { return '['; }
75\] { return ']'; }
76\{ { return '{'; }
77\} { return '}'; }
78\; { return ';'; }
79\, { return ','; }
80\. { return '.'; }
81<<EOF>> { return 'EOF'; }
82. { console.log("INVALID: " + yytext); return 'INVALID'}
83
84/lex
85
86%left ';'
87%right 'if' 'else'
88%left EMPTY
89%left IDLIST
90%left ','
91%right '?' ':' TERCOND '=' '+=' '-=' '*=' '/=' '%=' '>>=' '<<=' '&=' '|=' '^=' '<==' '==>' '===' '<--' '-->'
92%left '||'
93%left '&&'
94%left '|'
95%left '^'
96%left '&'
97%left '==' '!='
98%left '<=' '>=' '<' '>'
99%left '<<' '>>'
100
101%left '+' '-'
102%left '*' '/' '%'
103%left '**'
104%right '++' '--' UMINUS UPLUS '!' '~'
105%left '.'
106%left DECL
107%left PLUSPLUSRIGHT MINUSMINUSRIGHT '[' ']' '(' ')'
108%left HIGH
109
110
111
112%{
113const bigInt = require('big-integer');
114const util = require('util');
115const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
116const __MASK__ = new bigInt(2).pow(253).minus(1);
117
118function setLines(dst, first, last) {
119 last = last || first;
120 dst.first_line = first.first_line;
121 dst.first_column = first.first_column;
122 dst.last_line = last.last_line;
123 dst.last_column = last.last_column;
124}
125
126%}
127
128%start allStatments
129
130%% /* language grammar */
131
132
133allStatments
134 : statmentList EOF
135 {
136// console.log(JSON.stringify($1, null, 1));
137 $$ = { type: "BLOCK", statements: $1.statments };
138 setLines($$, @1);
139 return $$
140 }
141 ;
142
143statmentList
144 : statmentList statment
145 {
146 $1.statments.push($2);
147 setLines($1, @1, @2);
148 }
149 | statment
150 {
151 $$ = { type: "STATMENTLIST", statments: [$1] };
152 setLines($$, @1);
153 }
154 ;
155
156statment
157 : functionDefinitionStatment
158 {
159 $$ = $1;
160 }
161 | templateDefinitionStatment
162 {
163 $$ = $1;
164 }
165 | ifStatment
166 {
167 $$ = $1;
168 }
169 | forStatment
170 {
171 $$ = $1;
172 }
173 | whileStatment
174 {
175 $$ = $1;
176 }
177 | doWhileStatment
178 {
179 $$ = $1;
180 }
181 | returnStatment
182 {
183 $$ = $1;
184 }
185 | block
186 {
187 $$ = $1;
188 }
189 | expressionStatment
190 {
191 $$ = $1;
192 }
193 | includeStatment
194 {
195 $$ = $1;
196 }
197 ;
198
199
200functionDefinitionStatment
201 : 'function' IDENTIFIER '(' identifierList ')' block
202 {
203 $$ = { type: "FUNCTIONDEF", name: $2, params: $4.identifiers, block: $6};
204 setLines($$, @1, @6);
205 }
206 | 'function' IDENTIFIER '(' ')' block
207 {
208 $$ = { type: "FUNCTIONDEF", name: $2, params: [], block: $5 };
209 setLines($$, @1, @5);
210 }
211 ;
212
213templateDefinitionStatment
214 : 'template' IDENTIFIER '(' identifierList ')' block
215 {
216 $$ = { type: "TEMPLATEDEF", name: $2, params: $4.identifiers, block: $6 };
217 setLines($$, @1, @6);
218 }
219 | 'template' IDENTIFIER '(' ')' block
220 {
221 $$ = { type: "TEMPLATEDEF", name: $2, params: [], block: $5 };
222 setLines($$, @1, @5);
223 }
224 ;
225
226
227identifierList
228 : identifierList ',' IDENTIFIER
229 {
230 $1.identifiers.push($3);
231 setLines($1, @1, @3);
232 }
233 | IDENTIFIER %prec EMPTY
234 {
235 $$ = { type: "IDENTIFIERLIST", identifiers: [$1] };
236 setLines($$, @1);
237 }
238 ;
239
240ifStatment
241 : 'if' '(' expression ')' statment 'else' statment
242 {
243 if ($3.type == "NUMBER") {
244 $$ = !$3.value.eq(0) ? $5 : $7;
245 } else {
246 $$ = { type: "IF", condition: $3, then: $5, else: $7 };
247 }
248 setLines($$, @1, @7);
249 }
250 | 'if' '(' expression ')' statment
251 {
252 if ($3.type == "NUMBER") {
253 $$ = !$3.value.eq(0) ? $5 : { type: "NUMBER", value: bigInt(0) };
254 } else {
255 $$ = { type: "IF", condition: $3, then: $5 };
256 }
257 setLines($$, @1, @5);
258 }
259 ;
260
261forStatment
262 : 'for' '(' expression ';' expression ';' expression ')' statment
263 {
264 $$ = { type: "FOR", init: $3, condition: $5, step: $7, body: $9 };
265 setLines($$, @1, @9);
266 }
267 ;
268
269whileStatment
270 : 'while' '(' expression ')' statment
271 {
272 $$ = { type: "WHILE", condition: $3, body: $5 };
273 setLines($$, @1, @5);
274 }
275 ;
276
277doWhileStatment
278 : 'do' statment 'while' '(' expression ')'
279 {
280 $$ = { type: "DOWHILE", condition: $5, body: $2 };
281 setLines($$, @1, @6);
282 }
283 ;
284
285returnStatment
286 : 'return' expression ';'
287 {
288 $$ = { type: "RETURN", value: $2 };
289 setLines($$, @1, @3);
290 }
291 | 'return' expression %prec ';'
292 {
293 $$ = { type: "RETURN", value: $2 }
294 setLines($$, @1, @2);
295 }
296 ;
297
298includeStatment
299 : 'include' STRING ';'
300 {
301 $$ = { type: "INCLUDE", file: $2 };
302 setLines($$, @1, @3);
303 }
304 | 'include' STRING %prec ';'
305 {
306 $$ = { type: "INCLUDE", file: $2 }
307 setLines($$, @1, @2);
308 }
309 ;
310
311block
312 : '{' statmentList '}'
313 {
314 $$ = { type: "BLOCK", statements: $2.statments };
315 setLines($$, @1, @3);
316 }
317 ;
318
319expressionStatment
320 : expression ';' %prec ';'
321 {
322 $$ = $1;
323 }
324 | expression %prec ';'
325 {
326 $$ = $1;
327 }
328 ;
329
330expression
331 : e17 %prec EMPTY
332 {
333 $$ = $1;
334 }
335 ;
336
337e17
338 : leftHandExpression '=' e17
339 {
340 $$ = { type: "OP", op: "=", values: [$1, $3] };
341 setLines($$, @1, @3);
342 }
343 | leftHandExpression '+=' e17
344 {
345 $$ = { type: "OP", op: "+=", values: [$1, $3] };
346 setLines($$, @1, @3);
347 }
348 | leftHandExpression '-=' e17
349 {
350 $$ = { type: "OP", op: "-=", values: [$1, $3] };
351 setLines($$, @1, @3);
352 }
353 | leftHandExpression '*=' e17
354 {
355 $$ = { type: "OP", op: "*=", values: [$1, $3] };
356 setLines($$, @1, @3);
357 }
358 | leftHandExpression '/=' e17
359 {
360 $$ = { type: "OP", op: "/=", values: [$1, $3] };
361 setLines($$, @1, @3);
362 }
363 | leftHandExpression '%=' e17
364 {
365 $$ = { type: "OP", op: "%=", values: [$1, $3] };
366 setLines($$, @1, @3);
367 }
368 | leftHandExpression '<<=' e17
369 {
370 $$ = { type: "OP", op: "<<=", values: [$1, $3] };
371 setLines($$, @1, @3);
372 }
373 | leftHandExpression '>>=' e17
374 {
375 $$ = { type: "OP", op: ">>=", values: [$1, $3] };
376 setLines($$, @1, @3);
377 }
378 | leftHandExpression '&=' e17
379 {
380 $$ = { type: "OP", op: "&=", values: [$1, $3] };
381 setLines($$, @1, @3);
382 }
383 | leftHandExpression '|=' e17
384 {
385 $$ = { type: "OP", op: "|=", values: [$1, $3] };
386 setLines($$, @1, @3);
387 }
388 | leftHandExpression '^=' e17
389 {
390 $$ = { type: "OP", op: "^=", values: [$1, $3] };
391 setLines($$, @1, @3);
392 }
393 | leftHandExpression '<==' e17
394 {
395 $$ = { type: "OP", op: "<==", values: [$1, $3] };
396 setLines($$, @1, @3);
397 }
398 | e17 '==>' leftHandExpression
399 {
400 $$ = { type: "OP", op: "<==", values: [$3, $1] };
401 setLines($$, @1, @3);
402 }
403 | leftHandExpression '<--' e17
404 {
405 $$ = { type: "OP", op: "<--", values: [$1, $3] };
406 setLines($$, @1, @3);
407 }
408 | e17 '-->' leftHandExpression
409 {
410 $$ = { type: "OP", op: "<--", values: [$3, $1] };
411 setLines($$, @1, @3);
412 }
413 | e16 '===' e17
414 {
415 $$ = { type: "OP", op: "===", values: [$1, $3] };
416 setLines($$, @1, @3);
417 }
418 | e17 '?' e17 ':' e17 %prec TERCOND
419 {
420 if ($1.type == "NUMBER") {
421 $$ = !$1.value.eq(0) ? $3 : $5;
422 } else {
423 $$ = { type: "OP", op: "?", values: [$1, $3, $5] };
424 }
425 setLines($$, @1, @5);
426 }
427 | e16 %prec EMPTY
428 {
429 $$ = $1;
430 }
431 ;
432
433e16
434 : rightArray
435 {
436 $$ = $1;
437 }
438 | e15 %prec EMPTY
439 {
440 $$ = $1;
441 }
442 ;
443
444e15
445 : e15 '||' e14
446 {
447 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
448 $$ = { type: "NUMBER", value: !$1.value.eq(0) || !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
449 } else {
450 $$ = { type: "OP", op: "||", values: [$1, $3] };
451 }
452 setLines($$, @1, @3);
453 }
454 | e14 %prec EMPTY
455 {
456 $$ = $1;
457 }
458 ;
459
460e14
461 : e14 '&&' e13
462 {
463 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
464 $$ = { type: "NUMBER", value: !$1.value.eq(0) && !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
465 } else {
466 $$ = { type: "OP", op: "&&", values: [$1, $3] };
467 }
468 setLines($$, @1, @3);
469 }
470 | e13 %prec EMPTY
471 {
472 $$ = $1;
473 }
474 ;
475
476e13
477 : e13 '|' e12
478 {
479 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
480 $$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
481 } else {
482 $$ = { type: "OP", op: "|", values: [$1, $3] };
483 }
484 setLines($$, @1, @3);
485 }
486 | e12 %prec EMPTY
487 {
488 $$ = $1;
489 }
490 ;
491
492
493e12
494 : e12 '^' e11
495 {
496 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
497 $$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
498 } else {
499 $$ = { type: "OP", op: "^", values: [$1, $3] };
500 }
501 setLines($$, @1, @3);
502 }
503 | e11 %prec EMPTY
504 {
505 $$ = $1;
506 }
507 ;
508
509e11
510 : e11 '&' e10
511 {
512 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
513 $$ = { type: "NUMBER", value: $1.value.and($3.value).and(__MASK__) };
514 } else {
515 $$ = { type: "OP", op: "&", values: [$1, $3] };
516 }
517 setLines($$, @1, @3);
518 }
519 | e10 %prec EMPTY
520 {
521 $$ = $1;
522 }
523 ;
524
525
526
527
528e10
529 : e10 '==' e9
530 {
531 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
532 $$ = { type: "NUMBER", value: $1.value.equals($3.value) ? bigInt(1) : bigInt(0) };
533 } else {
534 $$ = { type: "OP", op: "==", values: [$1, $3] };
535 }
536 setLines($$, @1, @3);
537 }
538 | e10 '!=' e9
539 {
540 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
541 $$ = { type: "NUMBER", value: $1.value.eq($3.value) ? bigInt(0) : bigInt(1) };
542 } else {
543 $$ = { type: "OP", op: "!=", values: [$1, $3] };
544 }
545 setLines($$, @1, @3);
546 }
547 | e9 %prec EMPTY
548 {
549 $$ = $1
550 }
551 ;
552
553e9
554 : e9 '<=' e7
555 {
556 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
557 $$ = { type: "NUMBER", value: $1.value.lesserOrEquals($3.value) ? bigInt(1) : bigInt(0) };
558 } else {
559 $$ = { type: "OP", op: "<=", values: [$1, $3] };
560 }
561 setLines($$, @1, @3);
562 }
563 | e9 '>=' e7
564 {
565 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
566 $$ = { type: "NUMBER", value: $1.value.greaterOrEquals($3.value) ? bigInt(1) : bigInt(0) };
567 } else {
568 $$ = { type: "OP", op: ">=", values: [$1, $3] };
569 }
570 setLines($$, @1, @3);
571 }
572 | e9 '<' e7
573 {
574 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
575 $$ = { type: "NUMBER", value: $1.value.lesser($3.value) ? bigInt(1) : bigInt(0) };
576 } else {
577 $$ = { type: "OP", op: "<", values: [$1, $3] };
578 }
579 setLines($$, @1, @3);
580 }
581 | e9 '>' e7
582 {
583 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
584 $$ = { type: "NUMBER", value: $1.value.greater($3.value) ? bigInt(1) : bigInt(0) };
585 } else {
586 $$ = { type: "OP", op: ">", values: [$1, $3] };
587 }
588 setLines($$, @1, @3);
589 }
590 | e7 %prec EMPTY
591 {
592 $$ = $1
593 }
594 ;
595
596e7
597 : e7 '<<' e6
598 {
599 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
600 let v = $3.value.greater(256) ? 256 : $3.value.value;
601 $$ = { type: "NUMBER", value: $1.value.shiftLeft(v).and(__MASK__) };
602 } else {
603 $$ = { type: "OP", op: "<<", values: [$1, $3] };
604 }
605 setLines($$, @1, @3);
606 }
607 | e7 '>>' e6
608 {
609 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
610 let v = $3.value.greater(256) ? 256 : $3.value.value;
611 $$ = {t1ype: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
612 } else {
613 $$ = { type: "OP", op: ">>", values: [$1, $3] };
614 }
615 setLines($$, @1, @3);
616 }
617 | e6 %prec EMPTY
618 {
619 $$ = $1;
620 }
621 ;
622
623e6
624 : e6 '+' e5
625 {
626 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
627 $$ = { type: "NUMBER", value: ($1.value.plus($3.value)).mod(__P__) };
628 } else {
629 $$ = { type: "OP", op: "+", values: [$1, $3] };
630 }
631 setLines($$, @1, @3);
632 }
633 | e6 '-' e5
634 {
635 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
636 $$ = { type: "NUMBER", value: ($1.value.plus(__P__).minus($3.value)).mod(__P__) };
637 } else {
638 $$ = { type: "OP", op: "-", values: [$1, $3] };
639 }
640 setLines($$, @1, @3);
641 }
642 | e5 %prec EMPTY
643 {
644 $$ = $1;
645 }
646 ;
647
648
649e5
650 : e5 '*' e4
651 {
652 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
653 $$ = { type: "NUMBER", value: ($1.value.times($3.value)).mod(__P__) };
654 } else {
655 $$ = { type: "OP", op: "*", values: [$1, $3] };
656 }
657 setLines($$, @1, @3);
658 }
659 | e5 '/' e4
660 {
661 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
662 $$ = { type: "NUMBER", value: ($1.value.times($3.value.modInv(__P__))).mod(__P__) };
663 } else {
664 $$ = { type: "OP", op: "/", values: [$1, $3] };
665 }
666 setLines($$, @1, @3);
667 }
668 | e5 '%' e4
669 {
670 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
671 $$ = { type: "NUMBER", value: $1.value.mod($3.value) };
672 } else {
673 $$ = { type: "OP", op: "%", values: [$1, $3] };
674 }
675 setLines($$, @1, @3);
676 }
677 | e4 %prec EMPTY
678 {
679 $$ = $1;
680 }
681 ;
682
683e4
684 : e4 '**' e3
685 {
686 if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
687 $$ = { type: "NUMBER", value: $1.value.modPow($3.value, __P__) };
688 } else {
689 $$ = { type: "OP", op: "**", values: [$1, $3] };
690 }
691 setLines($$, @1, @3);
692 }
693 | e3 %prec EMPTY
694 {
695 $$ = $1;
696 }
697 ;
698
699
700e3
701 : '++' leftHandExpression
702 {
703 $$ = { type: "OP", op: "PLUSPLUSLEFT", values: [$2] };
704 setLines($$, @1, @2);
705 }
706 | '--' leftHandExpression
707 {
708 $$ = { type: "OP", op: "MINUSMINUSLEFT", values: [$2] };
709 setLines($$, @1, @2);
710 }
711 | '+' e3 %prec UPLUS
712 {
713 $$ = $2;
714 setLines($$, @1, @2);
715 }
716 | '-' e3 %prec UMINUS
717 {
718 if ($2.type == "NUMBER") {
719 $$ = { type: "NUMBER", value: __P__.minus($2.value).mod(__P__) };
720 } else {
721 $$ = { type: "OP", op: "UMINUS", values: [$2] };
722 }
723 setLines($$, @1, @2);
724 }
725 | '!' e3
726 {
727 if ($2.type == "NUMBER") {
728 $$ = { type: "NUMBER", value: $2.value.eq(0) ? bigInt(1) : bigInt(0) };
729 } else {
730 $$ = { type: "OP", op: "!", values: [$2] };
731 }
732 setLines($$, @1, @2);
733 }
734 | '~' e3
735 {
736 if ($2.type == "NUMBER") {
737 $$ = { type: "NUMBER", value: $2.value.xor(__MASK__) };
738 } else {
739 $$ = { type: "OP", op: "~", values: [$2] };
740 }
741 setLines($$, @1, @2);
742 }
743 | e2 %prec EMPTY
744 {
745 $$ = $1;
746 }
747 ;
748
749e2
750 : leftHandExpression '++' %prec PLUSPLUSRIGHT
751 {
752 $$ = {type: "OP", op: "PLUSPLUSRIGHT", values: [$1] };
753 setLines($$, @1, @2);
754 }
755 | leftHandExpression '--' %prec MINUSMINUSRIGHT
756 {
757 $$ = {type: "OP", op: "MINUSMINUSRIGHT", values: [$1] };
758 setLines($$, @1, @2);
759 }
760 | functionCall
761 {
762 $$ = $1;
763 }
764 | e0 %prec EMPTY
765 {
766 $$ = $1;
767 }
768 ;
769
770e0
771 : leftHandExpression %prec EMPTY
772 {
773 $$ = $1
774 }
775 | DECNUMBER
776 {
777 $$ = {type: "NUMBER", value: bigInt($1).mod(__P__) }
778 setLines($$, @1);
779 }
780 | HEXNUMBER
781 {
782 $$ = {type: "NUMBER", value: bigInt($1.substr(2).toUpperCase(), 16).mod(__P__) }
783 setLines($$, @1);
784 }
785 | '(' expression ')' %prec EMPTY
786 {
787 $$ = $2;
788 setLines($$, @1, @3);
789 }
790 ;
791
792leftHandExpression
793 : simpleLeftHandExpression '.' simpleLeftHandExpression %prec EMPTY
794 {
795 $$ = {type: "PIN", component: $1, pin: $3 };
796 setLines($$, @1, @3);
797 }
798 | declaration %prec DECL
799 {
800 $$ = $1
801 }
802 | simpleLeftHandExpression %prec EMPTY
803 {
804 $$ = $1
805 }
806 ;
807
808
809
810declaration
811 : 'var' simpleLeftHandExpression %prec DECL
812 {
813 $$ = {type: "DECLARE", declareType: "VARIABLE", name: $2}
814 setLines($$, @1, @2);
815 }
816 | 'signal' simpleLeftHandExpression %prec DECL
817 {
818 $$ = {type: "DECLARE", declareType: "SIGNAL", name: $2}
819 setLines($$, @1, @2);
820 }
821 | 'signal' 'input' simpleLeftHandExpression %prec DECL
822 {
823 $$ = {type: "DECLARE", declareType: "SIGNALIN", name: $3};
824 setLines($$, @1, @3);
825 }
826 | 'signal' 'private' 'input' simpleLeftHandExpression %prec DECL
827 {
828 $$ = {type: "DECLARE", declareType: "SIGNALIN", private: true, name: $4};
829 setLines($$, @1, @4);
830 }
831 | 'signal' 'output' simpleLeftHandExpression %prec DECL
832 {
833 $$ = {type: "DECLARE", declareType: "SIGNALOUT", name: $3};
834 setLines($$, @1, @3);
835 }
836 | 'component' simpleLeftHandExpression %prec DECL
837 {
838 $$ = {type: "DECLARE", declareType: "COMPONENT", name: $2}
839 setLines($$, @1, @2);
840 }
841 ;
842
843simpleLeftHandExpression
844 : simpleLeftHandExpression array
845 {
846 for (let i=0; i< $2.values.length; i++) {
847 $1.selectors.push($2.values[i]);
848 }
849 setLines($1, @1, @2);
850 }
851 | IDENTIFIER %prec EMPTY
852 {
853 $$ = {type: "VARIABLE", name: $1 , selectors: []};
854 setLines($$, @1);
855 }
856 ;
857
858functionCall
859 : IDENTIFIER '(' expressionList ')'
860 {
861 $$ = {type: "FUNCTIONCALL", name: $1, params: $3.expressions}
862 setLines($$, @1, @4);
863 }
864 | IDENTIFIER '(' ')'
865 {
866 $$ = {type: "FUNCTIONCALL", name: $1, params: []}
867 setLines($$, @1, @3);
868 }
869 ;
870
871expressionList
872 : expressionList ',' expression
873 {
874 $1.expressions.push($3);
875 setLines($$, @1, @3);
876 }
877 | expression %prec ','
878 {
879 $$ = {type: "EXPRESSIONLST", expressions: [$1]};
880 setLines($$, @1);
881 }
882 ;
883
884rightArray
885 : array %prec EMPTY
886 {
887 $$ = $1;
888 }
889 ;
890
891array
892 : '[' expressionList ']'
893 {
894 $$ = { type: "ARRAY", values: $2.expressions};
895 setLines($$, @1, @3);
896 }
897 ;
898