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