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.

927 lines
24 KiB

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