aboutsummaryrefslogtreecommitdiffstats
path: root/rust
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-04-25 17:33:21 -0400
committerbnewbold <bnewbold@robocracy.org>2016-04-25 17:33:21 -0400
commit48ead3f5edd2166de454be9e5da6891375b40f57 (patch)
treeb04c8ae9d499ac35a1dc06a880dbe33898b0f36e /rust
parentca05dc57bf4ff7e3db0e856ec323539fd190826d (diff)
downloadspectrum-48ead3f5edd2166de454be9e5da6891375b40f57.tar.gz
spectrum-48ead3f5edd2166de454be9e5da6891375b40f57.zip
rust: implement a bunch more math built-ins
Diffstat (limited to 'rust')
-rw-r--r--rust/spectrum.rs48
1 files changed, 48 insertions, 0 deletions
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<SchemeExpr>,
Ok(SchemeExpr::SchemeProcedure(binds, body, ctx.clone()))
}
+fn apply_math_cmp(action: &str, args: Vec<SchemeExpr>) -> Result<SchemeExpr, String> {
+ if args.len() != 2 {
+ return Err(format!("math comparisons take 2 args (at {})", action));
+ }
+ let mut vals = Vec::<f64>::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<SchemeExpr>) -> Result<SchemeExpr, String> {
+ 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<SchemeExpr>) -> Result<SchemeExpr, String> {
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>,
&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?" => {