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