Use Primitive type in evaluator

This commit is contained in:
Greg Shuflin 2021-10-24 06:04:58 -07:00
parent bd698629ff
commit 7a7e4ec0f2
2 changed files with 42 additions and 15 deletions

View File

@ -288,7 +288,7 @@ pub enum Lookup {
Param,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Literal {
Nat(u64),
Int(i64),

View File

@ -59,13 +59,13 @@ fn paren_wrapped(terms: impl Iterator<Item=String>) -> String {
#[derive(Debug)]
enum RuntimeValue {
Expression(Expression),
Function(FunctionDefinition),
Primitive(Primitive),
}
impl From<Expression> for RuntimeValue {
fn from(ex: Expression) -> Self {
Self::Expression(ex)
impl From<Primitive> for RuntimeValue {
fn from(prim: Primitive) -> Self {
Self::Primitive(prim)
}
}
@ -90,12 +90,40 @@ fn expr_to_repl(expr: &Expression) -> String {
impl RuntimeValue {
fn to_repl(&self) -> String {
match self {
RuntimeValue::Expression(ref expr) => expr_to_repl(expr),
RuntimeValue::Primitive(ref prim) => expr_to_repl(&prim.to_expr()),
RuntimeValue::Function(ref expr) => "<function>".to_string(),
}
}
}
/// A fully-reduced value
#[derive(Debug, Clone)]
enum Primitive {
Tuple(Vec<Primitive>),
Literal(Literal),
Callable(DefId),
Unimplemented,
/*
PrimObject {
name: Rc<String>,
tag: usize,
items: Vec<Node>,
},
*/
}
impl Primitive {
fn to_expr(&self) -> Expression {
match self {
Primitive::Tuple(items) => Expression::Tuple(items.iter().map(|item| item.to_expr()).collect()),
Primitive::Literal(lit) => Expression::Literal(lit.clone()),
Primitive::Callable(defid) => Expression::Callable(Function::UserDefined(defid.clone())),
Primitive::Unimplemented => Expression::Unimplemented,
}
}
}
impl<'a> State<'a> {
pub fn new() -> Self {
Self {
@ -141,25 +169,24 @@ impl<'a> State<'a> {
}
}
fn expression(&mut self, expression: Expression) -> EvalResult<Expression> {
fn expression(&mut self, expression: Expression) -> EvalResult<Primitive> {
use Expression::Unimplemented;
Ok(match expression {
lit @ Expression::Literal(_) => lit,
Expression::Tuple(items) => Expression::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Expression>>>()?),
Expression::Literal(lit) => Primitive::Literal(lit),
Expression::Tuple(items) => Primitive::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Primitive>>>()?),
Expression::Lookup { ref id, kind } => {
let mem = id.into();
match kind {
Lookup::Function => {
if self.environments.lookup(&mem).is_some() {
Expression::Callable(Function::UserDefined(id.clone()))
Primitive::Callable(id.clone())
} else {
return Err(format!("Function not found for id: {}", id));
}
},
kind @ Lookup::LocalVar | kind @ Lookup::GlobalVar | kind @ Lookup::Param => {
match self.environments.lookup(&mem) {
//Some(RuntimeValue::Expression(expr)) => (*expr).clone(),
Some(RuntimeValue::Expression(expr)) => Unimplemented,
Some(RuntimeValue::Primitive(expr)) => expr.clone(),
_ => return Err(format!("Nothing found for variable lookup {} of kind {:?}", id, kind)),
}
},
@ -168,16 +195,16 @@ impl<'a> State<'a> {
Expression::Assign { ref lval, box rval } => {
let mem = lval.into();
let mut env = self.environments.lookup(&mem);
Unimplemented
Primitive::Unimplemented
},
Expression::Call { box f, args } => self.call_expression(f, args)?,
Unimplemented => Unimplemented,
Unimplemented => Primitive::Unimplemented,
Expression::ReductionError(e) => return Err(e.into()),
e => return Err(format!("Can't yet handle {:?}", e)),
})
}
fn call_expression(&mut self, f: Expression, args: Vec<Expression>) -> EvalResult<Expression> {
fn call_expression(&mut self, f: Expression, args: Vec<Expression>) -> EvalResult<Primitive> {
Err("Call expression not implemented".to_string().into())
}
}