diff options
author | bnewbold <bnewbold@robocracy.org> | 2016-04-25 23:54:43 -0400 |
---|---|---|
committer | bnewbold <bnewbold@robocracy.org> | 2016-04-25 23:54:43 -0400 |
commit | 3586683bda805c5156649f760f26921b9d0a2250 (patch) | |
tree | 5cfd32891dfc335c9d06690b60c75fe9e180709c | |
parent | 21bf5448a581e4839c81c4c37e655c0e85e5208a (diff) | |
download | spectrum-3586683bda805c5156649f760f26921b9d0a2250.tar.gz spectrum-3586683bda805c5156649f760f26921b9d0a2250.zip |
rust: add a (lazy) 'if' applier
-rw-r--r-- | prelude.scm | 1 | ||||
-rw-r--r-- | rust/spectrum.rs | 30 |
2 files changed, 27 insertions, 4 deletions
diff --git a/prelude.scm b/prelude.scm index a3b123e..a7469b5 100644 --- a/prelude.scm +++ b/prelude.scm @@ -18,7 +18,6 @@ ; my favorite! (define cdaddr (lambda (x) (cdr (car (cdr (cdr x)))))) -(define if (lambda (pred tval fval) (cond (pred tval) (else fval)))) (define not (lambda (x) (if x #f #t))) (define abs (lambda (x) (if (> x 0) x (* -1 x)))) diff --git a/rust/spectrum.rs b/rust/spectrum.rs index 18080f3..85d18b6 100644 --- a/rust/spectrum.rs +++ b/rust/spectrum.rs @@ -15,9 +15,9 @@ use std::collections::HashMap; //////////// Types and Constants -// TODO: how to avoid the '35' here? -const SCHEME_BUILTINS: [&'static str; 35] = [ - "lambda", "quote", "cond", "else", +// TODO: how to avoid the '37' here? +const SCHEME_BUILTINS: [&'static str; 37] = [ + "lambda", "quote", "cond", "else", "if", "begin", "display", "newline", "define", "set!", "cons", "car", "cdr", @@ -301,6 +301,21 @@ fn cond_action(list: &Vec<SchemeExpr>, Ok(SchemeExpr::SchemeNull) } +fn if_action(list: &Vec<SchemeExpr>, + ctx: HashMap<String, SchemeExpr>, + env: &mut HashMap<String, SchemeExpr>) -> Result<SchemeExpr, String> { + + if list.len() != 4 { + return Err(format!("'if' must receive 3 arguments")); + } + let pred = try!(scheme_meaning(&list[1], ctx.clone(), env)); + if pred != SchemeExpr::SchemeFalse && pred != SchemeExpr::SchemeNull { + return scheme_meaning(&list[2], ctx, env); + } else { + return scheme_meaning(&list[3], ctx, env); + } +} + fn lambda_action(list: &Vec<SchemeExpr>, ctx: HashMap<String, SchemeExpr>) -> Result<SchemeExpr, String> { if list.len() < 3 { @@ -554,6 +569,13 @@ fn apply_action(list: &Vec<SchemeExpr>, _ => Err(format!("cons second arg must be list or null")) } }, + "begin" => { + let mut ret = SchemeExpr::SchemeNull; + for expr in args { + ret = try!(scheme_meaning(&expr, ctx.clone(), env)); + } + Ok(ret) + }, "display" => { for expr in args { print!("{}", try!(scheme_repr(&expr))); @@ -626,6 +648,8 @@ fn scheme_meaning(ast: &SchemeExpr, match list[0] { SchemeExpr::SchemeBuiltin(ref b) if b == "quote" => quote_action(&list), + SchemeExpr::SchemeBuiltin(ref b) if b == "if" => + if_action(&list, ctx, env), SchemeExpr::SchemeBuiltin(ref b) if b == "cond" => cond_action(&list, ctx, env), SchemeExpr::SchemeBuiltin(ref b) if b == "lambda" => |