From 48ead3f5edd2166de454be9e5da6891375b40f57 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 25 Apr 2016 17:33:21 -0400 Subject: rust: implement a bunch more math built-ins --- rust/spectrum.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/rust/spectrum.rs b/rust/spectrum.rs index 9f30a00..c5ebad3 100644 --- a/rust/spectrum.rs +++ b/rust/spectrum.rs @@ -321,6 +321,52 @@ fn lambda_action(list: &Vec, Ok(SchemeExpr::SchemeProcedure(binds, body, ctx.clone())) } +fn apply_math_cmp(action: &str, args: Vec) -> Result { + if args.len() != 2 { + return Err(format!("math comparisons take 2 args (at {})", action)); + } + let mut vals = Vec::::new(); + for arg in args { + match arg { + SchemeExpr::SchemeNum(x) => { vals.push(x) }, + _ => { return Err(format!("math builtins take only numerical types (got {})", + scheme_repr(&arg).unwrap())) }, + } + } + + let ret: bool = match action { + "=" => vals[0] == vals[1], + ">" => vals[0] > vals[1], + ">=" => vals[0] >= vals[1], + "<" => vals[0] < vals[1], + "<=" => vals[0] <= vals[1], + _ => { return Err(format!("unexpected math builting: {}", action)); }, + }; + return Ok( if ret {SchemeExpr::SchemeTrue} else { SchemeExpr::SchemeFalse } ); +} + +fn apply_math_unary(action: &str, args: Vec) -> Result { + if args.len() != 1 { + return Err(format!("math unary builtins only take one argument (at {})", action)); + } + let val = match args[0] { + SchemeExpr::SchemeNum(x) => x, + _ => { return Err(format!("math builtins take only numerical types (got {})", + scheme_repr(&args[0]).unwrap())) + }, + }; + + let ret: f64 = match action { + "exp" => val.exp(), + "log" => val.ln(), + "sin" => val.sin(), + "cos" => val.cos(), + "tan" => val.tan(), + _ => { return Err(format!("unimplemented math operation: {}", action)); }, + }; + Ok(SchemeExpr::SchemeNum(ret)) +} + fn apply_math_op(action: &str, args: Vec) -> Result { if args.len() < 2 { return Err(format!("math builtins take two or more args (at {})", action)); @@ -449,6 +495,8 @@ fn apply_action(list: &Vec, &SchemeExpr::SchemeBuiltin(ref builtin) => { return match builtin.as_str() { "+" | "-" | "*" | "/" => apply_math_op(builtin, args), + "=" | ">" | ">=" | "<" | "<=" => apply_math_cmp(builtin, args), + "exp"| "log" | "sin" | "cos" | "tan" => apply_math_unary(builtin, args), "boolean?" | "symbol?" | "procedure?" | "pair?" | "number?" | "string?" | "null?" | "atom?" | "zero?" => apply_typecheck(builtin, args), "eq?" => { -- cgit v1.2.3