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