diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 8116400..abe43b6 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -256,7 +256,7 @@ impl<'a> State<'a> { fn apply_function(&mut self, f: Func, args: Vec) -> EvalResult { match f { - Func::BuiltIn(builtin) => Ok(Node::Expr(self.apply_builtin(builtin, args)?)), + Func::BuiltIn(builtin) => Ok(self.apply_builtin(builtin, args)?), Func::UserDefined { params, body, name } => { if params.len() != args.len() { @@ -276,86 +276,82 @@ impl<'a> State<'a> { } } - //TODO to make builtins work, need to change this concept of Node - fn apply_builtin(&mut self, builtin: Builtin, args: Vec) -> EvalResult { + fn apply_builtin(&mut self, builtin: Builtin, args: Vec) -> EvalResult { use self::Expr::*; use self::Lit::*; use Builtin::*; - let evaled_args: Result, String> = args.into_iter().map(|arg| { - match self.expression(Node::Expr(arg)) { - Ok(Node::Expr(e)) => Ok(e), - Ok(Node::PrimTuple { .. }) => Err(format!("Trying to apply a builtin to a tuple")), - Ok(Node::PrimObject { .. }) => Err(format!("Trying to apply a builtin to a primitive object")), - Err(e) => Err(e) - } - }).collect(); + let evaled_args: Result, String> = args.into_iter().map(|arg| self.expression(arg.to_node())) + .collect(); let evaled_args = evaled_args?; Ok(match (builtin, evaled_args.as_slice()) { - /* binops */ - (Add, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l + r)), - (Concatenate, &[Lit(StringLit(ref s1)), Lit(StringLit(ref s2))]) => Lit(StringLit(Rc::new(format!("{}{}", s1, s2)))), - (Subtract, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l - r)), - (Multiply, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l * r)), - (Divide, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Float((l as f64)/ (r as f64))), - (Quotient, &[Lit(Nat(l)), Lit(Nat(r))]) => if r == 0 { - return Err(format!("divide by zero")); - } else { - Lit(Nat(l / r)) - }, - (Modulo, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l % r)), - (Exponentiation, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l ^ r)), - (BitwiseAnd, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l & r)), - (BitwiseOr, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l | r)), + (binop, &[Node::Expr(ref lhs), Node::Expr(ref rhs)]) => match (binop, lhs, rhs) { + /* binops */ + (Add, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l + r)), + (Concatenate, Lit(StringLit(ref s1)), Lit(StringLit(ref s2))) => Lit(StringLit(Rc::new(format!("{}{}", s1, s2)))), + (Subtract, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l - r)), + (Multiply, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l * r)), + (Divide, Lit(Nat(l)), Lit(Nat(r))) => Lit(Float((*l as f64)/ (*r as f64))), + (Quotient, Lit(Nat(l)), Lit(Nat(r))) => if *r == 0 { + return Err(format!("divide by zero")); + } else { + Lit(Nat(l / r)) + }, + (Modulo, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l % r)), + (Exponentiation, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l ^ r)), + (BitwiseAnd, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l & r)), + (BitwiseOr, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l | r)), - /* comparisons */ - (Equality, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l == r)), - (Equality, &[Lit(Int(l)), Lit(Int(r))]) => Lit(Bool(l == r)), - (Equality, &[Lit(Float(l)), Lit(Float(r))]) => Lit(Bool(l == r)), - (Equality, &[Lit(Bool(l)), Lit(Bool(r))]) => Lit(Bool(l == r)), - (Equality, &[Lit(StringLit(ref l)), Lit(StringLit(ref r))]) => Lit(Bool(l == r)), + /* comparisons */ + (Equality, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l == r)), + (Equality, Lit(Int(l)), Lit(Int(r))) => Lit(Bool(l == r)), + (Equality, Lit(Float(l)), Lit(Float(r))) => Lit(Bool(l == r)), + (Equality, Lit(Bool(l)), Lit(Bool(r))) => Lit(Bool(l == r)), + (Equality, Lit(StringLit(ref l)), Lit(StringLit(ref r))) => Lit(Bool(l == r)), - (LessThan, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l < r)), - (LessThan, &[Lit(Int(l)), Lit(Int(r))]) => Lit(Bool(l < r)), - (LessThan, &[Lit(Float(l)), Lit(Float(r))]) => Lit(Bool(l < r)), + (LessThan, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l < r)), + (LessThan, Lit(Int(l)), Lit(Int(r))) => Lit(Bool(l < r)), + (LessThan, Lit(Float(l)), Lit(Float(r))) => Lit(Bool(l < r)), - (LessThanOrEqual, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l <= r)), - (LessThanOrEqual, &[Lit(Int(l)), Lit(Int(r))]) => Lit(Bool(l <= r)), - (LessThanOrEqual, &[Lit(Float(l)), Lit(Float(r))]) => Lit(Bool(l <= r)), + (LessThanOrEqual, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l <= r)), + (LessThanOrEqual, Lit(Int(l)), Lit(Int(r))) => Lit(Bool(l <= r)), + (LessThanOrEqual, Lit(Float(l)), Lit(Float(r))) => Lit(Bool(l <= r)), - (GreaterThan, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l > r)), - (GreaterThan, &[Lit(Int(l)), Lit(Int(r))]) => Lit(Bool(l > r)), - (GreaterThan, &[Lit(Float(l)), Lit(Float(r))]) => Lit(Bool(l > r)), - - (GreaterThanOrEqual, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l >= r)), - (GreaterThanOrEqual, &[Lit(Int(l)), Lit(Int(r))]) => Lit(Bool(l >= r)), - (GreaterThanOrEqual, &[Lit(Float(l)), Lit(Float(r))]) => Lit(Bool(l >= r)), - - /* prefix ops */ - (BooleanNot, &[Lit(Bool(true))]) => Lit(Bool(false)), - (BooleanNot, &[Lit(Bool(false))]) => Lit(Bool(true)), - (Negate, &[Lit(Nat(n))]) => Lit(Int(-1*(n as i64))), - (Negate, &[Lit(Int(n))]) => Lit(Int(-1*(n as i64))), - (Increment, &[Lit(Int(n))]) => Lit(Int(n)), - (Increment, &[Lit(Nat(n))]) => Lit(Nat(n)), + (GreaterThan, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l > r)), + (GreaterThan, Lit(Int(l)), Lit(Int(r))) => Lit(Bool(l > r)), + (GreaterThan, Lit(Float(l)), Lit(Float(r))) => Lit(Bool(l > r)), + (GreaterThanOrEqual, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l >= r)), + (GreaterThanOrEqual, Lit(Int(l)), Lit(Int(r))) => Lit(Bool(l >= r)), + (GreaterThanOrEqual, Lit(Float(l)), Lit(Float(r))) => Lit(Bool(l >= r)), + _ => return Err("No valid binop".to_string()) + }.to_node(), + (prefix, &[Node::Expr(ref arg)]) => match (prefix, arg) { + (BooleanNot, Lit(Bool(true))) => Lit(Bool(false)), + (BooleanNot, Lit(Bool(false))) => Lit(Bool(true)), + (Negate, Lit(Nat(n))) => Lit(Int(-1*(*n as i64))), + (Negate, Lit(Int(n))) => Lit(Int(-1*(*n as i64))), + (Increment, Lit(Int(n))) => Lit(Int(*n)), + (Increment, Lit(Nat(n))) => Lit(Nat(*n)), + _ => return Err("No valid prefix op".to_string()) + }.to_node(), /* builtin functions */ (IOPrint, &[ref anything]) => { let ref symbol_table = self.symbol_table_handle.borrow(); print!("{}", anything.to_repl(symbol_table)); - Expr::Unit + Expr::Unit.to_node() }, (IOPrintLn, &[ref anything]) => { let ref symbol_table = self.symbol_table_handle.borrow(); println!("{}", anything.to_repl(symbol_table)); - Expr::Unit + Expr::Unit.to_node() }, (IOGetLine, &[]) => { let mut buf = String::new(); io::stdin().read_line(&mut buf).expect("Error readling line in 'getline'"); - Lit(StringLit(Rc::new(buf.trim().to_string()))) + Lit(StringLit(Rc::new(buf.trim().to_string()))).to_node() }, (x, args) => return Err(format!("bad or unimplemented builtin {:?} | {:?}", x, args)), })