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\.                      { 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