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