diff options
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/spectrum.rs | 48 | 
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?" => {  | 
