parser.rs 40 KB

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