Got (some) arithmetic working again
This commit is contained in:
parent
3383921c6b
commit
c9cfc467b0
@ -4,6 +4,7 @@ use crate::util::ScopeStack;
|
|||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
type EvalResult<T> = Result<T, String>;
|
type EvalResult<T> = Result<T, String>;
|
||||||
@ -72,7 +73,6 @@ impl From<Primitive> for RuntimeValue {
|
|||||||
|
|
||||||
fn expr_to_repl(expr: &Expression) -> String {
|
fn expr_to_repl(expr: &Expression) -> String {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::Unimplemented => format!("Expression {:?} not implemented", expr),
|
|
||||||
Expression::Literal(lit) => match lit {
|
Expression::Literal(lit) => match lit {
|
||||||
Literal::Nat(n) => format!("{}", n),
|
Literal::Nat(n) => format!("{}", n),
|
||||||
Literal::Int(i) => format!("{}", i),
|
Literal::Int(i) => format!("{}", i),
|
||||||
@ -103,7 +103,6 @@ enum Primitive {
|
|||||||
Tuple(Vec<Primitive>),
|
Tuple(Vec<Primitive>),
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
Callable(Function),
|
Callable(Function),
|
||||||
Unimplemented,
|
|
||||||
/*
|
/*
|
||||||
PrimObject {
|
PrimObject {
|
||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
@ -113,13 +112,18 @@ enum Primitive {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Literal> for Primitive {
|
||||||
|
fn from(lit: Literal) -> Self {
|
||||||
|
Primitive::Literal(lit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Primitive {
|
impl Primitive {
|
||||||
fn to_expr(&self) -> Expression {
|
fn to_expr(&self) -> Expression {
|
||||||
match self {
|
match self {
|
||||||
Primitive::Tuple(items) => Expression::Tuple(items.iter().map(|item| item.to_expr()).collect()),
|
Primitive::Tuple(items) => Expression::Tuple(items.iter().map(|item| item.to_expr()).collect()),
|
||||||
Primitive::Literal(lit) => Expression::Literal(lit.clone()),
|
Primitive::Literal(lit) => Expression::Literal(lit.clone()),
|
||||||
Primitive::Callable(function) => Expression::Callable(function.clone()),
|
Primitive::Callable(function) => Expression::Callable(function.clone()),
|
||||||
Primitive::Unimplemented => Expression::Unimplemented,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +175,6 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expression(&mut self, expression: Expression) -> EvalResult<Primitive> {
|
fn expression(&mut self, expression: Expression) -> EvalResult<Primitive> {
|
||||||
use Expression::Unimplemented;
|
|
||||||
Ok(match expression {
|
Ok(match expression {
|
||||||
Expression::Literal(lit) => Primitive::Literal(lit),
|
Expression::Literal(lit) => Primitive::Literal(lit),
|
||||||
Expression::Tuple(items) => Primitive::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Primitive>>>()?),
|
Expression::Tuple(items) => Primitive::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Primitive>>>()?),
|
||||||
@ -194,10 +197,10 @@ impl<'a> State<'a> {
|
|||||||
Expression::Assign { ref lval, box rval } => {
|
Expression::Assign { ref lval, box rval } => {
|
||||||
let mem = lval.into();
|
let mem = lval.into();
|
||||||
let mut env = self.environments.lookup(&mem);
|
let mut env = self.environments.lookup(&mem);
|
||||||
Primitive::Unimplemented
|
return Err("Assign not implemented".to_string());
|
||||||
},
|
},
|
||||||
Expression::Call { box f, args } => self.call_expression(f, args)?,
|
Expression::Call { box f, args } => self.call_expression(f, args)?,
|
||||||
Unimplemented => Primitive::Unimplemented,
|
Expression::Callable(func) => Primitive::Callable(func),
|
||||||
Expression::ReductionError(e) => return Err(e.into()),
|
Expression::ReductionError(e) => return Err(e.into()),
|
||||||
e => return Err(format!("Can't yet handle {:?}", e)),
|
e => return Err(format!("Can't yet handle {:?}", e)),
|
||||||
})
|
})
|
||||||
@ -215,7 +218,33 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn apply_builtin(&mut self, builtin: Builtin, args: Vec<Expression>) -> EvalResult<Primitive> {
|
fn apply_builtin(&mut self, builtin: Builtin, args: Vec<Expression>) -> EvalResult<Primitive> {
|
||||||
return Err("unimplemented apply-builtin".to_string());
|
use Builtin::*;
|
||||||
|
use Literal::*;
|
||||||
|
use Expression::Literal as Lit;
|
||||||
|
|
||||||
|
let evaled_args: EvalResult<Vec<Expression>> =
|
||||||
|
args.into_iter().map(|arg| self.expression(arg).map(|prim| prim.to_expr())).collect();
|
||||||
|
let evaled_args = evaled_args?;
|
||||||
|
|
||||||
|
Ok(match (builtin, evaled_args.as_slice()) {
|
||||||
|
(FieldAccess, /*&[Node::PrimObject { .. }]*/ _) => {
|
||||||
|
return Err("Field access unimplemented".to_string());
|
||||||
|
}
|
||||||
|
(binop, &[ref lhs, ref rhs]) => match (binop, lhs, rhs) {
|
||||||
|
(Add, Lit(Nat(l)), Lit(Nat(r))) => Nat(l + r).into(),
|
||||||
|
(Concatenate, Lit(StringLit(ref s1)), Lit(StringLit(ref s2))) => StringLit(Rc::new(format!("{}{}", s1, s2))).into(),
|
||||||
|
(Subtract, Lit(Nat(l)), Lit(Nat(r))) => Nat(l - r).into(),
|
||||||
|
(Multiply, Lit(Nat(l)), Lit(Nat(r))) => Nat(l * r).into(),
|
||||||
|
(Divide, Lit(Nat(l)), Lit(Nat(r))) => Float((*l as f64)/ (*r as f64)).into(),
|
||||||
|
(Quotient, Lit(Nat(l)), Lit(Nat(r))) => if *r == 0 {
|
||||||
|
return Err("Divide-by-zero error".to_string());
|
||||||
|
} else {
|
||||||
|
Nat(l / r).into()
|
||||||
|
},
|
||||||
|
(binop, lhs, rhs) => return Err(format!("Invalid binop expression {:?} {:?} {:?}", lhs, binop, rhs)),
|
||||||
|
},
|
||||||
|
(x, args) => return Err(format!("bad or unimplemented builtin {:?} | {:?}", x, args)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_function(&mut self, def_id: DefId, args: Vec<Expression>) -> EvalResult<Primitive> {
|
fn apply_function(&mut self, def_id: DefId, args: Vec<Expression>) -> EvalResult<Primitive> {
|
||||||
|
Loading…
Reference in New Issue
Block a user