3 use std::collections::HashMap;
5 use mal::types::{MalVal, MalRet, MalError, err_str};
6 use mal::types::{symbol, _nil, list, vector, hash_map, malfunc};
7 use mal::types::MalError::{ErrString, ErrMalVal};
8 use mal::types::MalType::{Nil, False, Sym, List, Vector, Hash_Map};
9 use mal::{readline, reader, core};
10 use mal::env::{env_set, env_get, env_new, Env};
14 fn read(str: String) -> MalRet {
19 fn eval_ast(ast: MalVal, env: Env) -> MalRet {
21 Sym(_) => env_get(&env, &ast),
22 List(ref a,_) | Vector(ref a,_) => {
23 let mut ast_vec : Vec<MalVal> = vec![];
26 ast_vec.push(try!(eval(mv2, env.clone())));
28 Ok(match *ast { List(_,_) => list(ast_vec),
29 _ => vector(ast_vec) })
31 Hash_Map(ref hm,_) => {
32 let mut new_hm: HashMap<String,MalVal> = HashMap::new();
33 for (key, value) in hm.iter() {
34 new_hm.insert(key.to_string(),
35 try!(eval(value.clone(), env.clone())));
43 fn eval(ast: MalVal, env: Env) -> MalRet {
44 //println!("eval: {}, {}", ast, env.borrow());
45 //println!("eval: {}", ast);
47 List(_,_) => (), // continue
48 _ => return eval_ast(ast, env),
53 List(_,_) => (), // continue
58 let (args, a0sym) = match *tmp {
61 return Ok(tmp.clone());
63 let ref a0 = *args[0];
65 Sym(ref a0sym) => (args, &a0sym[..]),
66 _ => (args, "__<fn*>__"),
69 _ => return err_str("Expected list"),
74 let a1 = (*args)[1].clone();
75 let a2 = (*args)[2].clone();
76 let r = try!(eval(a2, env.clone()));
79 env_set(&env.clone(), a1, r.clone());
82 _ => return err_str("def! of non-symbol"),
86 let let_env = env_new(Some(env.clone()));
87 let a1 = (*args)[1].clone();
88 let a2 = (*args)[2].clone();
90 List(ref binds,_) | Vector(ref binds,_) => {
91 let mut it = binds.iter();
93 let b = it.next().unwrap();
94 let exp = it.next().unwrap();
97 let r = try!(eval(exp.clone(), let_env.clone()));
98 env_set(&let_env, b.clone(), r);
100 _ => return err_str("let* with non-symbol binding"),
104 _ => return err_str("let* with non-list bindings"),
106 return eval(a2, let_env.clone());
109 let el = list(args[1..].to_vec());
110 match *try!(eval_ast(el, env.clone())) {
112 let ref last = lst[lst.len()-1];
113 return Ok(last.clone());
115 _ => return err_str("invalid do call"),
119 let a1 = (*args)[1].clone();
120 let c = try!(eval(a1, env.clone()));
124 let a3 = (*args)[3].clone();
125 return eval(a3, env.clone());
131 let a2 = (*args)[2].clone();
132 return eval(a2, env.clone());
137 let a1 = args[1].clone();
138 let a2 = args[2].clone();
139 return Ok(malfunc(eval, a2, env, a1, _nil()));
141 _ => { // function call
142 let el = try!(eval_ast(tmp.clone(), env.clone()));
143 let args = match *el {
144 List(ref args,_) => args,
145 _ => return err_str("Invalid apply"),
147 let ref f = args.clone()[0];
148 f.apply(args[1..].to_vec())
154 fn print(exp: MalVal) -> String {
158 fn rep(str: &str, env: Env) -> Result<String,MalError> {
159 let ast = try!(read(str.to_string()));
160 //println!("read: {}", ast);
161 let exp = try!(eval(ast, env));
166 // core.rs: defined using rust
167 let repl_env = env_new(None);
168 for (k, v) in core::ns().into_iter() {
169 env_set(&repl_env, symbol(&k), v);
172 // core.mal: defined using the language itself
173 let _ = rep("(def! not (fn* (a) (if a false true)))", repl_env.clone());
177 let line = readline::mal_readline("user> ");
178 match line { None => break, _ => () }
179 match rep(&line.unwrap(), repl_env.clone()) {
180 Ok(str) => println!("{}", str),
181 Err(ErrMalVal(_)) => (), // Blank line
182 Err(ErrString(s)) => println!("Error: {}", s),