lisp.rs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. #![allow(non_snake_case)]
  2. use crate::types::LispCircuit;
  3. use bellman::groth16::PreparedVerifyingKey;
  4. use sapvi::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof};
  5. use simplelog::*;
  6. use bellman::groth16;
  7. use bls12_381::Bls12;
  8. use fnv::FnvHashMap;
  9. use itertools::Itertools;
  10. use rand::rngs::OsRng;
  11. use std::{borrow::{Borrow, BorrowMut}, fs};
  12. use std::fs::File;
  13. use std::rc::Rc;
  14. use std::time::Instant;
  15. use types::EnforceAllocation;
  16. #[macro_use]
  17. extern crate clap;
  18. #[macro_use]
  19. extern crate lazy_static;
  20. extern crate fnv;
  21. extern crate itertools;
  22. extern crate regex;
  23. #[macro_use]
  24. mod types;
  25. use crate::types::MalErr::{ErrMalVal, ErrString};
  26. use crate::types::MalVal::{Bool, Enforce, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector};
  27. use crate::types::VerifyKeyParams;
  28. use crate::types::{error, format_error, MalArgs, MalErr, MalRet, MalVal};
  29. mod env;
  30. mod printer;
  31. mod reader;
  32. use crate::env::{env_bind, env_find, env_get, env_new, env_set, env_sets, Env};
  33. #[macro_use]
  34. mod core;
  35. // read
  36. fn read(str: &str) -> MalRet {
  37. reader::read_str(str.to_string())
  38. }
  39. // eval
  40. fn qq_iter(elts: &MalArgs) -> MalVal {
  41. let mut acc = list![];
  42. for elt in elts.iter().rev() {
  43. if let List(v, _) = elt {
  44. if v.len() == 2 {
  45. if let Sym(ref s) = v[0] {
  46. if s == "splice-unquote" {
  47. acc = list![Sym("concat".to_string()), v[1].clone(), acc];
  48. continue;
  49. }
  50. }
  51. }
  52. }
  53. acc = list![Sym("cons".to_string()), quasiquote(&elt), acc];
  54. }
  55. return acc;
  56. }
  57. fn quasiquote(ast: &MalVal) -> MalVal {
  58. match ast {
  59. List(v, _) => {
  60. if v.len() == 2 {
  61. if let Sym(ref s) = v[0] {
  62. if s == "unquote" {
  63. return v[1].clone();
  64. }
  65. }
  66. }
  67. return qq_iter(&v);
  68. }
  69. Vector(v, _) => return list![Sym("vec".to_string()), qq_iter(&v)],
  70. Hash(_, _) | Sym(_) => return list![Sym("quote".to_string()), ast.clone()],
  71. _ => ast.clone(),
  72. }
  73. }
  74. fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
  75. match ast {
  76. List(v, _) => match v[0] {
  77. Sym(ref s) => match env_find(env, s) {
  78. Some(e) => match env_get(&e, &v[0]) {
  79. Ok(f @ MalFunc { is_macro: true, .. }) => Some((f, v[1..].to_vec())),
  80. _ => None,
  81. },
  82. _ => None,
  83. },
  84. _ => None,
  85. },
  86. _ => None,
  87. }
  88. }
  89. fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
  90. let mut was_expanded = false;
  91. while let Some((mf, args)) = is_macro_call(&ast, env) {
  92. // println!("macroexpand 1: {:?}", ast);
  93. ast = match mf.apply(args) {
  94. Err(e) => return (false, Err(e)),
  95. Ok(a) => a,
  96. };
  97. // println!("macroexpand 2: {:?}", ast);
  98. was_expanded = true;
  99. }
  100. (was_expanded, Ok(ast))
  101. }
  102. fn eval_ast(ast: &MalVal, env: &Env) -> MalRet {
  103. match ast {
  104. Sym(_) => Ok(env_get(&env, &ast)?),
  105. List(v, _) => {
  106. let mut lst: MalArgs = vec![];
  107. for a in v.iter() {
  108. lst.push(eval(a.clone(), env.clone())?)
  109. }
  110. Ok(list!(lst))
  111. }
  112. Vector(v, _) => {
  113. let mut lst: MalArgs = vec![];
  114. for a in v.iter() {
  115. lst.push(eval(a.clone(), env.clone())?)
  116. }
  117. Ok(vector!(lst))
  118. }
  119. Hash(hm, _) => {
  120. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  121. for (k, v) in hm.iter() {
  122. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  123. }
  124. Ok(Hash(Rc::new(new_hm), Rc::new(Nil)))
  125. }
  126. _ => Ok(ast.clone()),
  127. }
  128. }
  129. fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
  130. let ret: MalRet;
  131. 'tco: loop {
  132. ret = match ast.clone() {
  133. List(l, _) => {
  134. if l.len() == 0 {
  135. return Ok(ast);
  136. }
  137. match macroexpand(ast.clone(), &env) {
  138. (true, Ok(new_ast)) => {
  139. ast = new_ast;
  140. continue 'tco;
  141. }
  142. (_, Err(e)) => return Err(e),
  143. _ => (),
  144. }
  145. if l.len() == 0 {
  146. return Ok(ast);
  147. }
  148. let a0 = &l[0];
  149. match a0 {
  150. Sym(ref a0sym) if a0sym == "def!" => {
  151. env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
  152. }
  153. Sym(ref a0sym) if a0sym == "zk*" => {
  154. println!("zk* {:?}", l[1]);
  155. let (a1, a2) = (l[1].clone(), l[2].clone());
  156. match a1 {
  157. List(ref binds, _) | Vector(ref binds, _) => {
  158. for (b, e) in binds.iter().tuples() {
  159. match b {
  160. Sym(_) => {
  161. let _ = env_set(
  162. &env,
  163. b.clone(),
  164. eval(e.clone(), env.clone())?,
  165. );
  166. }
  167. _ => {
  168. return error("let* with non-Sym binding");
  169. }
  170. }
  171. }
  172. }
  173. _ => {
  174. return error("let* with non-List bindings");
  175. }
  176. };
  177. ast = a2;
  178. continue 'tco;
  179. }
  180. Sym(ref a0sym) if a0sym == "let*" => {
  181. env = env_new(Some(env.clone()));
  182. let (a1, a2) = (l[1].clone(), l[2].clone());
  183. match a1 {
  184. List(ref binds, _) | Vector(ref binds, _) => {
  185. for (b, e) in binds.iter().tuples() {
  186. match b {
  187. Sym(_) => {
  188. let _ = env_set(
  189. &env,
  190. b.clone(),
  191. eval(e.clone(), env.clone())?,
  192. );
  193. }
  194. _ => {
  195. return error("let* with non-Sym binding");
  196. }
  197. }
  198. }
  199. }
  200. _ => {
  201. return error("let* with non-List bindings");
  202. }
  203. };
  204. ast = a2;
  205. continue 'tco;
  206. }
  207. Sym(ref a0sym) if a0sym == "quote" => Ok(l[1].clone()),
  208. Sym(ref a0sym) if a0sym == "quasiquoteexpand" => Ok(quasiquote(&l[1])),
  209. Sym(ref a0sym) if a0sym == "quasiquote" => {
  210. ast = quasiquote(&l[1]);
  211. continue 'tco;
  212. }
  213. Sym(ref a0sym) if a0sym == "defmacro!" => {
  214. let (a1, a2) = (l[1].clone(), l[2].clone());
  215. let r = eval(a2, env.clone())?;
  216. match r {
  217. MalFunc {
  218. eval,
  219. ast,
  220. env,
  221. params,
  222. ..
  223. } => Ok(env_set(
  224. &env,
  225. a1.clone(),
  226. MalFunc {
  227. eval: eval,
  228. ast: ast.clone(),
  229. env: env.clone(),
  230. params: params.clone(),
  231. is_macro: true,
  232. meta: Rc::new(Nil),
  233. },
  234. )?),
  235. _ => error("set_macro on non-function"),
  236. }
  237. }
  238. Sym(ref a0sym) if a0sym == "macroexpand" => {
  239. match macroexpand(l[1].clone(), &env) {
  240. (_, Ok(new_ast)) => Ok(new_ast),
  241. (_, e) => return e,
  242. }
  243. }
  244. Sym(ref a0sym) if a0sym == "try*" => match eval(l[1].clone(), env.clone()) {
  245. Err(ref e) if l.len() >= 3 => {
  246. let exc = match e {
  247. ErrMalVal(mv) => mv.clone(),
  248. ErrString(s) => Str(s.to_string()),
  249. };
  250. match l[2].clone() {
  251. List(c, _) => {
  252. let catch_env = env_bind(
  253. Some(env.clone()),
  254. list!(vec![c[1].clone()]),
  255. vec![exc],
  256. )?;
  257. eval(c[2].clone(), catch_env)
  258. }
  259. _ => error("invalid catch block"),
  260. }
  261. }
  262. res => res,
  263. },
  264. Sym(ref a0sym) if a0sym == "do" => {
  265. match eval_ast(&list!(l[1..l.len() - 1].to_vec()), &env)? {
  266. List(_, _) => {
  267. ast = l.last().unwrap_or(&Nil).clone();
  268. continue 'tco;
  269. }
  270. _ => error("invalid do form"),
  271. }
  272. }
  273. Sym(ref a0sym) if a0sym == "if" => {
  274. let cond = eval(l[1].clone(), env.clone())?;
  275. match cond {
  276. Bool(false) | Nil if l.len() >= 4 => {
  277. ast = l[3].clone();
  278. continue 'tco;
  279. }
  280. Bool(false) | Nil => Ok(Nil),
  281. _ if l.len() >= 3 => {
  282. ast = l[2].clone();
  283. continue 'tco;
  284. }
  285. _ => Ok(Nil),
  286. }
  287. }
  288. Sym(ref a0sym) if a0sym == "fn*" => {
  289. let (a1, a2) = (l[1].clone(), l[2].clone());
  290. Ok(MalFunc {
  291. eval: eval,
  292. ast: Rc::new(a2),
  293. env: env,
  294. params: Rc::new(a1),
  295. is_macro: false,
  296. meta: Rc::new(Nil),
  297. })
  298. }
  299. Sym(ref a0sym) if a0sym == "eval" => {
  300. ast = eval(l[1].clone(), env.clone())?;
  301. while let Some(ref e) = env.clone().outer {
  302. env = e.clone();
  303. }
  304. continue 'tco;
  305. }
  306. Sym(ref a0sym) if a0sym == "setup" => {
  307. let a1 = l[1].clone();
  308. // todo
  309. ast = eval(a1.clone(), env.clone())?;
  310. // let _pvk = setup(a1.clone(), env.clone())?;
  311. continue 'tco;
  312. }
  313. Sym(ref a0sym) if a0sym == "prove" => {
  314. let a1 = l[1].clone();
  315. eval(a1.clone(), env.clone())?;
  316. prove(a1.clone(), env.clone())
  317. }
  318. Sym(ref a0sym) if a0sym == "alloc-const" => {
  319. let a1 = l[1].clone();
  320. let value = eval(l[2].clone(), env.clone())?;
  321. let result = eval(value.clone(), env.clone())?;
  322. let allocs = get_allocations(&env, "AllocationsConst");
  323. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  324. for (k, v) in allocs.iter() {
  325. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  326. }
  327. new_hm.insert(a1.pr_str(false), result.clone());
  328. env_set(
  329. &env,
  330. Sym("AllocationsConst".to_string()),
  331. Hash(Rc::new(new_hm), Rc::new(Nil)),
  332. )?;
  333. Ok(result.clone())
  334. }
  335. Sym(ref a0sym) if a0sym == "alloc-input" => {
  336. let a1 = l[1].clone();
  337. let value = eval(l[2].clone(), env.clone())?;
  338. let result = eval(value.clone(), env.clone())?;
  339. let allocs = get_allocations(&env, "AllocationsInput");
  340. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  341. for (k, v) in allocs.iter() {
  342. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  343. }
  344. new_hm.insert(a1.pr_str(false), result.clone());
  345. env_set(
  346. &env,
  347. Sym("AllocationsInput".to_string()),
  348. Hash(Rc::new(new_hm), Rc::new(Nil)),
  349. )?;
  350. Ok(result.clone())
  351. }
  352. Sym(ref a0sym) if a0sym == "alloc" => {
  353. let a1 = l[1].clone();
  354. let value = eval(l[2].clone(), env.clone())?;
  355. let result = eval(value.clone(), env.clone())?;
  356. println!("a1 {:?} ", a1);
  357. let allocs = get_allocations(&env, "Allocations");
  358. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  359. for (k, v) in allocs.iter() {
  360. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  361. }
  362. new_hm.insert(a1.pr_str(false), result.clone());
  363. // TODO change it
  364. if let Some(e) = &env.outer {
  365. env_set(
  366. &e,
  367. Sym("Allocations".to_string()),
  368. Hash(Rc::new(new_hm), Rc::new(Nil)),
  369. )?;
  370. } else {
  371. env_set(
  372. &env,
  373. Sym("Allocations".to_string()),
  374. Hash(Rc::new(new_hm), Rc::new(Nil)),
  375. )?;
  376. }
  377. Ok(result.clone())
  378. }
  379. //Sym(ref a0sym) if a0sym == "verify" => {
  380. Sym(ref a0sym) if a0sym == "enforce" => {
  381. // here i'm considering that we always have tuple with only two elements
  382. // also it's important to keep in mind for the sake of brevity of this v0
  383. // we will not allow calculation or any lisp evaluations inside the enforce
  384. // it means that every symbol will be on allocations and we will do the
  385. // find/replace on the bellman circuit, it's nasty v0
  386. let mut left_vec = vec![];
  387. let mut right_vec = vec![];
  388. let mut out_vec = vec![];
  389. // todo extract a macro for this
  390. match l[1].clone() {
  391. List(v, _) | Vector(v, _) => {
  392. if let List(_, _) = &v.to_vec()[0] {
  393. for ele in v.to_vec().iter() {
  394. if let List(ele_vec, _) = ele {
  395. left_vec.push((
  396. ele_vec[0].pr_str(false),
  397. ele_vec[1].pr_str(false),
  398. ));
  399. }
  400. }
  401. } else {
  402. left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  403. }
  404. }
  405. _ => {}
  406. };
  407. match l[2].clone() {
  408. List(v, _) | Vector(v, _) => {
  409. if let List(_, _) = &v.to_vec()[0] {
  410. for ele in v.to_vec().iter() {
  411. if let List(ele_vec, _) = ele {
  412. right_vec.push((
  413. ele_vec[0].pr_str(false),
  414. ele_vec[1].pr_str(false),
  415. ));
  416. }
  417. }
  418. } else {
  419. right_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  420. }
  421. }
  422. _ => {}
  423. };
  424. match l[3].clone() {
  425. List(v, _) | Vector(v, _) => {
  426. if let List(_, _) = &v.to_vec()[0] {
  427. for ele in v.to_vec().iter() {
  428. if let List(ele_vec, _) = ele {
  429. out_vec.push((
  430. ele_vec[0].pr_str(false),
  431. ele_vec[1].pr_str(false),
  432. ));
  433. }
  434. }
  435. } else {
  436. out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  437. }
  438. }
  439. _ => {}
  440. };
  441. let enforce_vec = get_enforce_allocs(&env);
  442. let enforce = EnforceAllocation {
  443. idx: enforce_vec.len() + 1,
  444. left: left_vec,
  445. right: right_vec,
  446. output: out_vec,
  447. };
  448. let mut new_vec: Vec<EnforceAllocation> = vec![enforce];
  449. for value in enforce_vec.iter() {
  450. new_vec.push(value.clone());
  451. }
  452. // TODO change it
  453. if let Some(e) = &env.outer {
  454. env_set(
  455. &e,
  456. Sym("AllocationsEnforce".to_string()),
  457. vector![vec![Enforce(Rc::new(new_vec.clone()))]],
  458. )?;
  459. } else {
  460. env_set(
  461. &env,
  462. Sym("AllocationsEnforce".to_string()),
  463. vector![vec![Enforce(Rc::new(new_vec.clone()))]],
  464. )?;
  465. }
  466. println!("allocs here {:?}", get_allocations_nested(&env, "Allocations"));
  467. println!("enforce here {:?}", get_enforce_allocs_nested(&env));
  468. Ok(MalVal::Nil)
  469. }
  470. _ => match eval_ast(&ast, &env)? {
  471. List(ref el, _) => {
  472. let ref f = el[0].clone();
  473. let args = el[1..].to_vec();
  474. match f {
  475. Func(_, _) => f.apply(args),
  476. MalFunc {
  477. ast: mast,
  478. env: menv,
  479. params,
  480. ..
  481. } => {
  482. let a = &**mast;
  483. let p = &**params;
  484. env = env_bind(Some(menv.clone()), p.clone(), args)?;
  485. ast = a.clone();
  486. continue 'tco;
  487. }
  488. _ => {
  489. println!("{:?}", args);
  490. Ok(vector![el.to_vec()])
  491. //error("call non-function")
  492. }
  493. }
  494. }
  495. _ => error("expected a list"),
  496. },
  497. }
  498. }
  499. _ => eval_ast(&ast, &env),
  500. };
  501. break;
  502. } // end 'tco loop
  503. ret
  504. }
  505. pub fn get_enforce_allocs(env: &Env) -> Vec<EnforceAllocation> {
  506. if let Some(e) = &env.outer {
  507. get_enforce_allocs_nested(&e)
  508. } else {
  509. get_enforce_allocs_nested(&env)
  510. }
  511. }
  512. pub fn get_enforce_allocs_nested(env: &Env) -> Vec<EnforceAllocation> {
  513. match env_find(env, "AllocationsEnforce") {
  514. Some(e) => match env_get(&e, &Sym("AllocationsEnforce".to_string())) {
  515. Ok(f) => {
  516. if let Vector(val, _) = f {
  517. if let Enforce(ret) = &val[0] {
  518. ret.to_vec()
  519. } else {
  520. vec![]
  521. }
  522. } else {
  523. vec![]
  524. }
  525. }
  526. _ => vec![],
  527. },
  528. _ => vec![],
  529. }
  530. }
  531. pub fn get_allocations(env: &Env, key: &str) -> Rc<FnvHashMap<String, MalVal>> {
  532. if let Some(e) = &env.outer {
  533. get_allocations_nested(&e, key)
  534. } else {
  535. get_allocations_nested(&env, key)
  536. }
  537. }
  538. pub fn get_allocations_nested(env: &Env, key: &str) -> Rc<FnvHashMap<String, MalVal>> {
  539. let alloc_hm: Rc<FnvHashMap<String, MalVal>> = Rc::new(FnvHashMap::default());
  540. match env_find(env, key) {
  541. Some(e) => match env_get(&e, &Sym(key.to_string())) {
  542. Ok(f) => {
  543. if let Hash(allocs, _) = f {
  544. allocs
  545. } else {
  546. alloc_hm
  547. }
  548. }
  549. _ => alloc_hm,
  550. },
  551. _ => alloc_hm,
  552. }
  553. }
  554. pub fn setup(_ast: MalVal, env: Env) -> Result<VerifyKeyParams, MalErr> {
  555. let start = Instant::now();
  556. let c = LispCircuit {
  557. params: FnvHashMap::default(),
  558. allocs: FnvHashMap::default(),
  559. alloc_inputs: FnvHashMap::default(),
  560. constraints: Vec::new(),
  561. };
  562. let random_parameters =
  563. groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap();
  564. let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
  565. println!("Setup: [{:?}]", start.elapsed());
  566. Ok(VerifyKeyParams {
  567. verifying_key: pvk,
  568. random_params: random_parameters,
  569. })
  570. }
  571. pub fn prove(_ast: MalVal, env: Env) -> MalRet {
  572. // let start = Instant::now();
  573. let allocs_input = get_allocations(&env, "AllocationsInput");
  574. let allocs = get_allocations(&env, "Allocations");
  575. let enforce_allocs = get_enforce_allocs(&env);
  576. let allocs_const = get_allocations(&env, "AllocationsConst");
  577. //setup
  578. let params = Some({
  579. let circuit = LispCircuit {
  580. params: allocs_const.as_ref().clone(),
  581. allocs: allocs.as_ref().clone(),
  582. alloc_inputs: allocs_input.as_ref().clone(),
  583. constraints: enforce_allocs.clone(),
  584. };
  585. groth16::generate_random_parameters::<Bls12, _, _>(circuit, &mut OsRng)?
  586. });
  587. let verifying_key = Some(groth16::prepare_verifying_key(&params.as_ref().unwrap().vk));
  588. // prove
  589. let circuit = LispCircuit {
  590. params: allocs_const.as_ref().clone(),
  591. allocs: allocs.as_ref().clone(),
  592. alloc_inputs: allocs_input.as_ref().clone(),
  593. constraints: enforce_allocs.clone(),
  594. };
  595. let proof = groth16::create_random_proof(circuit, params.as_ref().unwrap(), &mut OsRng)?;
  596. let mut vec_input = vec![];
  597. for (k, val) in allocs_input.iter() {
  598. match val {
  599. MalVal::Str(v) => {
  600. vec_input.push(bls12_381::Scalar::from_string(&v.to_string()));
  601. }
  602. MalVal::ZKScalar(v) => {
  603. vec_input.push(bls12_381::Scalar::from(*v));
  604. }
  605. _ => {}
  606. };
  607. }
  608. let result = groth16::verify_proof(verifying_key.as_ref().unwrap(), &proof, &vec_input);
  609. println!("vec public {:?}", vec_input);
  610. println!("result {:?}", result);
  611. Ok(MalVal::Nil)
  612. }
  613. pub fn verify(_ast: &MalVal) -> MalRet {
  614. let _public_input = vec![bls12_381::Scalar::from(27)];
  615. let start = Instant::now();
  616. println!("Verify: [{:?}]", start.elapsed());
  617. Ok(MalVal::Nil)
  618. }
  619. // print
  620. fn print(ast: &MalVal) -> String {
  621. ast.pr_str(true)
  622. }
  623. fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
  624. let ast = read(str)?;
  625. let exp = eval(ast, env.clone())?;
  626. Ok(print(&exp))
  627. }
  628. fn main() -> Result<(), ()> {
  629. let matches = clap_app!(zklisp =>
  630. (version: "0.1.0")
  631. (author: "mileschet <miles.chet@gmail.com>")
  632. (about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
  633. (@subcommand load =>
  634. (about: "Load the file into the interpreter")
  635. (@arg FILE: +required "Lisp Contract filename")
  636. )
  637. )
  638. .get_matches();
  639. // CombinedLogger::init(vec![TermLogger::new(
  640. // LevelFilter::Debug,
  641. // Config::default(),
  642. // TerminalMode::Mixed,
  643. // )
  644. // .unwrap()])
  645. // .unwrap();
  646. match matches.subcommand() {
  647. Some(("load", matches)) => {
  648. let file: String = matches.value_of("FILE").unwrap().parse().unwrap();
  649. repl_load(file)?;
  650. }
  651. _ => {
  652. eprintln!("error: Invalid subcommand invoked");
  653. std::process::exit(-1);
  654. }
  655. }
  656. Ok(())
  657. }
  658. fn repl_load(file: String) -> Result<(), ()> {
  659. let repl_env = env_new(None);
  660. for (k, v) in core::ns() {
  661. env_sets(&repl_env, k, v);
  662. }
  663. let _ = rep("(def! not (fn* (a) (if a false true)))", &repl_env);
  664. let _ = rep(
  665. "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
  666. &repl_env,
  667. );
  668. //let _ = rep("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", &repl_env);
  669. match rep(&format!("(load-file \"{}\")", file), &repl_env) {
  670. Ok(_) => std::process::exit(0),
  671. Err(e) => {
  672. println!("Error: {}", format_error(e));
  673. std::process::exit(1);
  674. }
  675. }
  676. }