diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2021-11-23 23:49:58 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2021-11-25 09:53:44 +0200 |
| commit | e81d731b29c484ef2bab159d78a5417674e840ed (patch) | |
| tree | 3f211c6e5a70b27e62f6b95b1b8d7772fd59ee9e /src | |
| parent | c1f50fea93ad308f215e2d2878d773b55a370edb (diff) | |
Builtins with more than one parameter seemingly working
Diffstat (limited to 'src')
| -rw-r--r-- | src/builtins.rs | 66 | ||||
| -rw-r--r-- | src/runtime.rs | 10 |
2 files changed, 65 insertions, 11 deletions
diff --git a/src/builtins.rs b/src/builtins.rs index dbc17eb..b8b789f 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -4,6 +4,8 @@ use std::rc::Rc; pub const B_INTEGER_EQ0: &str = "int.eq0?"; pub const B_INTEGER_INCREMENT: &str = "int.increment"; +pub const B_INTEGER_ADD: &str = "int.add"; +pub const B_INTEGER_ADD_1: &str = "##int.add_1"; pub fn make_boolean_true_function() -> Term { let x = advance_v(); @@ -27,13 +29,18 @@ pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> { "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))), - B_INTEGER_INCREMENT => Some(Term::Builtin(String::from(B_INTEGER_INCREMENT))), + 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, } } -pub fn evaluate_builtin(symbol: &String, rhs: Rc<Term>) -> Result<(Rc<Term>, usize), String> { +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() { B_INTEGER_EQ0 => match &*rhs { Term::Primitive(primitive) => match primitive { @@ -46,24 +53,69 @@ pub fn evaluate_builtin(symbol: &String, rhs: Rc<Term>) -> Result<(Rc<Term>, usi } other => { return Err(format!( - "[runtime] cannot apply builtin {} to argument type {}", + "[runtime] cannot apply builtin {} to argument {}", symbol, other )) } }, - _ => return Ok((Rc::new(Term::Builtin(symbol.clone())), 0)), + _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)), }, B_INTEGER_INCREMENT => match &*rhs { Term::Primitive(primitive) => match primitive { Value::Integer(value) => Term::Primitive(Value::Integer(value + 1)), other => { return Err(format!( - "[runtime] cannot apply builtin {} to argument type {}", + "[runtime] cannot apply builtin {} to argument {}", symbol, other )) } }, - _ => return Ok((Rc::new(Term::Builtin(symbol.clone())), 0)), + _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)), + }, + B_INTEGER_ADD => match &*rhs { + Term::Primitive(primitive) => match primitive { + Value::Integer(_) => { + Term::Builtin(String::from(B_INTEGER_ADD_1), vec![primitive.clone()]) + } + other => { + return Err(format!( + "[runtime] cannot apply builtin {} to argument {}", + symbol, other + )) + } + }, + _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 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]; + match summand { + Value::Integer(summand_value) => { + Term::Primitive(Value::Integer(summand_value + value)) + } + other => { + return Err(format!( + "[runtime] cannot apply builtin {} to argument {}", + symbol, other + )) + } + } + } + other => { + return Err(format!( + "[runtime] cannot apply builtin {} to argument {}", + symbol, other + )) + } + }, + _ => { + return Ok(( + Rc::new(Term::Builtin(symbol.clone(), bound_arguments.clone())), + 0, + )) + } }, _ => return Err(format!("[runtime] invalid builtin evaluated: {}", symbol)), }; diff --git a/src/runtime.rs b/src/runtime.rs index 7e4e6f4..84f1820 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -27,7 +27,7 @@ pub enum Term { Application(Rc<Term>, Rc<Term>), Primitive(Value), Lazy(String), - Builtin(String), + Builtin(String, Vec<Value>), } impl Term { @@ -40,7 +40,7 @@ impl Term { Value::Integer(int_val) => format!("{}Integer({})", indent_str, int_val), Value::String(str_val) => format!("{}String({})", indent_str, str_val), }, - Term::Builtin(symbol) => format!("{}Builtin({})", indent_str, symbol), + Term::Builtin(symbol, _) => format!("{}Builtin({})", indent_str, symbol), Term::Abstraction(v, body) => format!( "{}Abstraction({})\n{}", indent_str, @@ -137,7 +137,9 @@ pub fn reduce_term( &Some((*abs_v, subst_rhs_rc)), resolve_lazy, ), - Term::Builtin(symbol) => builtins::evaluate_builtin(symbol, subst_rhs_rc), + Term::Builtin(symbol, bound_arguments) => { + builtins::evaluate_builtin(symbol, bound_arguments, subst_rhs_rc) + } _ => Ok(( Rc::new(Term::Application(subst_lhs_rc, subst_rhs_rc)), subst_n, @@ -155,7 +157,7 @@ pub fn reduce_term( )?; Ok((Rc::new(Term::Abstraction(*abs_v, subst_body)), subst_n)) } - Term::Builtin(_) => Ok((term_rc, 0)), + Term::Builtin(_, _) => Ok((term_rc, 0)), // Term::Lazy(symbol) => { // if resolve_lazy { // let table_lookup_value = symbol_table.get(symbol); |
