From 3586683bda805c5156649f760f26921b9d0a2250 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 25 Apr 2016 23:54:43 -0400 Subject: rust: add a (lazy) 'if' applier --- prelude.scm | 1 - 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, Ok(SchemeExpr::SchemeNull) } +fn if_action(list: &Vec, + ctx: HashMap, + env: &mut HashMap) -> Result { + + 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, ctx: HashMap) -> Result { if list.len() < 3 { @@ -554,6 +569,13 @@ fn apply_action(list: &Vec, _ => 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" => -- cgit v1.2.3