parser.rs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. use std::{iter::Peekable, str::Chars};
  2. use indexmap::IndexMap;
  3. use itertools::Itertools;
  4. use super::{
  5. ast::{Arg, Constant, Literal, Statement, StatementType, Variable, Witness},
  6. error::ErrorEmitter,
  7. lexer::{Token, TokenType},
  8. LitType, Opcode, VarType,
  9. };
  10. /// zkas language builtin keywords.
  11. /// These can not be used anywhere except where they are expected.
  12. const KEYWORDS: [&str; 3] = ["constant", "contract", "circuit"];
  13. /// Valid EcFixedPoint constant names supported by the VM.
  14. const VALID_ECFIXEDPOINT: [&str; 1] = ["VALUE_COMMIT_RANDOM"];
  15. /// Valid EcFixedPointShort constant names supported by the VM.
  16. const VALID_ECFIXEDPOINTSHORT: [&str; 1] = ["VALUE_COMMIT_VALUE"];
  17. /// Valid EcFixedPointBase constant names supported by the VM.
  18. const VALID_ECFIXEDPOINTBASE: [&str; 1] = ["NULLIFIER_K"];
  19. pub struct Parser {
  20. tokens: Vec<Token>,
  21. error: ErrorEmitter,
  22. }
  23. impl Parser {
  24. pub fn new(filename: &str, source: Chars, tokens: Vec<Token>) -> Self {
  25. // For nice error reporting, we'll load everything into a string
  26. // vector so we have references to lines.
  27. let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
  28. let error = ErrorEmitter::new("Parser", filename, lines);
  29. Self { tokens, error }
  30. }
  31. pub fn parse(&self) -> (Vec<Constant>, Vec<Witness>, Vec<Statement>) {
  32. // We use these to keep state while parsing.
  33. let mut namespace = None;
  34. let (mut declaring_constant, mut declared_constant) = (false, false);
  35. let (mut declaring_contract, mut declared_contract) = (false, false);
  36. let (mut declaring_circuit, mut declared_circuit) = (false, false);
  37. // The tokens gathered from each of the sections
  38. let mut constant_tokens = vec![];
  39. let mut contract_tokens = vec![];
  40. let mut circuit_tokens = vec![];
  41. let mut circuit_stmt = vec![];
  42. let mut circuit_stmts = vec![];
  43. let mut ast_inner = IndexMap::new();
  44. let mut ast = IndexMap::new();
  45. if self.tokens[0].token_type != TokenType::Symbol {
  46. self.error.abort(
  47. "Source file does not start with a section. Expected `constant/contract/circuit`.",
  48. 0,
  49. 0,
  50. );
  51. }
  52. let mut iter = self.tokens.iter();
  53. while let Some(t) = iter.next() {
  54. // Sections "constant", "contract", and "circuit" are
  55. // the sections we must be declaring in our source code.
  56. // When we find one, we'll take all the tokens found in
  57. // the section and place them in their respective vec.
  58. // NOTE: Currently this logic depends on the fact that
  59. // the sections are closed off with braces. This should
  60. // be revisited later when we decide to add other lang
  61. // functionality that also depends on using braces.
  62. if !declaring_constant && !declaring_contract && !declaring_circuit {
  63. //
  64. // We use this macro to avoid code repetition in the following
  65. // match statement for soaking up the section tokens.
  66. macro_rules! absorb_inner_tokens {
  67. ($v:ident) => {
  68. for inner in iter.by_ref() {
  69. if KEYWORDS.contains(&inner.token.as_str()) &&
  70. inner.token_type == TokenType::Symbol
  71. {
  72. self.error.abort(
  73. &format!("Keyword '{}' used in improper place.", inner.token),
  74. inner.line,
  75. inner.column,
  76. );
  77. }
  78. $v.push(inner.clone());
  79. if inner.token_type == TokenType::RightBrace {
  80. break
  81. }
  82. }
  83. };
  84. }
  85. match t.token.as_str() {
  86. "constant" => {
  87. declaring_constant = true;
  88. absorb_inner_tokens!(constant_tokens);
  89. }
  90. "contract" => {
  91. declaring_contract = true;
  92. absorb_inner_tokens!(contract_tokens);
  93. }
  94. "circuit" => {
  95. declaring_circuit = true;
  96. absorb_inner_tokens!(circuit_tokens);
  97. }
  98. x => self.error.abort(
  99. &format!("Section `{}` is not a valid section", x),
  100. t.line,
  101. t.column,
  102. ),
  103. }
  104. }
  105. // We use this macro to set or check that the namespace of all sections
  106. // is the same and no stray strings appeared.
  107. macro_rules! check_namespace {
  108. ($t:ident) => {
  109. if let Some(ns) = namespace.clone() {
  110. if ns != $t[0].token {
  111. self.error.abort(
  112. &format!("Found '{}' namespace, expected '{}'.", $t[0].token, ns),
  113. $t[0].line,
  114. $t[0].column,
  115. );
  116. }
  117. } else {
  118. namespace = Some($t[0].token.clone());
  119. }
  120. };
  121. }
  122. // Parse the constant section into the AST.
  123. if declaring_constant {
  124. if declared_constant {
  125. self.error.abort("Duplicate `constant` section found.", t.line, t.column);
  126. }
  127. self.check_section_structure("constant", constant_tokens.clone());
  128. check_namespace!(constant_tokens);
  129. let mut constants_map = IndexMap::new();
  130. // This is everything between the braces: { ... }
  131. let mut constant_inner = constant_tokens[2..constant_tokens.len() - 1].iter();
  132. while let Some((typ, name, comma)) = constant_inner.next_tuple() {
  133. if comma.token_type != TokenType::Comma {
  134. self.error.abort("Separator is not a comma.", comma.line, comma.column);
  135. }
  136. // No variable shadowing
  137. if constants_map.contains_key(name.token.as_str()) {
  138. self.error.abort(
  139. &format!(
  140. "Section `constant` already contains the token `{}`.",
  141. &name.token
  142. ),
  143. name.line,
  144. name.column,
  145. );
  146. }
  147. constants_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  148. }
  149. if constant_inner.next().is_some() {
  150. self.error.abort("Internal error, leftovers in 'constant' iterator", 0, 0);
  151. }
  152. ast_inner.insert("constant".to_string(), constants_map);
  153. declaring_constant = false;
  154. declared_constant = true;
  155. }
  156. // Parse the contract section into the AST.
  157. if declaring_contract {
  158. if declared_contract {
  159. self.error.abort("Duplicate `contract` section found.", t.line, t.column);
  160. }
  161. self.check_section_structure("contract", contract_tokens.clone());
  162. check_namespace!(contract_tokens);
  163. let mut witnesses_map = IndexMap::new();
  164. // This is everything between the braces: { ... }
  165. let mut contract_inner = contract_tokens[2..contract_tokens.len() - 1].iter();
  166. while let Some((typ, name, comma)) = contract_inner.next_tuple() {
  167. if comma.token_type != TokenType::Comma {
  168. self.error.abort("Separator is not a comma.", comma.line, comma.column);
  169. }
  170. // No variable shadowing
  171. if witnesses_map.contains_key(name.token.as_str()) {
  172. self.error.abort(
  173. &format!(
  174. "Section `contract` already contains the token `{}`.",
  175. &name.token
  176. ),
  177. name.line,
  178. name.column,
  179. );
  180. }
  181. witnesses_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  182. }
  183. if contract_inner.next().is_some() {
  184. self.error.abort("Internal error, leftovers in 'contract' iterator", 0, 0);
  185. }
  186. ast_inner.insert("contract".to_string(), witnesses_map);
  187. declaring_contract = false;
  188. declared_contract = true;
  189. }
  190. // Parse the circuit section into the AST.
  191. if declaring_circuit {
  192. if declared_circuit {
  193. self.error.abort("Duplicate `circuit` section found.", t.line, t.column);
  194. }
  195. self.check_section_structure("circuit", circuit_tokens.clone());
  196. check_namespace!(circuit_tokens);
  197. for i in circuit_tokens[2..circuit_tokens.len() - 1].iter() {
  198. if i.token_type == TokenType::Semicolon {
  199. circuit_stmts.push(circuit_stmt.clone());
  200. circuit_stmt = vec![];
  201. continue
  202. }
  203. circuit_stmt.push(i.clone());
  204. }
  205. declaring_circuit = false;
  206. declared_circuit = true;
  207. }
  208. }
  209. let ns = namespace.unwrap();
  210. ast.insert(ns.clone(), ast_inner);
  211. let constants = {
  212. let c = match ast.get(&ns).unwrap().get("constant") {
  213. Some(c) => c,
  214. None => {
  215. self.error.abort("Missing `constant` section in .zk source.", 0, 0);
  216. unreachable!();
  217. }
  218. };
  219. self.parse_ast_constants(c)
  220. };
  221. let witnesses = {
  222. let c = match ast.get(&ns).unwrap().get("contract") {
  223. Some(c) => c,
  224. None => {
  225. self.error.abort("Missing `contract` section in .zk source.", 0, 0);
  226. unreachable!();
  227. }
  228. };
  229. self.parse_ast_contract(c)
  230. };
  231. let statements = self.parse_ast_circuit(circuit_stmts);
  232. if statements.is_empty() {
  233. self.error.abort("Circuit section is empty.", 0, 0);
  234. }
  235. (constants, witnesses, statements)
  236. }
  237. fn check_section_structure(&self, section: &str, tokens: Vec<Token>) {
  238. if tokens[0].token_type != TokenType::String {
  239. self.error.abort(
  240. "Section declaration must start with a naming string.",
  241. tokens[0].line,
  242. tokens[0].column,
  243. );
  244. }
  245. if tokens[1].token_type != TokenType::LeftBrace {
  246. self.error.abort(
  247. "Section must be opened with a left brace '{'",
  248. tokens[0].line,
  249. tokens[0].column,
  250. );
  251. }
  252. if tokens.last().unwrap().token_type != TokenType::RightBrace {
  253. self.error.abort(
  254. "Section must be closed with a right brace '}'",
  255. tokens[0].line,
  256. tokens[0].column,
  257. );
  258. }
  259. match section {
  260. "constant" | "contract" => {
  261. if tokens.len() == 3 {
  262. self.error.warn(&format!("{} section is empty.", section), 0, 0);
  263. }
  264. if tokens[2..tokens.len() - 1].len() % 3 != 0 {
  265. self.error.abort(
  266. &format!("Invalid number of elements in '{}' section. Must be pairs of '<Type> <name>' separated with a comma ','.", section),
  267. tokens[0].line,
  268. tokens[0].column
  269. );
  270. }
  271. }
  272. "circuit" => {
  273. if tokens.len() == 3 {
  274. self.error.abort("circuit section is empty.", 0, 0);
  275. }
  276. if tokens[tokens.len() - 2].token_type != TokenType::Semicolon {
  277. self.error.abort(
  278. "Circuit section does not end with a semicolon. Would never finish parsing.",
  279. tokens[tokens.len()-2].line,
  280. tokens[tokens.len()-2].column,
  281. );
  282. }
  283. }
  284. _ => panic!(),
  285. };
  286. }
  287. fn parse_ast_constants(&self, ast: &IndexMap<String, (Token, Token)>) -> Vec<Constant> {
  288. let mut ret = vec![];
  289. // k = name
  290. // v = (name, type)
  291. for (k, v) in ast {
  292. if &v.0.token != k {
  293. self.error.abort(
  294. &format!("Constant name `{}` doesn't match token `{}`.", v.0.token, k),
  295. v.0.line,
  296. v.0.column,
  297. );
  298. }
  299. if v.0.token_type != TokenType::Symbol {
  300. self.error.abort(
  301. &format!("Constant name `{}` is not a symbol.", v.0.token),
  302. v.0.line,
  303. v.0.column,
  304. );
  305. }
  306. if v.1.token_type != TokenType::Symbol {
  307. self.error.abort(
  308. &format!("Constant type `{}` is not a symbol.", v.1.token),
  309. v.1.line,
  310. v.1.column,
  311. );
  312. }
  313. // Valid constant types, these are the constants/generators supported
  314. // in `src/crypto/constants.rs` and `src/crypto/constants/`.
  315. match v.1.token.as_str() {
  316. "EcFixedPoint" => {
  317. if !VALID_ECFIXEDPOINT.contains(&v.0.token.as_str()) {
  318. self.error.abort(
  319. &format!(
  320. "`{}` is not a valid EcFixedPoint constant. Supported: {:?}",
  321. v.0.token.as_str(),
  322. VALID_ECFIXEDPOINT
  323. ),
  324. v.0.line,
  325. v.0.column,
  326. );
  327. }
  328. ret.push(Constant {
  329. name: k.to_string(),
  330. typ: VarType::EcFixedPoint,
  331. line: v.1.line,
  332. column: v.1.column,
  333. });
  334. }
  335. "EcFixedPointShort" => {
  336. if !VALID_ECFIXEDPOINTSHORT.contains(&v.0.token.as_str()) {
  337. self.error.abort(
  338. &format!(
  339. "`{}` is not a valid EcFixedPointShort constant. Supported: {:?}",
  340. v.0.token.as_str(),
  341. VALID_ECFIXEDPOINTSHORT
  342. ),
  343. v.0.line,
  344. v.0.column,
  345. );
  346. }
  347. ret.push(Constant {
  348. name: k.to_string(),
  349. typ: VarType::EcFixedPointShort,
  350. line: v.1.line,
  351. column: v.1.column,
  352. });
  353. }
  354. "EcFixedPointBase" => {
  355. if !VALID_ECFIXEDPOINTBASE.contains(&v.0.token.as_str()) {
  356. self.error.abort(
  357. &format!(
  358. "`{}` is not a valid EcFixedPointBase constant. Supported: {:?}",
  359. v.0.token.as_str(),
  360. VALID_ECFIXEDPOINTBASE
  361. ),
  362. v.0.line,
  363. v.0.column,
  364. );
  365. }
  366. ret.push(Constant {
  367. name: k.to_string(),
  368. typ: VarType::EcFixedPointBase,
  369. line: v.1.line,
  370. column: v.1.column,
  371. });
  372. }
  373. x => {
  374. self.error.abort(
  375. &format!("`{}` is an unsupported constant type.", x),
  376. v.1.line,
  377. v.1.column,
  378. );
  379. }
  380. }
  381. }
  382. ret
  383. }
  384. fn parse_ast_contract(&self, ast: &IndexMap<String, (Token, Token)>) -> Vec<Witness> {
  385. let mut ret = vec![];
  386. // k = name
  387. // v = (name, type)
  388. for (k, v) in ast {
  389. if &v.0.token != k {
  390. self.error.abort(
  391. &format!("Witness name `{}` doesn't match token `{}`.", v.0.token, k),
  392. v.0.line,
  393. v.0.column,
  394. );
  395. }
  396. if v.0.token_type != TokenType::Symbol {
  397. self.error.abort(
  398. &format!("Witness name `{}` is not a symbol.", v.0.token),
  399. v.0.line,
  400. v.0.column,
  401. );
  402. }
  403. if v.1.token_type != TokenType::Symbol {
  404. self.error.abort(
  405. &format!("Witness type `{}` is not a symbol.", v.1.token),
  406. v.1.line,
  407. v.1.column,
  408. );
  409. }
  410. // Valid witness types
  411. match v.1.token.as_str() {
  412. "Base" => {
  413. ret.push(Witness {
  414. name: k.to_string(),
  415. typ: VarType::Base,
  416. line: v.0.line,
  417. column: v.0.column,
  418. });
  419. }
  420. "Scalar" => {
  421. ret.push(Witness {
  422. name: k.to_string(),
  423. typ: VarType::Scalar,
  424. line: v.0.line,
  425. column: v.0.column,
  426. });
  427. }
  428. "MerklePath" => {
  429. ret.push(Witness {
  430. name: k.to_string(),
  431. typ: VarType::MerklePath,
  432. line: v.0.line,
  433. column: v.0.column,
  434. });
  435. }
  436. "Uint32" => {
  437. ret.push(Witness {
  438. name: k.to_string(),
  439. typ: VarType::Uint32,
  440. line: v.0.line,
  441. column: v.0.column,
  442. });
  443. }
  444. "Uint64" => {
  445. ret.push(Witness {
  446. name: k.to_string(),
  447. typ: VarType::Uint64,
  448. line: v.0.line,
  449. column: v.0.column,
  450. });
  451. }
  452. x => {
  453. self.error.abort(
  454. &format!("`{}` is an unsupported witness type.", x),
  455. v.1.line,
  456. v.1.column,
  457. );
  458. }
  459. }
  460. }
  461. ret
  462. }
  463. fn parse_ast_circuit(&self, statements: Vec<Vec<Token>>) -> Vec<Statement> {
  464. // The statement layouts/syntax in the language are as follows:
  465. //
  466. // C = poseidon_hash(pub_x, pub_y, value, token, serial, coin_blind);
  467. // | | | | |
  468. // V V V V V
  469. // variable opcode arg arg
  470. // assign
  471. //
  472. // constrain_instance(C);
  473. // | |
  474. // V V
  475. // opcode arg
  476. //
  477. // inner opcode arg
  478. // |
  479. // constrain_instance(ec_get_x(foo));
  480. // | |
  481. // V V
  482. // opcode arg as opcode
  483. //
  484. // In the latter, we want to support nested function calls, e.g.:
  485. //
  486. // constrain_instance(ec_get_x(token_commit));
  487. //
  488. // The inner call's result would still get pushed on the stack,
  489. // but it will not be accessible in any other scope.
  490. //
  491. // In certain opcodes, we also support literal types, and the
  492. // opcodes can return a variable type after running the operation.
  493. // e.g.
  494. // one = witness_base(1);
  495. // zero = witness_base(0);
  496. //
  497. // The literal type is used only in the function call's scope, but
  498. // the result is then accessible on the stack to be used by further
  499. // computation.
  500. //
  501. // Regarding multiple return values from opcodes, this is perhaps
  502. // not necessary for the current language scope, as this is a low
  503. // level representation. Note that it could be relatively easy to
  504. // modify the parsing logic to support that here. For now we'll
  505. // defer it, and if at some point we decide that the language is
  506. // too expressive and noisy, we'll consider having multiple return
  507. // types. It also very much depends on the type of functions/opcodes
  508. // that we want to support.
  509. // Vec of statements to return from this entire parsing operation.
  510. let mut ret = vec![];
  511. // Here, our statements tokens have been parsed and delimited by
  512. // semicolons (;) in the source file. This iterator contains each
  513. // of those statements as an array of tokens we then consume and
  514. // build the AST further.
  515. for statement in statements {
  516. if statement.is_empty() {
  517. continue
  518. }
  519. let (mut left_paren, mut right_paren) = (0, 0);
  520. for i in &statement {
  521. match i.token.as_str() {
  522. "(" => left_paren += 1,
  523. ")" => right_paren += 1,
  524. _ => {}
  525. }
  526. }
  527. if left_paren != right_paren || (left_paren == 0 || right_paren == 0) {
  528. self.error.abort(
  529. "Incorrect number of left and right parenthesis for statement.",
  530. statement[0].line,
  531. statement[0].column,
  532. );
  533. }
  534. // Peekable iterator so we can see tokens in advance
  535. // without consuming the iterator.
  536. let mut iter = statement.iter().peekable();
  537. // Dummy statement that we'll hopefully fill now.
  538. let mut stmt = Statement::default();
  539. let mut parsing = false;
  540. while let Some(token) = iter.next() {
  541. if !parsing {
  542. // TODO: MAKE SURE IT'S A SYMBOL
  543. // This logic must be changed if we want to support
  544. // multiple return values.
  545. if let Some(next_token) = iter.peek() {
  546. if next_token.token_type == TokenType::Assign {
  547. stmt.line = token.line;
  548. stmt.typ = StatementType::Assign;
  549. stmt.rhs = vec![];
  550. stmt.lhs = Some(Variable {
  551. name: token.token.clone(),
  552. typ: VarType::Dummy,
  553. line: token.line,
  554. column: token.column,
  555. });
  556. // Skip over the `=` token.
  557. iter.next();
  558. parsing = true;
  559. continue
  560. }
  561. if next_token.token_type == TokenType::LeftParen {
  562. stmt.line = token.line;
  563. stmt.typ = StatementType::Call;
  564. stmt.rhs = vec![];
  565. stmt.lhs = None;
  566. parsing = true;
  567. }
  568. if !parsing {
  569. self.error.abort(
  570. &format!("Illegal token `{}`.", next_token.token),
  571. next_token.line,
  572. next_token.column,
  573. );
  574. }
  575. }
  576. }
  577. // If parsing == true, we now know if we're making a variable
  578. // assignment or a function call without a return value.
  579. // Let's dig deeper to see what the statement's call is, and
  580. // what it contains as arguments. With this we'll fill `rhs`.
  581. // The arguments could be literal types, other variables, or
  582. // even nested function calls.
  583. // For now, we don't care if the params are valid, as this is
  584. // the job of the semantic analyzer which comes after the
  585. // parsing module.
  586. // The assumption here is that the current token is a function
  587. // call, so we check if it's legit and start digging.
  588. let func_name = token.token.as_str();
  589. // TODO: MAKE SURE IT'S A SYMBOL
  590. if let Some(op) = Opcode::from_name(func_name) {
  591. let rhs = self.parse_function_call(token, &mut iter);
  592. stmt.opcode = op;
  593. stmt.rhs = rhs;
  594. } else {
  595. self.error.abort(
  596. &format!("Unimplemented opcode `{}`.", func_name),
  597. token.line,
  598. token.column,
  599. );
  600. }
  601. ret.push(stmt);
  602. stmt = Statement::default();
  603. }
  604. }
  605. ret
  606. }
  607. fn parse_function_call(
  608. &self,
  609. token: &Token,
  610. iter: &mut Peekable<std::slice::Iter<'_, Token>>,
  611. ) -> Vec<Arg> {
  612. if let Some(next_token) = iter.peek() {
  613. if next_token.token_type != TokenType::LeftParen {
  614. self.error.abort(
  615. "Invalid function call opening. Must start with a '('.",
  616. next_token.line,
  617. next_token.column,
  618. );
  619. }
  620. // Skip the opening parenthesis
  621. iter.next();
  622. } else {
  623. self.error.abort("Premature ending of statement.", token.line, token.column);
  624. }
  625. let mut ret = vec![];
  626. // The next element in the iter now hopefully contains an opcode
  627. // argument. If it's another opcode, we'll recurse into this
  628. // function's logic.
  629. // Otherwise, we look for variable and literal types.
  630. while let Some(arg) = iter.next() {
  631. // ============================
  632. // Parse a nested function call
  633. // ============================
  634. if let Some(op_inner) = Opcode::from_name(&arg.token) {
  635. if let Some(paren) = iter.peek() {
  636. if paren.token_type != TokenType::LeftParen {
  637. self.error.abort(
  638. "Invalid function call opening. Must start with a '('.",
  639. paren.line,
  640. paren.column,
  641. );
  642. }
  643. // Recurse this function to get the params of the nested one.
  644. let args = self.parse_function_call(arg, iter);
  645. // Then we assign a "fake" variable that serves as a stack
  646. // reference.
  647. let var = Variable {
  648. name: format!("_op_inner_{}_{}", arg.line, arg.column),
  649. typ: VarType::Dummy,
  650. line: arg.line,
  651. column: arg.column,
  652. };
  653. let arg = Arg::Func(Statement {
  654. typ: StatementType::Assign,
  655. opcode: op_inner,
  656. lhs: Some(var),
  657. rhs: args,
  658. line: arg.line,
  659. });
  660. ret.push(arg);
  661. continue
  662. }
  663. self.error.abort(
  664. "Missing tokens in statement, there's a syntax error here.",
  665. arg.line,
  666. arg.column,
  667. );
  668. }
  669. // ==========================================
  670. // Parse normal argument, not a function call
  671. // ==========================================
  672. if let Some(sep) = iter.next() {
  673. // See if we have a variable or a literal type.
  674. match arg.token_type {
  675. TokenType::Symbol => ret.push(Arg::Var(Variable {
  676. name: arg.token.clone(),
  677. typ: VarType::Dummy,
  678. line: arg.line,
  679. column: arg.column,
  680. })),
  681. TokenType::Number => {
  682. // Check if we can actually convert this into a number.
  683. match arg.token.parse::<u64>() {
  684. Ok(_) => {}
  685. Err(e) => {
  686. self.error.abort(
  687. &format!("Failed to convert literal into u64: {}", e),
  688. arg.line,
  689. arg.column,
  690. );
  691. }
  692. };
  693. ret.push(Arg::Lit(Literal {
  694. name: arg.token.clone(),
  695. typ: LitType::Uint64,
  696. line: arg.line,
  697. column: arg.column,
  698. }))
  699. }
  700. TokenType::RightParen => {
  701. if let Some(comma) = iter.peek() {
  702. if comma.token_type == TokenType::Comma {
  703. iter.next();
  704. }
  705. }
  706. break
  707. }
  708. x => unimplemented!("{:#?}", x),
  709. };
  710. if sep.token_type == TokenType::RightParen {
  711. if let Some(comma) = iter.peek() {
  712. if comma.token_type == TokenType::Comma {
  713. iter.next();
  714. }
  715. }
  716. // Reached end of args
  717. break
  718. }
  719. if sep.token_type != TokenType::Comma {
  720. self.error.abort(
  721. "Argument separator is not a comma (`,`)",
  722. sep.line,
  723. sep.column,
  724. );
  725. }
  726. }
  727. }
  728. ret
  729. }
  730. }