parser.rs 42 KB

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