aboutsummaryrefslogtreecommitdiff
path: root/rust/src/types.rs
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-27 20:07:29 -0500
committerJoel Martin <github@martintribe.org>2014-10-27 20:07:29 -0500
commit5939404b0fb822fd29a483dc0d0a4d716cef206e (patch)
tree8196739b701df4fb7b61fed967eaca28f61d4b57 /rust/src/types.rs
parenta77e2b31de9d1c1f5767e6bff56062f8b3c71211 (diff)
downloadmal-5939404b0fb822fd29a483dc0d0a4d716cef206e.tar.gz
mal-5939404b0fb822fd29a483dc0d0a4d716cef206e.zip
rust: add vector and hash-map support.
Diffstat (limited to 'rust/src/types.rs')
-rw-r--r--rust/src/types.rs48
1 files changed, 37 insertions, 11 deletions
diff --git a/rust/src/types.rs b/rust/src/types.rs
index b8e1de0..e540ff1 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -1,12 +1,13 @@
#![allow(dead_code)]
use std::rc::Rc;
-use std::collections;
+use std::collections::HashMap;
use std::fmt;
use super::printer::{escape_str,pr_list};
use super::env::{Env,env_new,env_bind};
#[deriving(Clone)]
+#[allow(non_camel_case_types)]
pub enum MalType {
Nil,
True,
@@ -16,7 +17,7 @@ pub enum MalType {
Sym(String),
List(Vec<MalVal>),
Vector(Vec<MalVal>),
- HashMap(collections::HashMap<String, MalVal>),
+ Hash_Map(HashMap<String, MalVal>),
Func(fn(Vec<MalVal>) -> MalRet),
//Func(fn(&[MalVal]) -> MalRet),
//Func(|Vec<MalVal>|:'a -> MalRet),
@@ -59,19 +60,22 @@ impl MalType {
Vector(ref v) => {
res = pr_list(v, _r, "[", "]", " ")
},
- HashMap(ref v) => {
+ Hash_Map(ref v) => {
let mut first = true;
res.push_str("{");
for (key, value) in v.iter() {
if first { first = false; } else { res.push_str(" "); }
- res.push_str(key.as_slice());
+ if print_readably {
+ res.push_str(escape_str(key.as_slice()).as_slice())
+ } else {
+ res.push_str(key.as_slice())
+ }
res.push_str(" ");
res.push_str(value.pr_str(_r).as_slice());
}
res.push_str("}")
},
// TODO: better native function representation
- //Func(ref v) => {
Func(_) => {
res.push_str(format!("#<function ...>").as_slice())
},
@@ -79,10 +83,8 @@ impl MalType {
res.push_str(format!("(fn* {} {})", mf.params, mf.exp).as_slice())
},
/*
-
-// Atom(ref v) => v.fmt(f),
+ Atom(ref v) => v.fmt(f),
*/
- //_ => { res.push_str("#<unknown type>") },
};
res
}
@@ -115,8 +117,10 @@ impl PartialEq for MalType {
(&Strn(ref a), &Strn(ref b)) => a == b,
(&Sym(ref a), &Sym(ref b)) => a == b,
(&List(ref a), &List(ref b)) |
- (&Vector(ref a), &Vector(ref b)) => a == b,
- (&HashMap(ref a), &HashMap(ref b)) => a == b,
+ (&Vector(ref a), &Vector(ref b)) |
+ (&List(ref a), &Vector(ref b)) |
+ (&Vector(ref a), &List(ref b)) => a == b,
+ (&Hash_Map(ref a), &Hash_Map(ref b)) => a == b,
// TODO: fix this
(&Func(_), &Func(_)) => false,
(&MalFunc(_), &MalFunc(_)) => false,
@@ -142,7 +146,29 @@ pub fn symbol(strn: &str) -> MalVal { Rc::new(Sym(strn.to_string())) }
pub fn strn(strn: &str) -> MalVal { Rc::new(Strn(strn.to_string())) }
pub fn string(strn: String) -> MalVal { Rc::new(Strn(strn)) }
-pub fn list(lst: Vec<MalVal>) -> MalVal { Rc::new(List(lst)) }
+pub fn list(seq: Vec<MalVal>) -> MalVal { Rc::new(List(seq)) }
+pub fn vector(seq: Vec<MalVal>) -> MalVal { Rc::new(Vector(seq)) }
+pub fn hash_map(hm: HashMap<String,MalVal>) -> MalVal { Rc::new(Hash_Map(hm)) }
+
+pub fn hash_mapv(seq: Vec<MalVal>) -> MalRet {
+ if seq.len() % 2 == 1 {
+ return Err("odd number of elements to hash-map".to_string());
+ }
+ let mut new_hm: HashMap<String,MalVal> = HashMap::new();
+ let mut it = seq.iter();
+ loop {
+ let k = match it.next() {
+ Some(mv) => match *mv.clone() {
+ Strn(ref s) => s.to_string(),
+ _ => return Err("key is not a string in hash-map call".to_string()),
+ },
+ None => break,
+ };
+ let v = it.next().unwrap();
+ new_hm.insert(k, v.clone());
+ }
+ Ok(Rc::new(Hash_Map(new_hm)))
+}
pub fn func(f: fn(Vec<MalVal>) -> MalRet ) -> MalVal {
Rc::new(Func(f))