You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

917 lines
24 KiB

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