diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2021-11-24 22:47:23 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2021-11-25 09:53:55 +0200 |
| commit | 7f9207d9742c062c2a23ca53aa48420217558e7a (patch) | |
| tree | ffcc15beb0c26245c8aefd65b6206ce30df370ec /src/builtins.rs | |
| parent | 1baf725a38b90c13e5afacebd18fb3799a2bd081 (diff) | |
Recursion working oh yes
Diffstat (limited to 'src/builtins.rs')
| -rw-r--r-- | src/builtins.rs | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/builtins.rs b/src/builtins.rs index d0f5788..390a213 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -84,8 +84,11 @@ pub fn make_identity_function() -> Term { } pub const B_INTEGER_EQ: &str = "int.eq?"; -pub const B_INTEGER_INCREMENT: &str = "int.increment"; +pub const B_INTEGER_INCREMENT: &str = "int.inc"; pub const B_INTEGER_ADD: &str = "int.add"; +pub const B_INTEGER_SUBTRACT: &str = "int.sub"; +pub const B_INTEGER_MULTIPLY: &str = "int.mul"; +pub const B_INTEGER_DIVIDE: &str = "int.div"; pub const B_STRING_EQ: &str = "string.eq?"; pub const B_BOOL_TO_STRING: &str = "bool.to-string"; @@ -97,6 +100,9 @@ pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> { B_INTEGER_EQ => Builtin::new(B_INTEGER_EQ, 2), B_INTEGER_INCREMENT => Builtin::new(B_INTEGER_INCREMENT, 1), B_INTEGER_ADD => Builtin::new(B_INTEGER_ADD, 2), + B_INTEGER_SUBTRACT => Builtin::new(B_INTEGER_SUBTRACT, 2), + B_INTEGER_MULTIPLY => Builtin::new(B_INTEGER_MULTIPLY, 2), + B_INTEGER_DIVIDE => Builtin::new(B_INTEGER_DIVIDE, 2), B_STRING_EQ => Builtin::new(B_STRING_EQ, 2), B_BOOL_TO_STRING => Builtin::new(B_BOOL_TO_STRING, 1), _ => return None, @@ -130,7 +136,46 @@ pub fn evaluate_builtin(builtin: &Builtin, rhs: Rc<Term>) -> Result<(Rc<Term>, u 2 => Term::Builtin(builtin.bind_arg(primitive)), 1 => { let other_value = extract_enum_value!(&builtin.arguments[0], Value::Integer(other_value) => other_value); - Term::Primitive(Value::Integer(value + other_value)) + Term::Primitive(Value::Integer(other_value + value)) + } + _ => return argument_n_error(builtin.identifier, builtin.n_arguments), + }, + Term::Primitive(_) => return argument_type_error(builtin.identifier, &*rhs), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), + }, + B_INTEGER_SUBTRACT => match &*rhs { + Term::Primitive(primitive @ Value::Integer(value)) => match builtin.n_arguments { + 2 => Term::Builtin(builtin.bind_arg(primitive)), + 1 => { + let other_value = extract_enum_value!(&builtin.arguments[0], Value::Integer(other_value) => other_value); + Term::Primitive(Value::Integer(other_value - value)) + } + _ => return argument_n_error(builtin.identifier, builtin.n_arguments), + }, + Term::Primitive(_) => return argument_type_error(builtin.identifier, &*rhs), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), + }, + B_INTEGER_MULTIPLY => match &*rhs { + Term::Primitive(primitive @ Value::Integer(value)) => match builtin.n_arguments { + 2 => Term::Builtin(builtin.bind_arg(primitive)), + 1 => { + let other_value = extract_enum_value!(&builtin.arguments[0], Value::Integer(other_value) => other_value); + Term::Primitive(Value::Integer(other_value * value)) + } + _ => return argument_n_error(builtin.identifier, builtin.n_arguments), + }, + Term::Primitive(_) => return argument_type_error(builtin.identifier, &*rhs), + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), + }, + B_INTEGER_DIVIDE => match &*rhs { + Term::Primitive(primitive @ Value::Integer(value)) => match builtin.n_arguments { + 2 => Term::Builtin(builtin.bind_arg(primitive)), + 1 => { + if *value == 0 { + return Err("[runtime] divide by zero".to_owned()); + } + let other_value = extract_enum_value!(&builtin.arguments[0], Value::Integer(other_value) => other_value); + Term::Primitive(Value::Integer(other_value / value)) } _ => return argument_n_error(builtin.identifier, builtin.n_arguments), }, |
