1 // support precompiled regexes in reader.rs
4 extern crate regex_macros;
7 use std::collections::HashMap;
9 use types::{MalVal,MalRet,MalFunc,Nil,False,Sym,List,Vector,Hash_Map,Func,
10 _nil,list,vector,hash_map,malfunc};
11 use env::{Env,env_new,env_bind,env_set,env_get};
20 fn read(str: String) -> MalRet {
25 fn eval_ast(ast: MalVal, env: Env) -> MalRet {
26 let ast2 = ast.clone();
30 env_get(env.clone(), sym.clone())
32 List(ref a) | Vector(ref a) => {
33 let mut ast_vec : Vec<MalVal> = vec![];
36 match eval(mv2, env.clone()) {
37 Ok(mv) => { ast_vec.push(mv); },
38 Err(e) => { return Err(e); },
41 Ok(match *ast { List(_) => list(ast_vec),
42 _ => vector(ast_vec) })
45 let mut new_hm: HashMap<String,MalVal> = HashMap::new();
46 for (key, value) in hm.iter() {
47 match eval(value.clone(), env.clone()) {
48 Ok(mv) => { new_hm.insert(key.to_string(), mv); },
49 Err(e) => return Err(e),
60 fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
63 //println!("eval: {}, {}", ast, env.borrow());
64 //println!("eval: {}", ast);
65 let ast2 = ast.clone();
67 List(_) => (), // continue
68 _ => return eval_ast(ast2, env),
72 let ast3 = ast2.clone();
78 let ref a0 = *args[0];
81 match a0sym.as_slice() {
83 let a1 = (*args)[1].clone();
84 let a2 = (*args)[2].clone();
85 let res = eval(a2, env.clone());
90 env_set(&env.clone(), s.clone(), r.clone());
94 return Err("def! of non-symbol".to_string())
98 Err(e) => return Err(e),
102 let let_env = env_new(Some(env.clone()));
103 let a1 = (*args)[1].clone();
104 let a2 = (*args)[2].clone();
106 List(ref binds) | Vector(ref binds) => {
107 let mut it = binds.iter();
108 while it.len() >= 2 {
109 let b = it.next().unwrap();
110 let exp = it.next().unwrap();
113 match eval(exp.clone(), let_env.clone()) {
115 env_set(&let_env, bstr.clone(), r);
123 return Err("let* with non-symbol binding".to_string());
128 _ => return Err("let* with non-list bindings".to_string()),
131 env = let_env.clone();
135 let el = list(args.slice(1,args.len()-1).to_vec());
136 match eval_ast(el, env.clone()) {
137 Err(e) => return Err(e),
139 let ref last = args[args.len()-1];
146 let a1 = (*args)[1].clone();
147 let cond = eval(a1, env.clone());
148 if cond.is_err() { return cond; }
149 match *cond.unwrap() {
152 let a3 = (*args)[3].clone();
161 let a2 = (*args)[2].clone();
169 let a1 = (*args)[1].clone();
170 let a2 = (*args)[2].clone();
171 return Ok(malfunc(eval, a2, env.clone(), a1));
179 return match eval_ast(ast3, env.clone()) {
184 let args2 = args.clone();
186 Func(f) => f(args.slice(1,args.len()).to_vec()),
188 let mfc = mf.clone();
189 let alst = list(args.slice(1,args.len()).to_vec());
190 let new_env = env_new(Some(mfc.env.clone()));
191 match env_bind(&new_env, mfc.params, alst) {
200 _ => Err("attempt to call non-function".to_string()),
203 _ => Err("Invalid apply".to_string()),
208 _ => return Err("Expected list".to_string()),
215 fn print(exp: MalVal) -> String {
219 fn rep(str: String, env: Env) -> Result<String,String> {
223 //println!("read: {}", ast);
224 match eval(ast, env) {
226 Ok(exp) => Ok(print(exp)),
233 // core.rs: defined using rust
234 let repl_env = env_new(None);
235 for (k, v) in core::ns().into_iter() { env_set(&repl_env, k, v); }
237 // core.mal: defined using the language itself
238 let _ = rep("(def! not (fn* (a) (if a false true)))".to_string(),
242 let line = readline::mal_readline("user> ");
243 match line { None => break, _ => () }
244 match rep(line.unwrap(), repl_env.clone()) {
245 Ok(str) => println!("{}", str),
246 Err(str) => println!("Error: {}", str),