diff options
Diffstat (limited to 'src/builtins.rs')
| -rw-r--r-- | src/builtins.rs | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/src/builtins.rs b/src/builtins.rs index b8b789f..51ea699 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -1,7 +1,26 @@ use super::ast; use super::runtime::{advance_v, Term, Value}; +use std::fmt; use std::rc::Rc; +#[derive(Debug, Clone, PartialEq)] +pub struct Builtin { + identifier: &'static str, + repr_name: &'static str, + arguments: Vec<Value>, +} + +impl fmt::Display for Builtin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut arg_str = String::new(); + for argument in &self.arguments { + arg_str.push_str(format!(" {}", argument).as_str()); + } + + write!(f, "Builtin({}){}", self.repr_name, arg_str) + } +} + pub const B_INTEGER_EQ0: &str = "int.eq0?"; pub const B_INTEGER_INCREMENT: &str = "int.increment"; pub const B_INTEGER_ADD: &str = "int.add"; @@ -25,23 +44,33 @@ pub fn make_identity_function() -> Term { } pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> { - match symbol.as_str() { - "true" => Some(make_boolean_true_function()), - "false" => Some(make_boolean_false_function()), - "id" => Some(make_identity_function()), - B_INTEGER_EQ0 => Some(Term::Builtin(String::from(B_INTEGER_EQ0), vec![])), - B_INTEGER_INCREMENT => Some(Term::Builtin(String::from(B_INTEGER_INCREMENT), vec![])), - B_INTEGER_ADD => Some(Term::Builtin(String::from(B_INTEGER_ADD), vec![])), - _ => None, - } + let builtin = match symbol.as_str() { + "true" => return Some(make_boolean_true_function()), + "false" => return Some(make_boolean_false_function()), + "id" => return Some(make_identity_function()), + B_INTEGER_EQ0 => Builtin { + identifier: B_INTEGER_EQ0, + repr_name: B_INTEGER_EQ0, + arguments: vec![], + }, + B_INTEGER_INCREMENT => Builtin { + identifier: B_INTEGER_INCREMENT, + repr_name: B_INTEGER_INCREMENT, + arguments: vec![], + }, + B_INTEGER_ADD => Builtin { + identifier: B_INTEGER_ADD, + repr_name: B_INTEGER_ADD, + arguments: vec![], + }, + _ => return None, + }; + + Some(Term::Builtin(builtin)) } -pub fn evaluate_builtin( - symbol: &String, - bound_arguments: &Vec<Value>, - rhs: Rc<Term>, -) -> Result<(Rc<Term>, usize), String> { - let result_term = match symbol.as_str() { +pub fn evaluate_builtin(builtin: &Builtin, rhs: Rc<Term>) -> Result<(Rc<Term>, usize), String> { + let result_term = match builtin.identifier { B_INTEGER_EQ0 => match &*rhs { Term::Primitive(primitive) => match primitive { Value::Integer(value) => { @@ -54,11 +83,11 @@ pub fn evaluate_builtin( other => { return Err(format!( "[runtime] cannot apply builtin {} to argument {}", - symbol, other + builtin.identifier, other )) } }, - _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), }, B_INTEGER_INCREMENT => match &*rhs { Term::Primitive(primitive) => match primitive { @@ -66,31 +95,36 @@ pub fn evaluate_builtin( other => { return Err(format!( "[runtime] cannot apply builtin {} to argument {}", - symbol, other + builtin.identifier, other )) } }, - _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), }, B_INTEGER_ADD => match &*rhs { Term::Primitive(primitive) => match primitive { Value::Integer(_) => { - Term::Builtin(String::from(B_INTEGER_ADD_1), vec![primitive.clone()]) + let new_builtin = Builtin { + identifier: B_INTEGER_ADD_1, + repr_name: builtin.identifier, + arguments: vec![primitive.clone()], + }; + Term::Builtin(new_builtin) } other => { return Err(format!( "[runtime] cannot apply builtin {} to argument {}", - symbol, other + builtin.identifier, other )) } }, - _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), }, B_INTEGER_ADD_1 => match &*rhs { Term::Primitive(primitive) => match primitive { Value::Integer(value) => { - assert_eq!(bound_arguments.len(), 1); - let summand = &bound_arguments[0]; + assert_eq!(builtin.arguments.len(), 1); + let summand = &builtin.arguments[0]; match summand { Value::Integer(summand_value) => { Term::Primitive(Value::Integer(summand_value + value)) @@ -98,7 +132,7 @@ pub fn evaluate_builtin( other => { return Err(format!( "[runtime] cannot apply builtin {} to argument {}", - symbol, other + builtin.identifier, other )) } } @@ -106,18 +140,18 @@ pub fn evaluate_builtin( other => { return Err(format!( "[runtime] cannot apply builtin {} to argument {}", - symbol, other + builtin.identifier, other )) } }, - _ => { - return Ok(( - Rc::new(Term::Builtin(symbol.clone(), bound_arguments.clone())), - 0, - )) - } + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), }, - _ => return Err(format!("[runtime] invalid builtin evaluated: {}", symbol)), + _ => { + return Err(format!( + "[runtime] invalid builtin evaluated: {}", + builtin.identifier + )) + } }; Ok((Rc::new(result_term), 1)) |
