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.

940 lines
25 KiB

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