aboutsummaryrefslogtreecommitdiff
path: root/rust/src/types.rs
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-27 18:13:45 -0500
committerJoel Martin <github@martintribe.org>2015-01-06 21:58:59 -0600
commita77e2b31de9d1c1f5767e6bff56062f8b3c71211 (patch)
tree1dcf0de2c407510aee4fac2ac5a8dfef7b63c963 /rust/src/types.rs
parent4ee7c0f2970accc0f49eeac7fb2a0359b159c8ae (diff)
downloadmal-a77e2b31de9d1c1f5767e6bff56062f8b3c71211.tar.gz
mal-a77e2b31de9d1c1f5767e6bff56062f8b3c71211.zip
rust: add step8_macros
Diffstat (limited to 'rust/src/types.rs')
-rw-r--r--rust/src/types.rs37
1 files changed, 30 insertions, 7 deletions
diff --git a/rust/src/types.rs b/rust/src/types.rs
index 85262c7..b8e1de0 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -4,7 +4,7 @@ use std::rc::Rc;
use std::collections;
use std::fmt;
use super::printer::{escape_str,pr_list};
-use super::env::Env;
+use super::env::{Env,env_new,env_bind};
#[deriving(Clone)]
pub enum MalType {
@@ -29,12 +29,13 @@ pub type MalRet = Result<MalVal,String>;
#[deriving(Clone)]
pub struct MalFuncData {
- pub exp: MalVal,
- pub env: Env,
- pub params: MalVal,
+ pub eval: fn(MalVal, Env) -> MalRet,
+ pub exp: MalVal,
+ pub env: Env,
+ pub params: MalVal,
+ pub is_macro: bool,
}
-
impl MalType {
pub fn pr_str(&self, print_readably: bool) -> String {
let _r = print_readably;
@@ -86,6 +87,22 @@ impl MalType {
res
}
+ pub fn apply(&self, args:Vec<MalVal>) -> MalRet {
+ match *self {
+ Func(f) => f(args),
+ MalFunc(ref mf) => {
+ let mfc = mf.clone();
+ let alst = list(args);
+ let new_env = env_new(Some(mfc.env.clone()));
+ match env_bind(&new_env, mfc.params, alst) {
+ Ok(_) => (mfc.eval)(mfc.exp, new_env),
+ Err(e) => Err(e),
+ }
+ },
+ _ => Err("attempt to call non-function".to_string()),
+ }
+
+ }
}
impl PartialEq for MalType {
@@ -114,6 +131,7 @@ impl fmt::Show for MalType {
}
}
+
// Convenience constructor functions
pub fn _nil() -> MalVal { Rc::new(Nil) }
pub fn _true() -> MalVal { Rc::new(True) }
@@ -129,6 +147,11 @@ pub fn list(lst: Vec<MalVal>) -> MalVal { Rc::new(List(lst)) }
pub fn func(f: fn(Vec<MalVal>) -> MalRet ) -> MalVal {
Rc::new(Func(f))
}
-pub fn malfunc(exp: MalVal, env: Env, params: MalVal) -> MalVal {
- Rc::new(MalFunc(MalFuncData{ exp: exp, env: env, params: params}))
+pub fn malfunc(eval: fn(MalVal, Env) -> MalRet,
+ exp: MalVal, env: Env, params: MalVal) -> MalVal {
+ Rc::new(MalFunc(MalFuncData{eval: eval, exp: exp, env: env,
+ params: params, is_macro: false}))
+}
+pub fn malfuncd(mfd: MalFuncData) -> MalVal {
+ Rc::new(MalFunc(mfd))
}