aboutsummaryrefslogtreecommitdiff
path: root/src/simple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/simple.rs')
-rw-r--r--src/simple.rs53
1 files changed, 27 insertions, 26 deletions
diff --git a/src/simple.rs b/src/simple.rs
index 8d87dbf..e763221 100644
--- a/src/simple.rs
+++ b/src/simple.rs
@@ -1,32 +1,33 @@
use crate::ast::*;
-/// Evaluates an expression given a context (of variables) to a term, or fails.
-pub fn execute(context: &Context, expression: Expression) -> Result<Term, String> {
- match expression {
- Expression::Annotation { expr, .. } => execute(context, *expr),
- Expression::Constant { term } => Ok(term),
- Expression::Variable { id } => match context.get(&id) {
- Some(term) => Ok(term.clone()),
- None => Err(format!("no such variable in context {context:?}"))
- },
- Expression::Abstraction { param, func } =>
- Err(format!("attempting to execute an abstraction ({}){}", param, func)),
- Expression::Application { func, arg } => match *func {
- Expression::Abstraction { param, func } => {
- let value = execute(context, *arg)?;
- let mut context = context.clone();
- context.insert(param, value);
- return execute(&context, *func);
- }
- _ => Err(format!("attempting to execute an application to non-abstraction {}", *func))
- },
- Expression::Conditional { if_cond, if_then, if_else } => {
- match execute(context, *if_cond)? {
- Term::Boolean(true) => execute(context, *if_then),
- Term::Boolean(false) => execute(context, *if_else),
- term => Err(format!("invalid type {} for a conditional", convert(&term)?))
+impl Context {
+ /// Evaluates an expression given a context (of variables) to a term, or fails.
+ pub fn execute(&self, expression: Expression) -> Result<Term> {
+ match expression {
+ Expression::Annotation { expr, .. } => self.execute(*expr),
+ Expression::Constant { term } => Ok(term),
+ Expression::Variable { id } => match self.get(&id) {
+ Some(term) => Ok(term.clone()),
+ None => Err(format!("no such variable in context {self:?}").into())
+ },
+ Expression::Abstraction { param, func } =>
+ Err(format!("attempting to execute an abstraction ({}){}", param, func).into()),
+ Expression::Application { func, arg } => match *func {
+ Expression::Abstraction { param, func } => {
+ let value = self.execute(*arg)?;
+ let mut context = self.clone();
+ context.insert(param, value);
+ return context.execute(*func);
+ }
+ _ => Err(format!("attempting to execute an application to non-abstraction {}", *func).into())
+ },
+ Expression::Conditional { if_cond, if_then, if_else } => {
+ match self.execute(*if_cond)? {
+ Term::Boolean(true) => self.execute(*if_then),
+ Term::Boolean(false) => self.execute(*if_else),
+ term => Err(format!("invalid type {} for a conditional", &term.convert()?).into())
+ }
}
}
}
}
-