Make apply_builtin compatible with Node
This commit is contained in:
parent
12ed2f5c8e
commit
583e87c19a
@ -256,7 +256,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Node> {
|
fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Node> {
|
||||||
match f {
|
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 } => {
|
Func::UserDefined { params, body, name } => {
|
||||||
|
|
||||||
if params.len() != args.len() {
|
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<Expr>) -> EvalResult<Node> {
|
||||||
fn apply_builtin(&mut self, builtin: Builtin, args: Vec<Expr>) -> EvalResult<Expr> {
|
|
||||||
use self::Expr::*;
|
use self::Expr::*;
|
||||||
use self::Lit::*;
|
use self::Lit::*;
|
||||||
use Builtin::*;
|
use Builtin::*;
|
||||||
|
|
||||||
let evaled_args: Result<Vec<Expr>, String> = args.into_iter().map(|arg| {
|
let evaled_args: Result<Vec<Node>, String> = args.into_iter().map(|arg| self.expression(arg.to_node()))
|
||||||
match self.expression(Node::Expr(arg)) {
|
.collect();
|
||||||
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 = evaled_args?;
|
let evaled_args = evaled_args?;
|
||||||
|
|
||||||
Ok(match (builtin, evaled_args.as_slice()) {
|
Ok(match (builtin, evaled_args.as_slice()) {
|
||||||
|
(binop, &[Node::Expr(ref lhs), Node::Expr(ref rhs)]) => match (binop, lhs, rhs) {
|
||||||
/* binops */
|
/* binops */
|
||||||
(Add, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Nat(l + r)),
|
(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)))),
|
(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)),
|
(Subtract, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l - r)),
|
||||||
(Multiply, &[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))),
|
(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 {
|
(Quotient, Lit(Nat(l)), Lit(Nat(r))) => if *r == 0 {
|
||||||
return Err(format!("divide by zero"));
|
return Err(format!("divide by zero"));
|
||||||
} else {
|
} else {
|
||||||
Lit(Nat(l / r))
|
Lit(Nat(l / r))
|
||||||
},
|
},
|
||||||
(Modulo, &[Lit(Nat(l)), Lit(Nat(r))]) => 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)),
|
(Exponentiation, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l ^ r)),
|
||||||
(BitwiseAnd, &[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)),
|
(BitwiseOr, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l | r)),
|
||||||
|
|
||||||
/* comparisons */
|
/* comparisons */
|
||||||
(Equality, &[Lit(Nat(l)), Lit(Nat(r))]) => Lit(Bool(l == r)),
|
(Equality, Lit(Nat(l)), Lit(Nat(r))) => Lit(Bool(l == r)),
|
||||||
(Equality, &[Lit(Int(l)), Lit(Int(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(Float(l)), Lit(Float(r))) => Lit(Bool(l == r)),
|
||||||
(Equality, &[Lit(Bool(l)), Lit(Bool(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)),
|
(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(Nat(l)), Lit(Nat(r))) => Lit(Bool(l < r)),
|
||||||
(LessThan, &[Lit(Int(l)), Lit(Int(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(Float(l)), Lit(Float(r))) => Lit(Bool(l < r)),
|
||||||
|
|
||||||
(LessThanOrEqual, &[Lit(Nat(l)), Lit(Nat(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(Int(l)), Lit(Int(r))) => Lit(Bool(l <= r)),
|
||||||
(LessThanOrEqual, &[Lit(Float(l)), Lit(Float(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(Nat(l)), Lit(Nat(r))) => Lit(Bool(l > r)),
|
||||||
(GreaterThan, &[Lit(Int(l)), Lit(Int(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)),
|
(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)),
|
|
||||||
|
|
||||||
|
(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 */
|
/* builtin functions */
|
||||||
(IOPrint, &[ref anything]) => {
|
(IOPrint, &[ref anything]) => {
|
||||||
let ref symbol_table = self.symbol_table_handle.borrow();
|
let ref symbol_table = self.symbol_table_handle.borrow();
|
||||||
print!("{}", anything.to_repl(symbol_table));
|
print!("{}", anything.to_repl(symbol_table));
|
||||||
Expr::Unit
|
Expr::Unit.to_node()
|
||||||
},
|
},
|
||||||
(IOPrintLn, &[ref anything]) => {
|
(IOPrintLn, &[ref anything]) => {
|
||||||
let ref symbol_table = self.symbol_table_handle.borrow();
|
let ref symbol_table = self.symbol_table_handle.borrow();
|
||||||
println!("{}", anything.to_repl(symbol_table));
|
println!("{}", anything.to_repl(symbol_table));
|
||||||
Expr::Unit
|
Expr::Unit.to_node()
|
||||||
},
|
},
|
||||||
(IOGetLine, &[]) => {
|
(IOGetLine, &[]) => {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
io::stdin().read_line(&mut buf).expect("Error readling line in 'getline'");
|
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)),
|
(x, args) => return Err(format!("bad or unimplemented builtin {:?} | {:?}", x, args)),
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user