Functions

This commit is contained in:
greg 2018-05-11 23:23:54 -07:00
parent 848306ad1a
commit 6d8d2aecbd
2 changed files with 18 additions and 4 deletions

View File

@ -41,6 +41,7 @@ pub enum Lit {
pub enum Func {
BuiltIn(Rc<String>),
UserDefined {
name: Option<Rc<String>>,
params: Vec<Rc<String>>,
body: Vec<Stmt>,
}
@ -98,6 +99,7 @@ impl Declaration {
name: name.clone(),
constant: true,
expr: Expr::Func(Func::UserDefined {
name: None,
params: params.iter().map(|param| param.0.clone()).collect(),
body: statements.iter().map(|stmt| stmt.reduce()).collect(),
})

View File

@ -336,6 +336,7 @@ impl<'a> State<'a> {
impl Expr {
fn to_repl(&self) -> String {
use self::Lit::*;
use self::Func::*;
match self {
Expr::Lit(ref l) => match l {
Nat(n) => format!("{}", n),
@ -344,6 +345,11 @@ impl Expr {
Bool(b) => format!("{}", b),
StringLit(s) => format!("{}", s),
},
Expr::Func(f) => match f {
BuiltIn(name) => format!("<built-in function {}>", name),
UserDefined { name: None, .. } => format!("<function>"),
UserDefined { name: Some(name), .. } => format!("<function {}>", name),
},
_ => format!("{:?}", self),
}
}
@ -384,14 +390,15 @@ impl<'a> State<'a> {
literal @ Lit(_) => Ok(literal),
Call { f, args } => self.apply_function(f, args),
Val(v) => self.value(v),
_ => Err(format!("NOT IMPLEMENTED YET"))
func @ Func(_) => Ok(func),
e => Err(format!("Expr {:?} eval not implemented", e))
}
}
fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> {
match f {
Func::BuiltIn(sigil) => self.apply_builtin(sigil, args),
Func::UserDefined { params, body } => {
Func::UserDefined { params, body, .. } => {
Err(format!("Function application not done yet"))
}
}
@ -437,10 +444,16 @@ impl<'a> State<'a> {
match self.values.lookup(&name) {
None => return Err(format!("Value {} not found", *name)),
Some(lookup) => match lookup {
&Binding { ref val, .. } => Ok(val.clone()),
Binding { val, .. } => Ok(
if let Expr::Func(Func::UserDefined { name: None, params, body }) = val {
Expr::Func(Func::UserDefined { name: Some(name.clone()), params: params.clone(), body: body.clone() }) //TODO here is unnecessary cloning
} else {
val.clone()
}),
_ => Err(format!("Functions not done")),
}
}
}
/*
fn eval_value(&mut self, name: Rc<String>) -> EvalResult<FullyEvaluatedExpr> {
use self::ValueEntry::*;
@ -453,5 +466,4 @@ impl<'a> State<'a> {
}
}
*/
}
}