1 // support precompiled regexes in reader.rs
4 extern crate regex_macros;
7 use std::collections::HashMap;
9 use types::{MalVal,MalRet,Int,Sym,List,Vector,Hash_Map,
10 _int,list,vector,hash_map,func};
11 use env::{Env,env_new,env_set,env_get};
19 fn read(str: String) -> MalRet {
24 fn eval_ast(ast: MalVal, env: Env) -> MalRet {
25 let ast2 = ast.clone();
29 env_get(env.clone(), sym.clone())
31 List(ref a) | Vector(ref a) => {
32 let mut ast_vec : Vec<MalVal> = vec![];
35 match eval(mv2, env.clone()) {
36 Ok(mv) => { ast_vec.push(mv); },
37 Err(e) => { return Err(e); },
40 Ok(match *ast { List(_) => list(ast_vec),
41 _ => vector(ast_vec) })
44 let mut new_hm: HashMap<String,MalVal> = HashMap::new();
45 for (key, value) in hm.iter() {
46 match eval(value.clone(), env.clone()) {
47 Ok(mv) => { new_hm.insert(key.to_string(), mv); },
48 Err(e) => return Err(e),
59 fn eval(ast: MalVal, env: Env) -> MalRet {
60 //println!("eval: {}, {}", ast, env.borrow());
61 //println!("eval: {}", ast);
62 let ast2 = ast.clone();
64 List(_) => (), // continue
65 _ => return eval_ast(ast2, env),
74 let ref a0 = *args[0];
77 match a0sym.as_slice() {
79 let a1 = (*args)[1].clone();
80 let a2 = (*args)[2].clone();
81 let res = eval(a2, env.clone());
86 env_set(&env.clone(), s.clone(), r.clone());
90 return Err("def! of non-symbol".to_string())
94 Err(e) => return Err(e),
98 let let_env = env_new(Some(env.clone()));
99 let a1 = (*args)[1].clone();
100 let a2 = (*args)[2].clone();
102 List(ref binds) | Vector(ref binds) => {
103 let mut it = binds.iter();
104 while it.len() >= 2 {
105 let b = it.next().unwrap();
106 let exp = it.next().unwrap();
109 match eval(exp.clone(), let_env.clone()) {
111 env_set(&let_env, bstr.clone(), r);
119 return Err("let* with non-symbol binding".to_string());
124 _ => return Err("let* with non-list bindings".to_string()),
126 return eval(a2, let_env.clone());
134 return match eval_ast(ast, env) {
139 let ref f = args.clone()[0];
140 f.apply(args.slice(1,args.len()).to_vec())
142 _ => Err("Invalid apply".to_string()),
147 _ => Err("Expected list".to_string()),
152 fn print(exp: MalVal) -> String {
156 fn rep(str: String, env: Env) -> Result<String,String> {
160 //println!("read: {}", ast);
161 match eval(ast, env) {
163 Ok(exp) => Ok(print(exp)),
169 fn int_op(f: |i:int,j:int|-> int, a:Vec<MalVal>) -> MalRet {
171 Int(a0) => match *a[1] {
172 Int(a1) => Ok(_int(f(a0,a1))),
173 _ => Err("second arg must be an int".to_string()),
175 _ => Err("first arg must be an int".to_string()),
178 fn add(a:Vec<MalVal>) -> MalRet { int_op(|i,j| { i+j }, a) }
179 fn sub(a:Vec<MalVal>) -> MalRet { int_op(|i,j| { i-j }, a) }
180 fn mul(a:Vec<MalVal>) -> MalRet { int_op(|i,j| { i*j }, a) }
181 fn div(a:Vec<MalVal>) -> MalRet { int_op(|i,j| { i/j }, a) }
184 let repl_env = env_new(None);
185 env_set(&repl_env, "+".to_string(), func(add));
186 env_set(&repl_env, "-".to_string(), func(sub));
187 env_set(&repl_env, "*".to_string(), func(mul));
188 env_set(&repl_env, "/".to_string(), func(div));
191 let line = readline::mal_readline("user> ");
192 match line { None => break, _ => () }
193 match rep(line.unwrap(), repl_env.clone()) {
194 Ok(str) => println!("{}", str),
195 Err(str) => println!("Error: {}", str),