5 use std::time::{SystemTime, UNIX_EPOCH};
7 extern crate rustyline;
8 use rustyline::error::ReadlineError;
11 use types::{MalVal,MalArgs,MalRet,error,func,hash_map,_assoc,_dissoc,atom};
12 use types::MalVal::{Nil,Bool,Int,Str,Sym,List,Vector,Hash,Func,MalFunc,Atom};
13 use types::MalErr::{ErrMalVal};
17 macro_rules! fn_t_int_int {
18 ($ret:ident, $fn:expr) => {{
20 match (a[0].clone(), a[1].clone()) {
21 (Int(a0), Int(a1)) => Ok($ret($fn(a0, a1))),
22 _ => error("expecting (int,int) args"),
28 macro_rules! fn_is_type {
30 |a:MalArgs| { Ok(Bool(match a[0] { $($ps => true,)* _ => false})) }
32 ($p:pat if $e:expr) => {{
33 |a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, _ => false})) }
35 ($p:pat if $e:expr,$($ps:pat),*) => {{
36 |a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, $($ps => true,)* _ => false})) }
45 _ => error("expecting (str) arg"),
51 fn symbol(a: MalArgs) -> MalRet {
53 Str(ref s) => Ok(Sym(s.to_string())),
54 _ => error("illegal symbol call")
58 fn readline(a: MalArgs) -> MalRet {
60 static ref RL: Mutex<Editor<()>> = Mutex::new(Editor::<()>::new());
62 //let mut rl = Editor::<()>::new();
66 //match rl.readline(p) {
67 match RL.lock().unwrap().readline(p) {
68 Ok(line) => Ok(Str(line)),
69 Err(ReadlineError::Eof) => Ok(Nil),
70 Err(e) => error(&format!("{:?}", e))
73 _ => error("readline: prompt is not Str"),
77 fn slurp(f: String) -> MalRet {
78 let mut s = String::new();
79 match File::open(f).and_then(|mut f| f.read_to_string(&mut s)) {
81 Err(e) => error(&e.to_string()),
85 fn time_ms(_a: MalArgs) -> MalRet {
86 let ms_e = match SystemTime::now().duration_since(UNIX_EPOCH) {
88 Err(e) => return error(&format!("{:?}", e)),
90 Ok(Int(ms_e.as_secs() as i64 * 1000 +
91 ms_e.subsec_nanos() as i64 / 1_000_000))
94 fn get(a: MalArgs) -> MalRet {
95 match (a[0].clone(), a[1].clone()) {
97 (Hash(ref hm,_), Str(ref s)) => {
99 Some(mv) => Ok(mv.clone()),
103 _ => error("illegal get args")
107 fn assoc(a: MalArgs) -> MalRet {
109 Hash(ref hm,_) => _assoc((**hm).clone(), a[1..].to_vec()),
110 _ => error("assoc on non-Hash Map")
114 fn dissoc(a: MalArgs) -> MalRet {
116 Hash(ref hm,_) => _dissoc((**hm).clone(), a[1..].to_vec()),
117 _ => error("dissoc on non-Hash Map")
121 fn contains_q(a: MalArgs) -> MalRet {
122 match (a[0].clone(), a[1].clone()) {
123 (Hash(ref hm,_), Str(ref s)) => {
124 Ok(Bool(hm.contains_key(s)))
126 _ => error("illegal get args")
130 fn keys(a: MalArgs) -> MalRet {
133 Ok(list!(hm.keys().map(|k|{Str(k.to_string())}).collect()))
135 _ => error("keys requires Hash Map")
139 fn vals(a: MalArgs) -> MalRet {
142 Ok(list!(hm.values().map(|v|{v.clone()}).collect()))
144 _ => error("keys requires Hash Map")
148 fn cons(a: MalArgs) -> MalRet {
150 List(v,_) | Vector(v,_) => {
151 let mut new_v = vec![a[0].clone()];
152 new_v.extend_from_slice(&v);
153 Ok(list!(new_v.to_vec()))
155 _ => error("cons expects seq as second arg"),
159 fn concat(a: MalArgs) -> MalRet {
160 let mut new_v = vec![];
161 for seq in a.iter() {
163 List(v,_) | Vector(v,_) => new_v.extend_from_slice(v),
164 _ => return error("non-seq passed to concat"),
167 Ok(list!(new_v.to_vec()))
170 fn nth(a: MalArgs) -> MalRet {
171 match (a[0].clone(), a[1].clone()) {
172 (List(seq,_), Int(idx)) | (Vector(seq,_), Int(idx)) => {
173 if seq.len() <= idx as usize {
174 return error("nth: index out of range");
176 Ok(seq[idx as usize].clone())
178 _ => error("invalid args to nth"),
182 fn first(a: MalArgs) -> MalRet {
184 List(ref seq,_) | Vector(ref seq,_) if seq.len() == 0 => Ok(Nil),
185 List(ref seq,_) | Vector(ref seq,_) => Ok(seq[0].clone()),
187 _ => error("invalid args to first"),
191 fn rest(a: MalArgs) -> MalRet {
193 List(ref seq,_) | Vector(ref seq,_) => {
195 Ok(list!(seq[1..].to_vec()))
201 _ => error("invalid args to first"),
205 fn apply(a: MalArgs) -> MalRet {
207 List(ref v,_) | Vector(ref v,_) => {
209 let mut fargs = a[1..a.len()-1].to_vec();
210 fargs.extend_from_slice(&v);
213 _ => error("apply called with non-seq"),
217 fn map(a: MalArgs) -> MalRet {
219 List(ref v,_) | Vector(ref v,_) => {
220 let mut res = vec![];
222 res.push(a[0].apply(vec![mv.clone()])?)
226 _ => error("map called with non-seq"),
230 fn conj(a: MalArgs) -> MalRet {
233 let sl = a[1..].iter().rev().map(|a|{a.clone()}).collect::<Vec<MalVal>>();
234 Ok(list!([&sl[..],v].concat()))
236 Vector(ref v,_) => Ok(vector!([v,&a[1..]].concat())),
237 _ => error("conj: called with non-seq"),
241 fn seq(a: MalArgs) -> MalRet {
243 List(ref v,_) | Vector(ref v,_) if v.len() == 0 => Ok(Nil),
244 List(ref v,_) | Vector(ref v,_) => Ok(list!(v.to_vec())),
245 Str(ref s) if s.len() == 0 => Ok(Nil),
246 Str(ref s) if !a[0].keyword_q() => {
247 Ok(list!(s.chars().map(|c|{Str(c.to_string())}).collect()))
250 _ => error("seq: called with non-seq"),
254 pub fn ns() -> Vec<(&'static str, MalVal)> {
256 ("=", func(|a|{Ok(Bool(a[0] == a[1]))})),
257 ("throw", func(|a|{Err(ErrMalVal(a[0].clone()))})),
259 ("nil?", func(fn_is_type!(Nil))),
260 ("true?", func(fn_is_type!(Bool(true)))),
261 ("false?", func(fn_is_type!(Bool(false)))),
262 ("symbol", func(symbol)),
263 ("symbol?", func(fn_is_type!(Sym(_)))),
264 ("string?", func(fn_is_type!(Str(ref s) if !s.starts_with("\u{29e}")))),
265 ("keyword", func(|a|{a[0].keyword()})),
266 ("keyword?", func(fn_is_type!(Str(ref s) if s.starts_with("\u{29e}")))),
267 ("number?", func(fn_is_type!(Int(_)))),
268 ("fn?", func(fn_is_type!(MalFunc{is_macro,..} if !is_macro,Func(_,_)))),
269 ("macro?", func(fn_is_type!(MalFunc{is_macro,..} if is_macro))),
271 ("pr-str", func(|a|Ok(Str(pr_seq(&a, true, "", "", " "))))),
272 ("str", func(|a|Ok(Str(pr_seq(&a, false, "", "", ""))))),
273 ("prn", func(|a|{println!("{}", pr_seq(&a, true, "", "", " ")); Ok(Nil)})),
274 ("println", func(|a|{println!("{}", pr_seq(&a, false, "", "", " ")); Ok(Nil)})),
275 ("read-string", func(fn_str!(|s|{read_str(s)}))),
276 ("readline", func(readline)),
277 ("slurp", func(fn_str!(|f|{slurp(f)}))),
279 ("<", func(fn_t_int_int!(Bool,|i,j|{i<j}))),
280 ("<=", func(fn_t_int_int!(Bool,|i,j|{i<=j}))),
281 (">", func(fn_t_int_int!(Bool,|i,j|{i>j}))),
282 (">=", func(fn_t_int_int!(Bool,|i,j|{i>=j}))),
283 ("+", func(fn_t_int_int!(Int,|i,j|{i+j}))),
284 ("-", func(fn_t_int_int!(Int,|i,j|{i-j}))),
285 ("*", func(fn_t_int_int!(Int,|i,j|{i*j}))),
286 ("/", func(fn_t_int_int!(Int,|i,j|{i/j}))),
287 ("time-ms", func(time_ms)),
289 ("sequential?", func(fn_is_type!(List(_,_),Vector(_,_)))),
290 ("list", func(|a|{Ok(list!(a))})),
291 ("list?", func(fn_is_type!(List(_,_)))),
292 ("vector", func(|a|{Ok(vector!(a))})),
293 ("vector?", func(fn_is_type!(Vector(_,_)))),
294 ("hash-map", func(|a|{hash_map(a)})),
295 ("map?", func(fn_is_type!(Hash(_,_)))),
296 ("assoc", func(assoc)),
297 ("dissoc", func(dissoc)),
299 ("contains?", func(contains_q)),
300 ("keys", func(keys)),
301 ("vals", func(vals)),
303 ("cons", func(cons)),
304 ("concat", func(concat)),
305 ("empty?", func(|a|{a[0].empty_q()})),
307 ("first", func(first)),
308 ("rest", func(rest)),
309 ("count", func(|a|{a[0].count()})),
310 ("apply", func(apply)),
313 ("conj", func(conj)),
316 ("meta", func(|a|{a[0].get_meta()})),
317 ("with-meta", func(|a|{a[0].clone().with_meta(&a[1])})),
318 ("atom", func(|a|{Ok(atom(&a[0]))})),
319 ("atom?", func(fn_is_type!(Atom(_)))),
320 ("deref", func(|a|{a[0].deref()})),
321 ("reset!", func(|a|{a[0].reset_bang(&a[1])})),
322 ("swap!", func(|a|{a[0].swap_bang(&a[1..].to_vec())})),
326 // vim: ts=2:sw=2:expandtab