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::MalType::{Nil, False, Sym, List, Vector, Hash_Map};
8 use mal::types::MalError::{ErrString, ErrMalVal};
9 use mal::{readline, reader, core};
10 use mal::env::{env_set, env_get, env_new, Env};
13 fn read(str: String) -> MalRet {
18 fn eval_ast(ast: MalVal, env: Env) -> MalRet {
19 let ast2 = ast.clone();
22 Sym(_) => env_get(&env, &ast),
23 List(ref a,_) | Vector(ref a,_) => {
24 let mut ast_vec : Vec<MalVal> = vec![];
27 match eval(mv2, env.clone()) {
28 Ok(mv) => { ast_vec.push(mv); },
29 Err(e) => { return Err(e); },
32 Ok(match *ast { List(_,_) => list(ast_vec),
33 _ => vector(ast_vec) })
35 Hash_Map(ref hm,_) => {
36 let mut new_hm: HashMap<String,MalVal> = HashMap::new();
37 for (key, value) in hm.iter() {
38 match eval(value.clone(), env.clone()) {
39 Ok(mv) => { new_hm.insert(key.to_string(), mv); },
40 Err(e) => return Err(e),
51 fn eval(ast: MalVal, env: Env) -> MalRet {
52 //println!("eval: {}, {}", ast, env.borrow());
53 //println!("eval: {}", ast);
54 let ast2 = ast.clone();
56 List(_,_) => (), // continue
57 _ => return eval_ast(ast2, env),
62 List(_,_) => (), // continue
66 let (args, a0sym) = match *ast2 {
71 let ref a0 = *args[0];
73 Sym(ref a0sym) => (args, &a0sym[..]),
74 _ => (args, "__<fn*>__"),
77 _ => return err_str("Expected list"),
82 let a1 = (*args)[1].clone();
83 let a2 = (*args)[2].clone();
84 let res = eval(a2, env.clone());
89 env_set(&env.clone(), a1.clone(), r.clone());
93 return err_str("def! of non-symbol")
97 Err(e) => return Err(e),
101 let let_env = env_new(Some(env.clone()));
102 let a1 = (*args)[1].clone();
103 let a2 = (*args)[2].clone();
105 List(ref binds,_) | Vector(ref binds,_) => {
106 let mut it = binds.iter();
107 while it.len() >= 2 {
108 let b = it.next().unwrap();
109 let exp = it.next().unwrap();
112 match eval(exp.clone(), let_env.clone()) {
114 env_set(&let_env, b.clone(), r);
122 return err_str("let* with non-symbol binding");
127 _ => return err_str("let* with non-list bindings"),
129 return eval(a2, let_env.clone());
132 let el = list(args[1..].to_vec());
133 return match eval_ast(el, env.clone()) {
134 Err(e) => return Err(e),
138 let ref last = lst[lst.len()-1];
139 return Ok(last.clone());
141 _ => return err_str("invalid do call"),
147 let a1 = (*args)[1].clone();
148 let cond = eval(a1, env.clone());
150 Err(e) => return Err(e),
154 let a3 = (*args)[3].clone();
155 return eval(a3, env.clone());
161 let a2 = (*args)[2].clone();
162 return eval(a2, env.clone());
168 let a1 = (*args)[1].clone();
169 let a2 = (*args)[2].clone();
170 return Ok(malfunc(eval, a2, env.clone(), a1, _nil()));
172 _ => { // function call
173 return match eval_ast(ast, env.clone()) {
176 let args = match *el {
177 List(ref args,_) => args,
178 _ => return err_str("Invalid apply"),
180 let ref f = args.clone()[0];
181 f.apply(args[1..].to_vec())
189 fn print(exp: MalVal) -> String {
193 fn rep(str: &str, env: Env) -> Result<String,MalError> {
194 match read(str.to_string()) {
197 //println!("read: {}", ast);
198 match eval(ast, env) {
200 Ok(exp) => Ok(print(exp)),
207 // core.rs: defined using rust
208 let repl_env = env_new(None);
209 for (k, v) in core::ns().into_iter() {
210 env_set(&repl_env, symbol(&k), v);
213 // core.mal: defined using the language itself
214 let _ = rep("(def! not (fn* (a) (if a false true)))", repl_env.clone());
217 let line = readline::mal_readline("user> ");
218 match line { None => break, _ => () }
219 match rep(&line.unwrap(), repl_env.clone()) {
220 Ok(str) => println!("{}", str),
221 Err(ErrMalVal(_)) => (), // Blank line
222 Err(ErrString(s)) => println!("Error: {}", s),