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, Param,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Literal { pub enum Literal {
Nat(u64), Nat(u64),
Int(i64), Int(i64),

View File

@ -59,13 +59,13 @@ fn paren_wrapped(terms: impl Iterator<Item=String>) -> String {
#[derive(Debug)] #[derive(Debug)]
enum RuntimeValue { enum RuntimeValue {
Expression(Expression),
Function(FunctionDefinition), Function(FunctionDefinition),
Primitive(Primitive),
} }
impl From<Expression> for RuntimeValue { impl From<Primitive> for RuntimeValue {
fn from(ex: Expression) -> Self { fn from(prim: Primitive) -> Self {
Self::Expression(ex) Self::Primitive(prim)
} }
} }
@ -90,12 +90,40 @@ fn expr_to_repl(expr: &Expression) -> String {
impl RuntimeValue { impl RuntimeValue {
fn to_repl(&self) -> String { fn to_repl(&self) -> String {
match self { 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(), 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> { impl<'a> State<'a> {
pub fn new() -> Self { pub fn new() -> Self {
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; use Expression::Unimplemented;
Ok(match expression { Ok(match expression {
lit @ Expression::Literal(_) => lit, Expression::Literal(lit) => Primitive::Literal(lit),
Expression::Tuple(items) => Expression::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Expression>>>()?), Expression::Tuple(items) => Primitive::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::<EvalResult<Vec<Primitive>>>()?),
Expression::Lookup { ref id, kind } => { Expression::Lookup { ref id, kind } => {
let mem = id.into(); let mem = id.into();
match kind { match kind {
Lookup::Function => { Lookup::Function => {
if self.environments.lookup(&mem).is_some() { if self.environments.lookup(&mem).is_some() {
Expression::Callable(Function::UserDefined(id.clone())) Primitive::Callable(id.clone())
} else { } else {
return Err(format!("Function not found for id: {}", id)); return Err(format!("Function not found for id: {}", id));
} }
}, },
kind @ Lookup::LocalVar | kind @ Lookup::GlobalVar | kind @ Lookup::Param => { kind @ Lookup::LocalVar | kind @ Lookup::GlobalVar | kind @ Lookup::Param => {
match self.environments.lookup(&mem) { match self.environments.lookup(&mem) {
//Some(RuntimeValue::Expression(expr)) => (*expr).clone(), Some(RuntimeValue::Primitive(expr)) => expr.clone(),
Some(RuntimeValue::Expression(expr)) => Unimplemented,
_ => return Err(format!("Nothing found for variable lookup {} of kind {:?}", id, kind)), _ => 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 } => { 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);
Unimplemented Primitive::Unimplemented
}, },
Expression::Call { box f, args } => self.call_expression(f, args)?, Expression::Call { box f, args } => self.call_expression(f, args)?,
Unimplemented => Unimplemented, Unimplemented => Primitive::Unimplemented,
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)),
}) })
} }
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()) Err("Call expression not implemented".to_string().into())
} }
} }