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.

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