analyzer.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 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. io::{stdin, stdout, Read, Write},
  20. str::Chars,
  21. };
  22. use super::{
  23. ast::{Arg, Constant, Literal, Statement, StatementType, Var, Variable, Witness},
  24. error::ErrorEmitter,
  25. Opcode, VarType,
  26. };
  27. pub struct Analyzer {
  28. pub constants: Vec<Constant>,
  29. pub witnesses: Vec<Witness>,
  30. pub statements: Vec<Statement>,
  31. pub literals: Vec<Literal>,
  32. pub stack: Vec<Variable>,
  33. error: ErrorEmitter,
  34. }
  35. impl Analyzer {
  36. pub fn new(
  37. filename: &str,
  38. source: Chars,
  39. constants: Vec<Constant>,
  40. witnesses: Vec<Witness>,
  41. statements: Vec<Statement>,
  42. ) -> Self {
  43. // For nice error reporting, we'll load everything into a string
  44. // vector so we have references to lines.
  45. let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
  46. let error = ErrorEmitter::new("Semantic", filename, lines);
  47. Self { constants, witnesses, statements, literals: vec![], stack: vec![], error }
  48. }
  49. pub fn analyze_types(&mut self) {
  50. // To work around the pedantic safety, we'll make new vectors and then
  51. // replace the `statements` and `stack` vectors from the `Analyzer`
  52. // object when we are done.
  53. let mut statements = vec![];
  54. let mut stack = vec![];
  55. for statement in &self.statements {
  56. //println!("{:?}", statement);
  57. let mut stmt = statement.clone();
  58. let (return_types, arg_types) = statement.opcode.arg_types();
  59. let mut rhs = vec![];
  60. // This handling is kinda limiting, but it'll do for now.
  61. if !(arg_types[0] == VarType::BaseArray || arg_types[0] == VarType::ScalarArray) {
  62. // Check that number of args is correct
  63. if statement.rhs.len() != arg_types.len() {
  64. self.error.abort(
  65. &format!(
  66. "Incorrect number of arguments for statement. Expected {}, got {}.",
  67. arg_types.len(),
  68. statement.rhs.len()
  69. ),
  70. statement.line,
  71. 1,
  72. );
  73. }
  74. } else {
  75. // In case of arrays, check there's at least one element.
  76. if statement.rhs.is_empty() {
  77. self.error.abort(
  78. "Expected at least one element for statement using arrays.",
  79. statement.line,
  80. 1,
  81. );
  82. }
  83. }
  84. // Edge-cases for some opcodes
  85. #[allow(clippy::single_match)]
  86. match &statement.opcode {
  87. Opcode::RangeCheck => {
  88. if let Arg::Lit(arg0) = &statement.rhs[0] {
  89. if &arg0.name != "64" && &arg0.name != "253" {
  90. self.error.abort(
  91. "Supported range checks are only 64 and 253 bits.",
  92. arg0.line,
  93. arg0.column,
  94. );
  95. }
  96. } else {
  97. self.error.abort(
  98. "Invalid argument for range_check opcode.",
  99. statement.line,
  100. 0,
  101. );
  102. }
  103. }
  104. _ => {}
  105. }
  106. for (idx, arg) in statement.rhs.iter().enumerate() {
  107. // In case an argument is a function call, we will first
  108. // convert it to another statement that will get executed
  109. // before this one. An important assumption is that this
  110. // opcode has a return value. When executed we will push
  111. // this value onto the stack and use it as a reference to
  112. // the actual statement we're parsing at this moment.
  113. // TODO: FIXME: This needs a recursive algorithm, as this
  114. // only allows a single nested function.
  115. if let Arg::Func(func) = arg {
  116. let (f_return_types, f_arg_types) = func.opcode.arg_types();
  117. if f_return_types.is_empty() {
  118. self.error.abort(
  119. &format!(
  120. "Used a function argument which doesn't have a return value: {:?}",
  121. func.opcode
  122. ),
  123. statement.line,
  124. 1,
  125. );
  126. }
  127. let v = Variable {
  128. name: func.lhs.clone().unwrap().name,
  129. typ: f_return_types[0],
  130. line: func.lhs.clone().unwrap().line,
  131. column: func.lhs.clone().unwrap().column,
  132. };
  133. // FIXME: Needs better *Array handling.
  134. if arg_types[0] == VarType::BaseArray {
  135. if f_return_types[0] != VarType::Base {
  136. self.error.abort(
  137. &format!(
  138. "Function passed as argument returns wrong type. Expected `{:?}`, got `{:?}`.",
  139. VarType::Base,
  140. f_return_types[0],
  141. ),
  142. v.line,
  143. v.column,
  144. );
  145. }
  146. } else if arg_types[0] == VarType::ScalarArray {
  147. if f_return_types[0] != VarType::Scalar {
  148. self.error.abort(
  149. &format!(
  150. "Function passed as argument returns wrong type. Expected `{:?}`, got `{:?}`.",
  151. VarType::Scalar,
  152. f_return_types[0],
  153. ),
  154. v.line,
  155. v.column,
  156. );
  157. }
  158. } else if f_return_types[0] != arg_types[idx] {
  159. self.error.abort(
  160. &format!(
  161. "Function passed as argument returns wrong type. Expected `{:?}`, got `{:?}`.",
  162. arg_types[idx],
  163. f_return_types[0],
  164. ),
  165. v.line,
  166. v.column,
  167. );
  168. }
  169. // Replace the statement function call with the variable from
  170. // the statement we just created to represent this nest.
  171. stmt.rhs[idx] = Arg::Var(v.clone());
  172. let mut rhs_inner = vec![];
  173. for (inner_idx, i) in func.rhs.iter().enumerate() {
  174. if let Arg::Var(v) = i {
  175. if let Some(var_ref) = self.lookup_var(&v.name) {
  176. let (var_type, ln, col) = match var_ref {
  177. Var::Constant(c) => (c.typ, c.line, c.column),
  178. Var::Witness(c) => (c.typ, c.line, c.column),
  179. Var::Variable(c) => (c.typ, c.line, c.column),
  180. };
  181. if var_type != f_arg_types[inner_idx] {
  182. self.error.abort(
  183. &format!(
  184. "Incorrect argument type. Expected `{:?}`, got `{:?}`.",
  185. f_arg_types[inner_idx], var_type
  186. ),
  187. ln,
  188. col,
  189. );
  190. }
  191. // Apply the proper type.
  192. let mut v_new = v.clone();
  193. v_new.typ = var_type;
  194. rhs_inner.push(Arg::Var(v_new));
  195. continue
  196. }
  197. self.error.abort(
  198. &format!("Unknown variable reference `{}`.", v.name),
  199. v.line,
  200. v.column,
  201. );
  202. } else {
  203. unimplemented!()
  204. }
  205. }
  206. let s = Statement {
  207. typ: func.typ,
  208. opcode: func.opcode,
  209. lhs: Some(v.clone()),
  210. rhs: rhs_inner,
  211. line: func.line,
  212. };
  213. // The lhs of the inner function call becomes rhs of the outer one.
  214. rhs.push(Arg::Var(v.clone()));
  215. // Add this to the list of statements.
  216. statements.push(s);
  217. // We replace self.stack here so we can do proper stack lookups.
  218. stack.push(v.clone());
  219. self.stack = stack.clone();
  220. //println!("{:#?}", stack);
  221. //println!("{:#?}", statements);
  222. continue
  223. } // <-- Arg::Func
  224. // The literals get pushed on their own "stack", and
  225. // then the compiler will reference them by their own
  226. // index when it comes to running the statement that
  227. // requires the literal type.
  228. if let Arg::Lit(v) = arg {
  229. // Match this literal type to a VarType for
  230. // type checking.
  231. let var_type = v.typ.to_vartype();
  232. if var_type != arg_types[idx] {
  233. self.error.abort(
  234. &format!(
  235. "Incorrect argument type. Expected `{:?}`, got `{:?}`.",
  236. arg_types[idx], var_type
  237. ),
  238. v.line,
  239. v.column,
  240. );
  241. }
  242. self.literals.push(v.clone());
  243. rhs.push(Arg::Lit(v.clone()));
  244. continue
  245. }
  246. if let Arg::Var(v) = arg {
  247. // Look up variable and check if type is correct.
  248. if let Some(s_var) = self.lookup_var(&v.name) {
  249. let (var_type, _ln, _col) = match s_var {
  250. Var::Constant(c) => (c.typ, c.line, c.column),
  251. Var::Witness(c) => (c.typ, c.line, c.column),
  252. Var::Variable(c) => (c.typ, c.line, c.column),
  253. };
  254. // FIXME: Better array handling
  255. if arg_types[0] == VarType::BaseArray {
  256. if var_type != VarType::Base {
  257. self.error.abort(
  258. &format!(
  259. "Incorrect argument type. Expected `{:?}`, got `{:?}`.",
  260. VarType::Base,
  261. var_type
  262. ),
  263. v.line,
  264. v.column,
  265. );
  266. }
  267. } else if arg_types[0] == VarType::ScalarArray {
  268. if var_type != VarType::Scalar {
  269. self.error.abort(
  270. &format!(
  271. "Incorrect argument type. Expected `{:?}`, got `{:?}`.",
  272. VarType::Scalar,
  273. var_type
  274. ),
  275. v.line,
  276. v.column,
  277. );
  278. }
  279. } else if var_type != arg_types[idx] {
  280. self.error.abort(
  281. &format!(
  282. "Incorrect argument type. Expected `{:?}`, got `{:?}`.",
  283. arg_types[idx], var_type
  284. ),
  285. v.line,
  286. v.column,
  287. );
  288. }
  289. // Replace Dummy type with correct type.
  290. let mut v_new = v.clone();
  291. v_new.typ = var_type;
  292. rhs.push(Arg::Var(v_new));
  293. continue
  294. }
  295. self.error.abort(
  296. &format!("Unknown variable reference `{}`.", v.name),
  297. v.line,
  298. v.column,
  299. );
  300. }
  301. } // <-- statement.rhs.iter().enumerate()
  302. // We now type-checked and assigned types to the statement rhs,
  303. // so now we apply it to the statement.
  304. stmt.rhs = rhs;
  305. // In case this statement is an assignment, we will push its
  306. // result on the stack.
  307. if statement.typ == StatementType::Assign {
  308. let mut var = statement.lhs.clone().unwrap();
  309. var.typ = return_types[0];
  310. stmt.lhs = Some(var.clone());
  311. stack.push(var.clone());
  312. self.stack = stack.clone();
  313. }
  314. //println!("{:#?}", stmt);
  315. statements.push(stmt);
  316. } // <-- for statement in &self.statements
  317. // Here we replace the self.statements and self.stack with what we
  318. // built so far. These can be used later on by the compiler after
  319. // this function is finished.
  320. self.statements = statements;
  321. self.stack = stack;
  322. //println!("=================STATEMENTS===============\n{:#?}", self.statements);
  323. //println!("===================STACK==================\n{:#?}", self.stack);
  324. //println!("==================LITERALS================\n{:#?}", self.literals);
  325. }
  326. fn lookup_var(&self, name: &str) -> Option<Var> {
  327. if let Some(r) = self.lookup_constant(name) {
  328. return Some(Var::Constant(r))
  329. }
  330. if let Some(r) = self.lookup_witness(name) {
  331. return Some(Var::Witness(r))
  332. }
  333. if let Some(r) = self.lookup_stack(name) {
  334. return Some(Var::Variable(r))
  335. }
  336. None
  337. }
  338. fn lookup_constant(&self, name: &str) -> Option<Constant> {
  339. for i in &self.constants {
  340. if i.name == name {
  341. return Some(i.clone())
  342. }
  343. }
  344. None
  345. }
  346. fn lookup_witness(&self, name: &str) -> Option<Witness> {
  347. for i in &self.witnesses {
  348. if i.name == name {
  349. return Some(i.clone())
  350. }
  351. }
  352. None
  353. }
  354. fn lookup_stack(&self, name: &str) -> Option<Variable> {
  355. for i in &self.stack {
  356. if i.name == name {
  357. return Some(i.clone())
  358. }
  359. }
  360. None
  361. }
  362. pub fn analyze_semantic(&mut self) {
  363. let mut stack = vec![];
  364. println!("Loading constants...\n-----");
  365. for i in &self.constants {
  366. println!("Adding `{}` to stack", i.name);
  367. stack.push(&i.name);
  368. Analyzer::pause();
  369. }
  370. println!("Stack:\n{:#?}\n-----", stack);
  371. println!("Loading witnesses...\n-----");
  372. for i in &self.witnesses {
  373. println!("Adding `{}` to stack", i.name);
  374. stack.push(&i.name);
  375. Analyzer::pause();
  376. }
  377. println!("Stack:\n{:#?}\n-----", stack);
  378. println!("Loading circuit...");
  379. for i in &self.statements {
  380. let mut argnames = vec![];
  381. for arg in &i.rhs {
  382. if let Arg::Var(arg) = arg {
  383. argnames.push(arg.name.clone());
  384. } else if let Arg::Lit(lit) = arg {
  385. argnames.push(lit.name.clone());
  386. } else {
  387. unreachable!()
  388. }
  389. }
  390. println!("Executing: {:?}({:?})", i.opcode, argnames);
  391. Analyzer::pause();
  392. for arg in &i.rhs {
  393. if let Arg::Var(arg) = arg {
  394. print!("Looking up `{}` on the stack... ", arg.name);
  395. if let Some(index) = stack.iter().position(|&r| r == &arg.name) {
  396. println!("Found at stack index {}", index);
  397. } else {
  398. self.error.abort(
  399. &format!("Could not find `{}` on the stack", arg.name),
  400. arg.line,
  401. arg.column,
  402. );
  403. }
  404. } else if let Arg::Lit(lit) = arg {
  405. println!("Using literal `{}`", lit.name);
  406. } else {
  407. println!("{:#?}", arg);
  408. unreachable!();
  409. }
  410. Analyzer::pause();
  411. }
  412. match i.typ {
  413. StatementType::Assign => {
  414. println!("Pushing result as `{}` to stack", &i.lhs.as_ref().unwrap().name);
  415. stack.push(&i.lhs.as_ref().unwrap().name);
  416. println!("Stack:\n{:#?}\n-----", stack);
  417. }
  418. StatementType::Call => {
  419. println!("-----");
  420. }
  421. _ => unreachable!(),
  422. }
  423. }
  424. }
  425. fn pause() {
  426. let msg = b"[Press Enter to continue]\r";
  427. let mut stdout = stdout();
  428. let _ = stdout.write(msg).unwrap();
  429. stdout.flush().unwrap();
  430. let _ = stdin().read(&mut [0]).unwrap();
  431. write!(stdout, "{}{}\r", termion::cursor::Up(1), termion::clear::CurrentLine).unwrap();
  432. }
  433. }