5 use std::time::{SystemTime, UNIX_EPOCH};
7 extern crate rustyline;
8 use rustyline::error::ReadlineError;
11 use crate::printer::pr_seq;
12 use crate::reader::read_str;
13 use crate::types::MalErr::ErrMalVal;
14 use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector};
15 use crate::types::{MalArgs, MalRet, MalVal, _assoc, _dissoc, atom, error, func, hash_map};
17 macro_rules! fn_t_int_int {
18 ($ret:ident, $fn:expr) => {{
19 |a: MalArgs| match (a[0].clone(), a[1].clone()) {
20 (Int(a0), Int(a1)) => Ok($ret($fn(a0, a1))),
21 _ => error("expecting (int,int) args"),
26 macro_rules! fn_is_type {
28 |a:MalArgs| { Ok(Bool(match a[0] { $($ps => true,)* _ => false})) }
30 ($p:pat if $e:expr) => {{
31 |a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, _ => false})) }
33 ($p:pat if $e:expr,$($ps:pat),*) => {{
34 |a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, $($ps => true,)* _ => false})) }
40 |a: MalArgs| match a[0].clone() {
42 _ => error("expecting (str) arg"),
47 fn symbol(a: MalArgs) -> MalRet {
49 Str(ref s) => Ok(Sym(s.to_string())),
50 _ => error("illegal symbol call"),
54 fn readline(a: MalArgs) -> MalRet {
56 static ref RL: Mutex<Editor<()>> = Mutex::new(Editor::<()>::new());
58 //let mut rl = Editor::<()>::new();
62 //match rl.readline(p) {
63 match RL.lock().unwrap().readline(p) {
65 // Remove any trailing \n or \r\n
66 if line.ends_with('\n') {
68 if line.ends_with('\r') {
74 Err(ReadlineError::Eof) => Ok(Nil),
75 Err(e) => error(&format!("{:?}", e)),
78 _ => error("readline: prompt is not Str"),
82 fn slurp(f: String) -> MalRet {
83 let mut s = String::new();
84 match File::open(f).and_then(|mut f| f.read_to_string(&mut s)) {
86 Err(e) => error(&e.to_string()),
90 fn time_ms(_a: MalArgs) -> MalRet {
91 let ms_e = match SystemTime::now().duration_since(UNIX_EPOCH) {
93 Err(e) => return error(&format!("{:?}", e)),
96 ms_e.as_secs() as i64 * 1000 + ms_e.subsec_nanos() as i64 / 1_000_000
100 fn get(a: MalArgs) -> MalRet {
101 match (a[0].clone(), a[1].clone()) {
103 (Hash(ref hm, _), Str(ref s)) => match hm.get(s) {
104 Some(mv) => Ok(mv.clone()),
107 _ => error("illegal get args"),
111 fn assoc(a: MalArgs) -> MalRet {
113 Hash(ref hm, _) => _assoc((**hm).clone(), a[1..].to_vec()),
114 _ => error("assoc on non-Hash Map"),
118 fn dissoc(a: MalArgs) -> MalRet {
120 Hash(ref hm, _) => _dissoc((**hm).clone(), a[1..].to_vec()),
121 _ => error("dissoc on non-Hash Map"),
125 fn contains_q(a: MalArgs) -> MalRet {
126 match (a[0].clone(), a[1].clone()) {
127 (Hash(ref hm, _), Str(ref s)) => Ok(Bool(hm.contains_key(s))),
128 _ => error("illegal get args"),
132 fn keys(a: MalArgs) -> MalRet {
134 Hash(ref hm, _) => Ok(list!(hm.keys().map(|k| { Str(k.to_string()) }).collect())),
135 _ => error("keys requires Hash Map"),
139 fn vals(a: MalArgs) -> MalRet {
141 Hash(ref hm, _) => Ok(list!(hm.values().map(|v| { v.clone() }).collect())),
142 _ => error("keys requires Hash Map"),
146 fn cons(a: MalArgs) -> MalRet {
148 List(v, _) | Vector(v, _) => {
149 let mut new_v = vec![a[0].clone()];
150 new_v.extend_from_slice(&v);
151 Ok(list!(new_v.to_vec()))
153 _ => error("cons expects seq as second arg"),
157 fn concat(a: MalArgs) -> MalRet {
158 let mut new_v = vec![];
159 for seq in a.iter() {
161 List(v, _) | Vector(v, _) => new_v.extend_from_slice(v),
162 _ => return error("non-seq passed to concat"),
165 Ok(list!(new_v.to_vec()))
168 fn nth(a: MalArgs) -> MalRet {
169 match (a[0].clone(), a[1].clone()) {
170 (List(seq, _), Int(idx)) | (Vector(seq, _), Int(idx)) => {
171 if seq.len() <= idx as usize {
172 return error("nth: index out of range");
174 Ok(seq[idx as usize].clone())
176 _ => error("invalid args to nth"),
180 fn first(a: MalArgs) -> MalRet {
182 List(ref seq, _) | Vector(ref seq, _) if seq.len() == 0 => Ok(Nil),
183 List(ref seq, _) | Vector(ref seq, _) => Ok(seq[0].clone()),
185 _ => error("invalid args to first"),
189 fn rest(a: MalArgs) -> MalRet {
191 List(ref seq, _) | Vector(ref seq, _) => {
193 Ok(list!(seq[1..].to_vec()))
199 _ => error("invalid args to first"),
203 fn apply(a: MalArgs) -> MalRet {
204 match a[a.len() - 1] {
205 List(ref v, _) | Vector(ref v, _) => {
207 let mut fargs = a[1..a.len() - 1].to_vec();
208 fargs.extend_from_slice(&v);
211 _ => error("apply called with non-seq"),
215 fn map(a: MalArgs) -> MalRet {
217 List(ref v, _) | Vector(ref v, _) => {
218 let mut res = vec![];
220 res.push(a[0].apply(vec![mv.clone()])?)
224 _ => error("map called with non-seq"),
228 fn conj(a: MalArgs) -> MalRet {
235 .collect::<Vec<MalVal>>();
236 Ok(list!([&sl[..], v].concat()))
238 Vector(ref v, _) => Ok(vector!([v, &a[1..]].concat())),
239 _ => error("conj: called with non-seq"),
243 fn seq(a: MalArgs) -> MalRet {
245 List(ref v, _) | Vector(ref v, _) if v.len() == 0 => Ok(Nil),
246 List(ref v, _) | Vector(ref v, _) => Ok(list!(v.to_vec())),
247 Str(ref s) if s.len() == 0 => Ok(Nil),
248 Str(ref s) if !a[0].keyword_q() => {
249 Ok(list!(s.chars().map(|c| { Str(c.to_string()) }).collect()))
252 _ => error("seq: called with non-seq"),
256 pub fn ns() -> Vec<(&'static str, MalVal)> {
258 ("=", func(|a| Ok(Bool(a[0] == a[1])))),
259 ("throw", func(|a| Err(ErrMalVal(a[0].clone())))),
260 ("nil?", func(fn_is_type!(Nil))),
261 ("true?", func(fn_is_type!(Bool(true)))),
262 ("false?", func(fn_is_type!(Bool(false)))),
263 ("symbol", func(symbol)),
264 ("symbol?", func(fn_is_type!(Sym(_)))),
267 func(fn_is_type!(Str(ref s) if !s.starts_with("\u{29e}"))),
269 ("keyword", func(|a| a[0].keyword())),
272 func(fn_is_type!(Str(ref s) if s.starts_with("\u{29e}"))),
274 ("number?", func(fn_is_type!(Int(_)))),
277 func(fn_is_type!(MalFunc{is_macro,..} if !is_macro,Func(_,_))),
281 func(fn_is_type!(MalFunc{is_macro,..} if is_macro)),
283 ("pr-str", func(|a| Ok(Str(pr_seq(&a, true, "", "", " "))))),
284 ("str", func(|a| Ok(Str(pr_seq(&a, false, "", "", ""))))),
288 println!("{}", pr_seq(&a, true, "", "", " "));
295 println!("{}", pr_seq(&a, false, "", "", " "));
299 ("read-string", func(fn_str!(|s| { read_str(s) }))),
300 ("readline", func(readline)),
301 ("slurp", func(fn_str!(|f| { slurp(f) }))),
302 ("<", func(fn_t_int_int!(Bool, |i, j| { i < j }))),
303 ("<=", func(fn_t_int_int!(Bool, |i, j| { i <= j }))),
304 (">", func(fn_t_int_int!(Bool, |i, j| { i > j }))),
305 (">=", func(fn_t_int_int!(Bool, |i, j| { i >= j }))),
306 ("+", func(fn_t_int_int!(Int, |i, j| { i + j }))),
307 ("-", func(fn_t_int_int!(Int, |i, j| { i - j }))),
308 ("*", func(fn_t_int_int!(Int, |i, j| { i * j }))),
309 ("/", func(fn_t_int_int!(Int, |i, j| { i / j }))),
310 ("time-ms", func(time_ms)),
311 ("sequential?", func(fn_is_type!(List(_, _), Vector(_, _)))),
312 ("list", func(|a| Ok(list!(a)))),
313 ("list?", func(fn_is_type!(List(_, _)))),
314 ("vector", func(|a| Ok(vector!(a)))),
315 ("vector?", func(fn_is_type!(Vector(_, _)))),
316 ("hash-map", func(|a| hash_map(a))),
317 ("map?", func(fn_is_type!(Hash(_, _)))),
318 ("assoc", func(assoc)),
319 ("dissoc", func(dissoc)),
321 ("contains?", func(contains_q)),
322 ("keys", func(keys)),
323 ("vals", func(vals)),
324 ("cons", func(cons)),
325 ("concat", func(concat)),
326 ("empty?", func(|a| a[0].empty_q())),
328 ("first", func(first)),
329 ("rest", func(rest)),
330 ("count", func(|a| a[0].count())),
331 ("apply", func(apply)),
333 ("conj", func(conj)),
335 ("meta", func(|a| a[0].get_meta())),
336 ("with-meta", func(|a| a[0].clone().with_meta(&a[1]))),
337 ("atom", func(|a| Ok(atom(&a[0])))),
338 ("atom?", func(fn_is_type!(Atom(_)))),
339 ("deref", func(|a| a[0].deref())),
340 ("reset!", func(|a| a[0].reset_bang(&a[1]))),
341 ("swap!", func(|a| a[0].swap_bang(&a[1..].to_vec()))),