parser.rs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. borrow::Borrow, collections::HashMap, hash::Hash, io::Result, iter::Peekable, str::Chars,
  20. };
  21. use super::{
  22. ast::{Arg, Constant, Literal, Statement, StatementType, Variable, Witness},
  23. constants::{ALLOWED_FIELDS, MAX_K, MAX_NS_LEN},
  24. error::ErrorEmitter,
  25. lexer::{Token, TokenType},
  26. LitType, Opcode, VarType,
  27. };
  28. /// zkas language builtin keywords.
  29. /// These can not be used anywhere except where they are expected.
  30. const KEYWORDS: [&str; 5] = ["k", "field", "constant", "witness", "circuit"];
  31. /// Forbidden namespaces
  32. const NOPE_NS: [&str; 4] = [".constant", ".literal", ".witness", ".circuit"];
  33. /// Valid EcFixedPoint constant names supported by the VM.
  34. const VALID_ECFIXEDPOINT: [&str; 1] = ["VALUE_COMMIT_RANDOM"];
  35. /// Valid EcFixedPointShort constant names supported by the VM.
  36. const VALID_ECFIXEDPOINTSHORT: [&str; 1] = ["VALUE_COMMIT_VALUE"];
  37. /// Valid EcFixedPointBase constant names supported by the VM.
  38. const VALID_ECFIXEDPOINTBASE: [&str; 2] = ["VALUE_COMMIT_RANDOM_BASE", "NULLIFIER_K"];
  39. #[derive(Clone)]
  40. struct IndexMap<K, V> {
  41. pub order: Vec<K>,
  42. pub map: HashMap<K, V>,
  43. }
  44. impl<K, V> IndexMap<K, V> {
  45. fn new() -> Self {
  46. Self { order: vec![], map: HashMap::new() }
  47. }
  48. }
  49. impl<K, V> IndexMap<K, V>
  50. where
  51. K: Eq + Hash + Send + Sync + Clone + 'static,
  52. V: Send + Sync + Clone + 'static,
  53. {
  54. fn contains_key<Q: Hash + Eq + ?Sized>(&self, k: &Q) -> bool
  55. where
  56. K: Borrow<Q>,
  57. {
  58. self.map.contains_key(k)
  59. }
  60. fn get<Q: Hash + Eq + ?Sized>(&self, k: &Q) -> Option<&V>
  61. where
  62. K: Borrow<Q>,
  63. {
  64. self.map.get(k)
  65. }
  66. fn insert(&mut self, k: K, v: V) -> Option<V> {
  67. self.order.push(k.clone());
  68. self.map.insert(k, v)
  69. }
  70. fn scam_iter(&self) -> Vec<(K, V)> {
  71. self.order.iter().map(|k| (k.clone(), self.get(k).unwrap().clone())).collect()
  72. }
  73. }
  74. pub struct Parser {
  75. tokens: Vec<Token>,
  76. error: ErrorEmitter,
  77. }
  78. type Parsed = (String, u32, Vec<Constant>, Vec<Witness>, Vec<Statement>);
  79. impl Parser {
  80. pub fn new(filename: &str, source: Chars, tokens: Vec<Token>) -> Self {
  81. // For nice error reporting, we'll load everything into a string
  82. // vector so we have references to lines.
  83. let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
  84. let error = ErrorEmitter::new("Parser", filename, lines);
  85. Self { tokens, error }
  86. }
  87. pub fn parse(&self) -> Result<Parsed> {
  88. // We use these to keep state while parsing.
  89. let mut namespace = None;
  90. let (mut declaring_constant, mut declared_constant) = (false, false);
  91. let (mut declaring_witness, mut declared_witness) = (false, false);
  92. let (mut declaring_circuit, mut declared_circuit) = (false, false);
  93. // The tokens gathered from each of the sections
  94. let mut constant_tokens = vec![];
  95. let mut witness_tokens = vec![];
  96. let mut circuit_tokens = vec![];
  97. // Tokens belonging to the current statement
  98. let mut circuit_stmt = vec![];
  99. // All completed statements are pushed here
  100. let mut circuit_stmts = vec![];
  101. // Contains constant and witness sections
  102. let mut ast_inner = IndexMap::new();
  103. let mut ast = IndexMap::new();
  104. if self.tokens.is_empty() {
  105. return Err(self.error.abort("Source file does not contain any valid tokens.", 0, 0))
  106. }
  107. if self.tokens[0].token_type != TokenType::Symbol {
  108. return Err(self.error.abort(
  109. "Source file does not start with a section. Expected `constant/witness/circuit`.",
  110. 0,
  111. 0,
  112. ))
  113. }
  114. let mut iter = self.tokens.iter();
  115. // The first thing that has to be declared in the source
  116. // code is the constant "k" which defines 2^k rows that
  117. // the circuit needs to successfully execute.
  118. let Some((k, equal, number, semicolon)) = NextTuple4::next_tuple(&mut iter) else {
  119. return Err(self.error.abort("Source file does not start with k=n;", 0, 0))
  120. };
  121. if k.token_type != TokenType::Symbol ||
  122. equal.token_type != TokenType::Assign ||
  123. number.token_type != TokenType::Number ||
  124. semicolon.token_type != TokenType::Semicolon
  125. {
  126. return Err(self.error.abort("Source file does not start with k=n;", k.line, k.column))
  127. }
  128. if k.token != "k" {
  129. return Err(self.error.abort("Source file does not start with k=n;", k.line, k.column))
  130. }
  131. // Ensure that the value for k can be parsed correctly into the token type.
  132. // The below code catches cases where a large k value exceeding the bounds of the target
  133. // type is supplied by the user. Without this check an integer overflow can occur.
  134. let declared_k = match number.token.parse() {
  135. Ok(v) => v,
  136. Err(e) => {
  137. return Err(self.error.abort(
  138. &format!("k param is invalid, max allowed is {}. Error: {}", MAX_K, e),
  139. number.line,
  140. number.column,
  141. ))
  142. }
  143. };
  144. if declared_k > MAX_K {
  145. return Err(self.error.abort(
  146. &format!("k param is too high, max allowed is {}", MAX_K),
  147. number.line,
  148. number.column,
  149. ))
  150. }
  151. // Then we declare the field we're working in.
  152. let Some((field, equal, field_name, semicolon)) = NextTuple4::next_tuple(&mut iter) else {
  153. return Err(self.error.abort(
  154. "Source file does not declare field after k",
  155. k.line,
  156. k.column,
  157. ))
  158. };
  159. if field.token_type != TokenType::Symbol ||
  160. equal.token_type != TokenType::Assign ||
  161. field_name.token_type != TokenType::String ||
  162. semicolon.token_type != TokenType::Semicolon
  163. {
  164. return Err(self.error.abort(
  165. "Source file does not declare field after k",
  166. field.line,
  167. field.column,
  168. ))
  169. }
  170. if field.token != "field" {
  171. return Err(self.error.abort(
  172. "Source file does not declare field after k",
  173. field.line,
  174. field.column,
  175. ))
  176. }
  177. if !ALLOWED_FIELDS.contains(&field_name.token.as_str()) {
  178. return Err(self.error.abort(
  179. &format!(
  180. "Declared field \"{}\" is not supported. Use any of: {:?}",
  181. field_name.token, ALLOWED_FIELDS
  182. ),
  183. field_name.line,
  184. field_name.column,
  185. ))
  186. }
  187. while let Some(t) = iter.next() {
  188. // Sections "constant", "witness", and "circuit" are
  189. // the sections we must be declaring in our source code.
  190. // When we find one, we'll take all the tokens found in
  191. // the section and place them in their respective vec.
  192. // NOTE: Currently this logic depends on the fact that
  193. // the sections are closed off with braces. This should
  194. // be revisited later when we decide to add other lang
  195. // functionality that also depends on using braces.
  196. if !declaring_constant && !declaring_witness && !declaring_circuit {
  197. //
  198. // We use this macro to avoid code repetition in the following
  199. // match statement for soaking up the section tokens.
  200. macro_rules! absorb_inner_tokens {
  201. ($v:ident) => {
  202. for inner in iter.by_ref() {
  203. if KEYWORDS.contains(&inner.token.as_str()) &&
  204. inner.token_type == TokenType::Symbol
  205. {
  206. return Err(self.error.abort(
  207. &format!("Keyword '{}' used in improper place.", inner.token),
  208. inner.line,
  209. inner.column,
  210. ))
  211. }
  212. $v.push(inner.clone());
  213. if inner.token_type == TokenType::RightBrace {
  214. break
  215. }
  216. }
  217. };
  218. }
  219. match t.token.as_str() {
  220. "constant" => {
  221. declaring_constant = true;
  222. absorb_inner_tokens!(constant_tokens);
  223. }
  224. "witness" => {
  225. declaring_witness = true;
  226. absorb_inner_tokens!(witness_tokens);
  227. }
  228. "circuit" => {
  229. declaring_circuit = true;
  230. absorb_inner_tokens!(circuit_tokens);
  231. }
  232. x => {
  233. return Err(self.error.abort(
  234. &format!("Section `{}` is not a valid section", x),
  235. t.line,
  236. t.column,
  237. ))
  238. }
  239. }
  240. }
  241. // We use this macro to set or check that the namespace of all sections
  242. // is the same and no stray strings appeared.
  243. macro_rules! check_namespace {
  244. ($t:ident) => {
  245. if let Some(ns) = namespace.clone() {
  246. if ns != $t[0].token {
  247. return Err(self.error.abort(
  248. &format!("Found '{}' namespace, expected '{}'.", $t[0].token, ns),
  249. $t[0].line,
  250. $t[0].column,
  251. ))
  252. }
  253. } else {
  254. if NOPE_NS.contains(&$t[0].token.as_str()) {
  255. return Err(self.error.abort(
  256. &format!("'{}' cannot be a namespace.", $t[0].token),
  257. $t[0].line,
  258. $t[0].column,
  259. ))
  260. }
  261. namespace = Some($t[0].token.clone());
  262. if namespace.as_ref().unwrap().as_bytes().len() > MAX_NS_LEN {
  263. return Err(self.error.abort(
  264. &format!("Namespace too long, max {} bytes", MAX_NS_LEN),
  265. $t[0].line,
  266. $t[0].column,
  267. ))
  268. }
  269. }
  270. };
  271. }
  272. // Parse the constant section into the AST.
  273. if declaring_constant {
  274. if declared_constant {
  275. return Err(self.error.abort(
  276. "Duplicate `constant` section found.",
  277. t.line,
  278. t.column,
  279. ))
  280. }
  281. self.check_section_structure("constant", constant_tokens.clone())?;
  282. check_namespace!(constant_tokens);
  283. let mut constants_map = IndexMap::new();
  284. // This is everything between the braces: { ... }
  285. let mut constant_inner = constant_tokens[2..constant_tokens.len() - 1].iter();
  286. while let Some((typ, name, comma)) = NextTuple3::next_tuple(&mut constant_inner) {
  287. if comma.token_type != TokenType::Comma {
  288. return Err(self.error.abort(
  289. "Separator is not a comma.",
  290. comma.line,
  291. comma.column,
  292. ))
  293. }
  294. // No variable shadowing
  295. if constants_map.contains_key(name.token.as_str()) {
  296. return Err(self.error.abort(
  297. &format!(
  298. "Section `constant` already contains the token `{}`.",
  299. &name.token
  300. ),
  301. name.line,
  302. name.column,
  303. ))
  304. }
  305. constants_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  306. }
  307. if constant_inner.next().is_some() {
  308. return Err(self.error.abort(
  309. "Internal error, leftovers in 'constant' iterator",
  310. 0,
  311. 0,
  312. ))
  313. }
  314. ast_inner.insert("constant".to_string(), constants_map);
  315. declaring_constant = false;
  316. declared_constant = true;
  317. }
  318. // Parse the witness section into the AST.
  319. if declaring_witness {
  320. if declared_witness {
  321. return Err(self.error.abort(
  322. "Duplicate `witness` section found.",
  323. t.line,
  324. t.column,
  325. ))
  326. }
  327. self.check_section_structure("witness", witness_tokens.clone())?;
  328. check_namespace!(witness_tokens);
  329. let mut witnesses_map = IndexMap::new();
  330. // This is everything between the braces: { ... }
  331. let mut witness_inner = witness_tokens[2..witness_tokens.len() - 1].iter();
  332. while let Some((typ, name, comma)) = NextTuple3::next_tuple(&mut witness_inner) {
  333. if comma.token_type != TokenType::Comma {
  334. return Err(self.error.abort(
  335. "Separator is not a comma.",
  336. comma.line,
  337. comma.column,
  338. ))
  339. }
  340. // No variable shadowing
  341. if witnesses_map.contains_key(name.token.as_str()) {
  342. return Err(self.error.abort(
  343. &format!(
  344. "Section `witness` already contains the token `{}`.",
  345. &name.token
  346. ),
  347. name.line,
  348. name.column,
  349. ))
  350. }
  351. witnesses_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  352. }
  353. if witness_inner.next().is_some() {
  354. return Err(self.error.abort(
  355. "Internal error, leftovers in 'witness' iterator",
  356. 0,
  357. 0,
  358. ))
  359. }
  360. ast_inner.insert("witness".to_string(), witnesses_map);
  361. declaring_witness = false;
  362. declared_witness = true;
  363. }
  364. // Parse the circuit section into the AST.
  365. if declaring_circuit {
  366. if declared_circuit {
  367. return Err(self.error.abort(
  368. "Duplicate `circuit` section found.",
  369. t.line,
  370. t.column,
  371. ))
  372. }
  373. self.check_section_structure("circuit", circuit_tokens.clone())?;
  374. check_namespace!(circuit_tokens);
  375. // Grab tokens for each statement
  376. for i in circuit_tokens[2..circuit_tokens.len() - 1].iter() {
  377. if i.token_type == TokenType::Semicolon {
  378. // Push completed statement to the heap
  379. circuit_stmts.push(circuit_stmt.clone());
  380. circuit_stmt = vec![];
  381. continue
  382. }
  383. circuit_stmt.push(i.clone());
  384. }
  385. declaring_circuit = false;
  386. declared_circuit = true;
  387. }
  388. }
  389. // Tokens have been processed and ast is complete
  390. let ns = match namespace {
  391. Some(v) => v,
  392. None => return Err(self.error.abort("Missing namespace in .zk source.", 0, 0)),
  393. };
  394. ast.insert(ns.clone(), ast_inner);
  395. let constants = {
  396. let c = match ast.get(&ns).unwrap().get("constant") {
  397. Some(c) => c,
  398. None => {
  399. return Err(self.error.abort("Missing `constant` section in .zk source.", 0, 0))
  400. }
  401. };
  402. self.parse_ast_constants(c)?
  403. };
  404. let witnesses = {
  405. let c = match ast.get(&ns).unwrap().get("witness") {
  406. Some(c) => c,
  407. None => {
  408. return Err(self.error.abort("Missing `witness` section in .zk source.", 0, 0))
  409. }
  410. };
  411. self.parse_ast_witness(c)?
  412. };
  413. let statements = self.parse_ast_circuit(circuit_stmts)?;
  414. if statements.is_empty() {
  415. return Err(self.error.abort("Circuit section is empty.", 0, 0))
  416. }
  417. Ok((ns, declared_k, constants, witnesses, statements))
  418. }
  419. /// Routine checks on section structure
  420. fn check_section_structure(&self, section: &str, tokens: Vec<Token>) -> Result<()> {
  421. // Offsets 0 and 1 are accessed directly below, so we need a length of at
  422. // least 2 in order to avoid an index-out-of-bounds panic.
  423. if tokens.len() < 2 {
  424. return Err(self.error.abort("Insufficient number of tokens in section.", 0, 0))
  425. }
  426. if tokens[0].token_type != TokenType::String {
  427. return Err(self.error.abort(
  428. "Section declaration must start with a naming string.",
  429. tokens[0].line,
  430. tokens[0].column,
  431. ))
  432. }
  433. if tokens[1].token_type != TokenType::LeftBrace {
  434. return Err(self.error.abort(
  435. "Section must be opened with a left brace '{'",
  436. tokens[0].line,
  437. tokens[0].column,
  438. ))
  439. }
  440. if tokens.last().unwrap().token_type != TokenType::RightBrace {
  441. return Err(self.error.abort(
  442. "Section must be closed with a right brace '}'",
  443. tokens[0].line,
  444. tokens[0].column,
  445. ))
  446. }
  447. match section {
  448. "constant" | "witness" => {
  449. if tokens.len() == 3 {
  450. self.error.warn(&format!("{} section is empty.", section), 0, 0);
  451. }
  452. if tokens[2..tokens.len() - 1].len() % 3 != 0 {
  453. return Err(self.error.abort(
  454. &format!("Invalid number of elements in '{}' section. Must be pairs of '<Type> <name>' separated with a comma ','.", section),
  455. tokens[0].line,
  456. tokens[0].column
  457. ))
  458. }
  459. }
  460. "circuit" => {
  461. if tokens.len() == 3 {
  462. return Err(self.error.abort("circuit section is empty.", 0, 0))
  463. }
  464. if tokens[tokens.len() - 2].token_type != TokenType::Semicolon {
  465. return Err(self.error.abort(
  466. "Circuit section does not end with a semicolon. Would never finish parsing.",
  467. tokens[tokens.len()-2].line,
  468. tokens[tokens.len()-2].column,
  469. ))
  470. }
  471. }
  472. _ => unreachable!(),
  473. };
  474. Ok(())
  475. }
  476. fn parse_ast_constants(&self, ast: &IndexMap<String, (Token, Token)>) -> Result<Vec<Constant>> {
  477. let mut ret = vec![];
  478. // k = name
  479. // v = (name, type)
  480. for (k, v) in ast.scam_iter() {
  481. if v.0.token != k {
  482. return Err(self.error.abort(
  483. &format!("Constant name `{}` doesn't match token `{}`.", v.0.token, k),
  484. v.0.line,
  485. v.0.column,
  486. ))
  487. }
  488. if v.0.token_type != TokenType::Symbol {
  489. return Err(self.error.abort(
  490. &format!("Constant name `{}` is not a symbol.", v.0.token),
  491. v.0.line,
  492. v.0.column,
  493. ))
  494. }
  495. if v.1.token_type != TokenType::Symbol {
  496. return Err(self.error.abort(
  497. &format!("Constant type `{}` is not a symbol.", v.1.token),
  498. v.1.line,
  499. v.1.column,
  500. ))
  501. }
  502. // Valid constant types, these are the constants/generators supported
  503. // in `src/crypto/constants.rs` and `src/crypto/constants/`.
  504. match v.1.token.as_str() {
  505. "EcFixedPoint" => {
  506. if !VALID_ECFIXEDPOINT.contains(&v.0.token.as_str()) {
  507. return Err(self.error.abort(
  508. &format!(
  509. "`{}` is not a valid EcFixedPoint constant. Supported: {:?}",
  510. v.0.token.as_str(),
  511. VALID_ECFIXEDPOINT
  512. ),
  513. v.0.line,
  514. v.0.column,
  515. ))
  516. }
  517. ret.push(Constant {
  518. name: k.to_string(),
  519. typ: VarType::EcFixedPoint,
  520. line: v.1.line,
  521. column: v.1.column,
  522. });
  523. }
  524. "EcFixedPointShort" => {
  525. if !VALID_ECFIXEDPOINTSHORT.contains(&v.0.token.as_str()) {
  526. return Err(self.error.abort(
  527. &format!(
  528. "`{}` is not a valid EcFixedPointShort constant. Supported: {:?}",
  529. v.0.token.as_str(),
  530. VALID_ECFIXEDPOINTSHORT
  531. ),
  532. v.0.line,
  533. v.0.column,
  534. ))
  535. }
  536. ret.push(Constant {
  537. name: k.to_string(),
  538. typ: VarType::EcFixedPointShort,
  539. line: v.1.line,
  540. column: v.1.column,
  541. });
  542. }
  543. "EcFixedPointBase" => {
  544. if !VALID_ECFIXEDPOINTBASE.contains(&v.0.token.as_str()) {
  545. return Err(self.error.abort(
  546. &format!(
  547. "`{}` is not a valid EcFixedPointBase constant. Supported: {:?}",
  548. v.0.token.as_str(),
  549. VALID_ECFIXEDPOINTBASE
  550. ),
  551. v.0.line,
  552. v.0.column,
  553. ))
  554. }
  555. ret.push(Constant {
  556. name: k.to_string(),
  557. typ: VarType::EcFixedPointBase,
  558. line: v.1.line,
  559. column: v.1.column,
  560. });
  561. }
  562. x => {
  563. return Err(self.error.abort(
  564. &format!("`{}` is an unsupported constant type.", x),
  565. v.1.line,
  566. v.1.column,
  567. ))
  568. }
  569. }
  570. }
  571. Ok(ret)
  572. }
  573. fn parse_ast_witness(&self, ast: &IndexMap<String, (Token, Token)>) -> Result<Vec<Witness>> {
  574. let mut ret = vec![];
  575. // k = name
  576. // v = (name, type)
  577. for (k, v) in ast.scam_iter() {
  578. if v.0.token != k {
  579. return Err(self.error.abort(
  580. &format!("Witness name `{}` doesn't match token `{}`.", v.0.token, k),
  581. v.0.line,
  582. v.0.column,
  583. ))
  584. }
  585. if v.0.token_type != TokenType::Symbol {
  586. return Err(self.error.abort(
  587. &format!("Witness name `{}` is not a symbol.", v.0.token),
  588. v.0.line,
  589. v.0.column,
  590. ))
  591. }
  592. if v.1.token_type != TokenType::Symbol {
  593. return Err(self.error.abort(
  594. &format!("Witness type `{}` is not a symbol.", v.1.token),
  595. v.1.line,
  596. v.1.column,
  597. ))
  598. }
  599. // Valid witness types
  600. // TODO: change to TryFrom impl for VarType
  601. match v.1.token.as_str() {
  602. "EcPoint" => {
  603. ret.push(Witness {
  604. name: k.to_string(),
  605. typ: VarType::EcPoint,
  606. line: v.0.line,
  607. column: v.0.column,
  608. });
  609. }
  610. "EcNiPoint" => {
  611. ret.push(Witness {
  612. name: k.to_string(),
  613. typ: VarType::EcNiPoint,
  614. line: v.0.line,
  615. column: v.0.column,
  616. });
  617. }
  618. "Base" => {
  619. ret.push(Witness {
  620. name: k.to_string(),
  621. typ: VarType::Base,
  622. line: v.0.line,
  623. column: v.0.column,
  624. });
  625. }
  626. "Scalar" => {
  627. ret.push(Witness {
  628. name: k.to_string(),
  629. typ: VarType::Scalar,
  630. line: v.0.line,
  631. column: v.0.column,
  632. });
  633. }
  634. "MerklePath" => {
  635. ret.push(Witness {
  636. name: k.to_string(),
  637. typ: VarType::MerklePath,
  638. line: v.0.line,
  639. column: v.0.column,
  640. });
  641. }
  642. "SparseMerklePath" => {
  643. ret.push(Witness {
  644. name: k.to_string(),
  645. typ: VarType::SparseMerklePath,
  646. line: v.0.line,
  647. column: v.0.column,
  648. });
  649. }
  650. "Uint32" => {
  651. ret.push(Witness {
  652. name: k.to_string(),
  653. typ: VarType::Uint32,
  654. line: v.0.line,
  655. column: v.0.column,
  656. });
  657. }
  658. "Uint64" => {
  659. ret.push(Witness {
  660. name: k.to_string(),
  661. typ: VarType::Uint64,
  662. line: v.0.line,
  663. column: v.0.column,
  664. });
  665. }
  666. x => {
  667. return Err(self.error.abort(
  668. &format!("`{}` is an unsupported witness type.", x),
  669. v.1.line,
  670. v.1.column,
  671. ))
  672. }
  673. }
  674. }
  675. Ok(ret)
  676. }
  677. fn parse_ast_circuit(&self, statements: Vec<Vec<Token>>) -> Result<Vec<Statement>> {
  678. // The statement layouts/syntax in the language are as follows:
  679. //
  680. // C = poseidon_hash(pub_x, pub_y, value, token, serial);
  681. // | | | | |
  682. // V V V V V
  683. // variable opcode arg arg
  684. // assign
  685. //
  686. // constrain_instance(C);
  687. // | |
  688. // V V
  689. // opcode arg
  690. //
  691. // inner opcode arg
  692. // |
  693. // constrain_instance(ec_get_x(foo));
  694. // | |
  695. // V V
  696. // opcode arg as opcode
  697. //
  698. // In the latter, we want to support nested function calls, e.g.:
  699. //
  700. // constrain_instance(ec_get_x(token_commit));
  701. //
  702. // The inner call's result would still get pushed on the heap,
  703. // but it will not be accessible in any other scope.
  704. //
  705. // In certain opcodes, we also support literal types, and the
  706. // opcodes can return a variable type after running the operation.
  707. // e.g.
  708. // one = witness_base(1);
  709. // zero = witness_base(0);
  710. //
  711. // The literal type is used only in the function call's scope, but
  712. // the result is then accessible on the heap to be used by further
  713. // computation.
  714. //
  715. // Regarding multiple return values from opcodes, this is perhaps
  716. // not necessary for the current language scope, as this is a low
  717. // level representation. Note that it could be relatively easy to
  718. // modify the parsing logic to support that here. For now we'll
  719. // defer it, and if at some point we decide that the language is
  720. // too expressive and noisy, we'll consider having multiple return
  721. // types. It also very much depends on the type of functions/opcodes
  722. // that we want to support.
  723. // Vec of statements to return from this entire parsing operation.
  724. let mut ret = vec![];
  725. // Here, our statements tokens have been parsed and delimited by
  726. // semicolons (;) in the source file. This iterator contains each
  727. // of those statements as an array of tokens we then consume and
  728. // build the AST further.
  729. for statement in statements {
  730. if statement.is_empty() {
  731. continue
  732. }
  733. let (mut left_paren, mut right_paren, mut left_bracket, mut right_bracket) =
  734. (0, 0, 0, 0);
  735. for i in &statement {
  736. match i.token.as_str() {
  737. "(" => left_paren += 1,
  738. ")" => right_paren += 1,
  739. "[" => left_bracket += 1,
  740. "]" => right_bracket += 1,
  741. _ => {}
  742. }
  743. }
  744. if (left_paren == 0 && right_paren == 0) && (left_bracket == 0 && right_bracket == 0) {
  745. return Err(self.error.abort(
  746. "Statement must include a function call or array initialization. No parentheses or square brackets present.",
  747. statement[0].line,
  748. statement[0].column,
  749. ))
  750. }
  751. if (left_bracket != right_bracket) || (left_paren != right_paren) {
  752. return Err(self.error.abort(
  753. "Parentheses or brackets are not matched.",
  754. statement[0].line,
  755. statement[0].column,
  756. ))
  757. }
  758. // Is there a valid use-case for defining nested arrays? For now,
  759. // if square brackets are present, raise an error unless there is
  760. // exactly one pair.
  761. if left_bracket > 1 {
  762. return Err(self.error.abort(
  763. "Only one pair of brackets allowed for array declaration",
  764. statement[0].line,
  765. statement[0].column,
  766. ))
  767. }
  768. // Peekable iterator so we can see tokens in advance
  769. // without consuming the iterator.
  770. let mut iter = statement.iter().peekable();
  771. // Dummy statement that we'll hopefully fill now.
  772. let mut stmt = Statement::default();
  773. let mut parsing = false;
  774. while let Some(token) = iter.next() {
  775. if !parsing {
  776. // TODO: MAKE SURE IT'S A SYMBOL
  777. // This logic must be changed if we want to support
  778. // multiple return values.
  779. if let Some(next_token) = iter.peek() {
  780. if next_token.token_type == TokenType::Assign {
  781. stmt.line = token.line;
  782. stmt.typ = StatementType::Assign;
  783. stmt.rhs = vec![];
  784. stmt.lhs = Some(Variable {
  785. name: token.token.clone(),
  786. typ: VarType::Dummy,
  787. line: token.line,
  788. column: token.column,
  789. });
  790. // Skip over the `=` token.
  791. iter.next();
  792. parsing = true;
  793. continue
  794. }
  795. if next_token.token_type == TokenType::LeftParen {
  796. stmt.line = token.line;
  797. stmt.typ = StatementType::Call;
  798. stmt.rhs = vec![];
  799. stmt.lhs = None;
  800. parsing = true;
  801. }
  802. if !parsing {
  803. return Err(self.error.abort(
  804. &format!("Illegal token `{}`.", next_token.token),
  805. next_token.line,
  806. next_token.column,
  807. ))
  808. }
  809. }
  810. }
  811. // If parsing == true, we now know if we're making a variable
  812. // assignment or a function call without a return value.
  813. // Let's dig deeper to see what the statement's call is, and
  814. // what it contains as arguments. With this we'll fill `rhs`.
  815. // The arguments could be literal types, other variables, an
  816. // array declaration, or even nested function calls.
  817. // For now, we don't care if the params are valid, as this is
  818. // the job of the semantic analyzer which comes after the
  819. // parsing module.
  820. // Array declaration.
  821. // TODO: Support function calls in array declarations. Currently
  822. // only literals can be used to construct an array.
  823. // Check only left_bracket. Validation to check that the brackets
  824. // are matched has already been performed above.
  825. if left_bracket > 0 {
  826. return Err(self.error.abort(
  827. "Arrays are not implemented yet.",
  828. token.line,
  829. token.column,
  830. ))
  831. //let rhs = self.parse_array_assignment(&mut iter);
  832. }
  833. // The assumption here is that the current token is a function
  834. // call, so we check if it's legit and start digging.
  835. let func_name = token.token.as_str();
  836. // Ensure the current function is a symbol
  837. if token.token_type != TokenType::Symbol {
  838. return Err(self.error.abort(
  839. "This token is not a symbol.",
  840. token.line,
  841. token.column,
  842. ))
  843. }
  844. if let Some(op) = Opcode::from_name(func_name) {
  845. let rhs = self.parse_function_call(token, &mut iter)?;
  846. stmt.opcode = op;
  847. stmt.rhs = rhs;
  848. } else {
  849. return Err(self.error.abort(
  850. &format!("Unimplemented opcode `{}`.", func_name),
  851. token.line,
  852. token.column,
  853. ))
  854. }
  855. // At this stage of parsing, we should have assigned `stmt` a StatementType that is
  856. // not a Noop. If we have failed to do so, we cannot proceed because Nooops must
  857. // never be pased to the compiler. This can occur when multiple independent
  858. // statements are passed on one line, or if a statement is not terminated by a
  859. // semicolon.
  860. if stmt.typ == StatementType::Noop {
  861. return Err(self.error.abort(
  862. "Statement is a NOOP; not allowed. (Did you miss a semicolon?)",
  863. token.line,
  864. token.column,
  865. ))
  866. }
  867. ret.push(stmt);
  868. stmt = Statement::default();
  869. }
  870. }
  871. Ok(ret)
  872. }
  873. // fn parse_array_assignment(
  874. // &self,
  875. // iter: &mut Peekable<std::slice::Iter<'_, Token>>,
  876. // ) -> Result<Vec<Arg>> {
  877. // if let Some(next_token) = iter.peek() {
  878. // if next_token.token_type != TokenType::LeftBracket {
  879. // return Err(self.error.abort(
  880. // "Invalid array assignment opening. Must start with a '['.",
  881. // next_token.line,
  882. // next_token.column,
  883. // ))
  884. // }
  885. // // Skip the opening parenthesis
  886. // iter.next();
  887. // } else {
  888. // // TODO: Use token line number and column
  889. // return Err(self.error.abort("Premature ending of statement.", 0, 0))
  890. // }
  891. // todo!();
  892. // }
  893. fn parse_function_call(
  894. &self,
  895. token: &Token,
  896. iter: &mut Peekable<std::slice::Iter<'_, Token>>,
  897. ) -> Result<Vec<Arg>> {
  898. if let Some(next_token) = iter.peek() {
  899. if next_token.token_type != TokenType::LeftParen {
  900. return Err(self.error.abort(
  901. "Invalid function call opening. Must start with a '('.",
  902. next_token.line,
  903. next_token.column,
  904. ))
  905. }
  906. // Skip the opening parenthesis
  907. iter.next();
  908. } else {
  909. return Err(self.error.abort("Premature ending of statement.", token.line, token.column))
  910. }
  911. let mut ret = vec![];
  912. // The next element in the iter now hopefully contains an opcode
  913. // argument. If it's another opcode, we'll recurse into this
  914. // function's logic.
  915. // Otherwise, we look for variable and literal types.
  916. while let Some(arg) = iter.next() {
  917. // ============================
  918. // Parse a nested function call
  919. // ============================
  920. if let Some(op_inner) = Opcode::from_name(&arg.token) {
  921. if let Some(paren) = iter.peek() {
  922. if paren.token_type != TokenType::LeftParen {
  923. return Err(self.error.abort(
  924. "Invalid function call opening. Must start with a '('.",
  925. paren.line,
  926. paren.column,
  927. ))
  928. }
  929. // Recurse this function to get the params of the nested one.
  930. let args = self.parse_function_call(arg, iter)?;
  931. // Then we assign a "fake" variable that serves as a heap
  932. // reference.
  933. let var = Variable {
  934. name: format!("_op_inner_{}_{}", arg.line, arg.column),
  935. typ: VarType::Dummy,
  936. line: arg.line,
  937. column: arg.column,
  938. };
  939. let arg = Arg::Func(Statement {
  940. typ: StatementType::Assign,
  941. opcode: op_inner,
  942. lhs: Some(var),
  943. rhs: args,
  944. line: arg.line,
  945. });
  946. ret.push(arg);
  947. continue
  948. }
  949. return Err(self.error.abort(
  950. "Missing tokens in statement, there's a syntax error here.",
  951. arg.line,
  952. arg.column,
  953. ))
  954. }
  955. // ==========================================
  956. // Parse normal argument, not a function call
  957. // ==========================================
  958. if let Some(sep) = iter.next() {
  959. // See if we have a variable or a literal type.
  960. match arg.token_type {
  961. TokenType::Symbol => ret.push(Arg::Var(Variable {
  962. name: arg.token.clone(),
  963. typ: VarType::Dummy,
  964. line: arg.line,
  965. column: arg.column,
  966. })),
  967. TokenType::Number => {
  968. // Check if we can actually convert this into a number.
  969. match arg.token.parse::<u64>() {
  970. Ok(_) => {}
  971. Err(e) => {
  972. return Err(self.error.abort(
  973. &format!("Failed to convert literal into u64: {}", e),
  974. arg.line,
  975. arg.column,
  976. ))
  977. }
  978. };
  979. ret.push(Arg::Lit(Literal {
  980. name: arg.token.clone(),
  981. typ: LitType::Uint64,
  982. line: arg.line,
  983. column: arg.column,
  984. }))
  985. }
  986. TokenType::RightParen => {
  987. if let Some(comma) = iter.peek() {
  988. if comma.token_type == TokenType::Comma {
  989. iter.next();
  990. }
  991. }
  992. break
  993. }
  994. // Note: Unimplemented symbols throw an error now instead of a panic.
  995. // This assists with fuzz testing as existing features can still be tested
  996. // without causing the fuzzer to choke due to the panic created
  997. // by unimplmented!().
  998. // x => unimplemented!("{:#?}", x),
  999. _ => {
  1000. return Err(self.error.abort(
  1001. "Character is illegal/unimplemented in this context",
  1002. arg.line,
  1003. arg.column,
  1004. ))
  1005. }
  1006. };
  1007. if sep.token_type == TokenType::RightParen {
  1008. if let Some(comma) = iter.peek() {
  1009. if comma.token_type == TokenType::Comma {
  1010. iter.next();
  1011. }
  1012. }
  1013. // Reached end of args
  1014. break
  1015. }
  1016. if sep.token_type != TokenType::Comma {
  1017. return Err(self.error.abort(
  1018. "Argument separator is not a comma (`,`)",
  1019. sep.line,
  1020. sep.column,
  1021. ))
  1022. }
  1023. }
  1024. }
  1025. Ok(ret)
  1026. }
  1027. }
  1028. trait NextTuple3<I>: Iterator<Item = I> {
  1029. fn next_tuple(&mut self) -> Option<(I, I, I)>;
  1030. }
  1031. impl<I: Iterator<Item = T>, T> NextTuple3<T> for I {
  1032. fn next_tuple(&mut self) -> Option<(T, T, T)> {
  1033. let a = self.next()?;
  1034. let b = self.next()?;
  1035. let c = self.next()?;
  1036. Some((a, b, c))
  1037. }
  1038. }
  1039. trait NextTuple4<I>: Iterator<Item = I> {
  1040. fn next_tuple(&mut self) -> Option<(I, I, I, I)>;
  1041. }
  1042. impl<I: Iterator<Item = T>, T> NextTuple4<T> for I {
  1043. fn next_tuple(&mut self) -> Option<(T, T, T, T)> {
  1044. let a = self.next()?;
  1045. let b = self.next()?;
  1046. let c = self.next()?;
  1047. let d = self.next()?;
  1048. Some((a, b, c, d))
  1049. }
  1050. }