diff options
| author | Joel Martin <github@martintribe.org> | 2014-10-27 23:20:22 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2015-01-06 21:59:01 -0600 |
| commit | 77b2da6cf337bbd85914619bfbccba69b6621a04 (patch) | |
| tree | afa9bcca8e965363962d585f312cb76eb14f8183 /rust/src/core.rs | |
| parent | bd3067230dcbd18fb1f0db7abb52c4ea1c2e227b (diff) | |
| download | mal-77b2da6cf337bbd85914619bfbccba69b6621a04.tar.gz mal-77b2da6cf337bbd85914619bfbccba69b6621a04.zip | |
rust: add conj, stepA. Self-hosting!
Diffstat (limited to 'rust/src/core.rs')
| -rw-r--r-- | rust/src/core.rs | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/rust/src/core.rs b/rust/src/core.rs index c1abaf6..e751f88 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -7,7 +7,7 @@ use std::io::File; use types::{MalVal,MalRet,err_val,err_str,err_string, Nil,Int,Strn,List,Vector,Hash_Map,Func,MalFunc,Atom, _nil,_true,_false,_int,string, - list,listm,vectorm,hash_mapm,func,funcm,malfuncd}; + list,vector,listm,vectorm,hash_mapm,func,funcm,malfuncd}; use types; use readline; use reader; @@ -209,7 +209,7 @@ pub fn keys(a:Vec<MalVal>) -> MalRet { Nil => return Ok(_nil()), _ => return err_str("contains? on non-hash map"), }; - if hm.len() == 0 { return Ok(_nil()); } + //if hm.len() == 0 { return Ok(_nil()); } let mut keys = vec![]; for k in hm.keys() { keys.push(string(k.to_string())); @@ -227,7 +227,7 @@ pub fn vals(a:Vec<MalVal>) -> MalRet { Nil => return Ok(_nil()), _ => return err_str("contains? on non-hash map"), }; - if hm.len() == 0 { return Ok(_nil()); } + //if hm.len() == 0 { return Ok(_nil()); } let mut vals = vec![]; for k in hm.values() { vals.push(k.clone()); @@ -382,6 +382,30 @@ pub fn map(a:Vec<MalVal>) -> MalRet { Ok(list(results)) } +pub fn conj(a:Vec<MalVal>) -> MalRet { + if a.len() < 2 { + return err_str("Wrong arity to conj call"); + } + let mut new_v:Vec<MalVal> = vec![]; + match *a[0].clone() { + List(ref l,_) => { + new_v.push_all(l.as_slice()); + for mv in a.iter().skip(1) { + new_v.insert(0,mv.clone()); + } + Ok(list(new_v)) + }, + Vector(ref l,_) => { + new_v.push_all(l.as_slice()); + for mv in a.iter().skip(1) { + new_v.push(mv.clone()); + } + Ok(vector(new_v)) + }, + _ => return err_str("conj called with non-sequence"), + } +} + // Metadata functions fn with_meta(a:Vec<MalVal>) -> MalRet { @@ -519,10 +543,12 @@ pub fn ns() -> HashMap<String,MalVal> { ns.insert("count".to_string(), func(count)); ns.insert("apply".to_string(), func(apply)); ns.insert("map".to_string(), func(map)); + ns.insert("conj".to_string(), func(conj)); ns.insert("with-meta".to_string(), func(with_meta)); ns.insert("meta".to_string(), func(meta)); ns.insert("atom".to_string(), func(types::atom)); + ns.insert("atom?".to_string(), func(types::atom_q)); ns.insert("deref".to_string(), func(deref)); ns.insert("reset!".to_string(), func(reset_bang)); ns.insert("swap!".to_string(), func(swap_bang)); |
