aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-04-25 23:54:43 -0400
committerbnewbold <bnewbold@robocracy.org>2016-04-25 23:54:43 -0400
commit3586683bda805c5156649f760f26921b9d0a2250 (patch)
tree5cfd32891dfc335c9d06690b60c75fe9e180709c
parent21bf5448a581e4839c81c4c37e655c0e85e5208a (diff)
downloadspectrum-3586683bda805c5156649f760f26921b9d0a2250.zip
spectrum-3586683bda805c5156649f760f26921b9d0a2250.tar.gz
rust: add a (lazy) 'if' applier
-rw-r--r--prelude.scm1
-rw-r--r--rust/spectrum.rs30
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" =>