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

View File

@ -336,6 +336,7 @@ impl<'a> State<'a> {
impl Expr { impl Expr {
fn to_repl(&self) -> String { fn to_repl(&self) -> String {
use self::Lit::*; use self::Lit::*;
use self::Func::*;
match self { match self {
Expr::Lit(ref l) => match l { Expr::Lit(ref l) => match l {
Nat(n) => format!("{}", n), Nat(n) => format!("{}", n),
@ -344,6 +345,11 @@ impl Expr {
Bool(b) => format!("{}", b), Bool(b) => format!("{}", b),
StringLit(s) => format!("{}", s), 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), _ => format!("{:?}", self),
} }
} }
@ -384,14 +390,15 @@ impl<'a> State<'a> {
literal @ Lit(_) => Ok(literal), literal @ Lit(_) => Ok(literal),
Call { f, args } => self.apply_function(f, args), Call { f, args } => self.apply_function(f, args),
Val(v) => self.value(v), 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> { fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> {
match f { match f {
Func::BuiltIn(sigil) => self.apply_builtin(sigil, args), Func::BuiltIn(sigil) => self.apply_builtin(sigil, args),
Func::UserDefined { params, body } => { Func::UserDefined { params, body, .. } => {
Err(format!("Function application not done yet")) Err(format!("Function application not done yet"))
} }
} }
@ -437,9 +444,15 @@ impl<'a> State<'a> {
match self.values.lookup(&name) { match self.values.lookup(&name) {
None => return Err(format!("Value {} not found", *name)), None => return Err(format!("Value {} not found", *name)),
Some(lookup) => match lookup { 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")), _ => Err(format!("Functions not done")),
} }
}
} }
/* /*
fn eval_value(&mut self, name: Rc<String>) -> EvalResult<FullyEvaluatedExpr> { fn eval_value(&mut self, name: Rc<String>) -> EvalResult<FullyEvaluatedExpr> {
@ -453,5 +466,4 @@ impl<'a> State<'a> {
} }
} }
*/ */
}
} }