From cf3e54525f0b63adf9ab086bf03751ed232fb0b5 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Sun, 21 Nov 2021 21:33:45 +0200 Subject: Prepare ast for parameterized functions --- src/builtins.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/builtins.rs (limited to 'src/builtins.rs') diff --git a/src/builtins.rs b/src/builtins.rs new file mode 100644 index 0000000..351a652 --- /dev/null +++ b/src/builtins.rs @@ -0,0 +1,107 @@ +use super::ast; +use super::runtime; +use super::runtime::Value; +use std::rc::Rc; + +pub const B_INTEGER_INCREMENT: &str = "int.increment"; +pub const B_INTEGER_DECREMENT: &str = "int.decrement"; +pub const B_INTEGER_ADD: &str = "int.add"; +pub const B_INTEGER_MULTIPLY: &str = "int.multiply"; +pub const B_INTEGER_EQ: &str = "int.eq?"; + +#[derive(Debug, Clone)] +pub enum BuiltinFunction { + IntegerIncrement, + IntegerDecrement, + IntegerAdd, + IntegerAdd1(i64), + IntegerMultiply, + IntegerMultiply1(i64), + IntegerEq, + IntegerEq1(i64), +} + +pub fn try_builtin_symbol_to_value(symbol: &ast::Symbol) -> Option { + match symbol.as_str() { + "true" => Some(runtime::make_boolean_true_function()), + "false" => Some(runtime::make_boolean_false_function()), + "id" => Some(runtime::make_identity_function()), + B_INTEGER_INCREMENT => Some(Value::BuiltinFunction(BuiltinFunction::IntegerIncrement)), + B_INTEGER_DECREMENT => Some(Value::BuiltinFunction(BuiltinFunction::IntegerDecrement)), + B_INTEGER_ADD => Some(Value::BuiltinFunction(BuiltinFunction::IntegerAdd)), + B_INTEGER_MULTIPLY => Some(Value::BuiltinFunction(BuiltinFunction::IntegerMultiply)), + B_INTEGER_EQ => Some(Value::BuiltinFunction(BuiltinFunction::IntegerEq)), + _ => None, + } +} + +pub fn apply_builtin(builtin: &BuiltinFunction, arg: &Value) -> Rc { + match builtin { + BuiltinFunction::IntegerIncrement => match arg { + Value::Integer(value) => Rc::new(Value::Integer(value + 1)), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_INCREMENT + ), + }, + BuiltinFunction::IntegerDecrement => match arg { + Value::Integer(value) => Rc::new(Value::Integer(value - 1)), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_DECREMENT + ), + }, + BuiltinFunction::IntegerAdd => match arg { + Value::Integer(value) => { + Rc::new(Value::BuiltinFunction(BuiltinFunction::IntegerAdd1(*value))) + } + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_ADD + ), + }, + BuiltinFunction::IntegerAdd1(other) => match arg { + Value::Integer(value) => Rc::new(Value::Integer(other + value)), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_ADD + ), + }, + BuiltinFunction::IntegerMultiply => match arg { + Value::Integer(value) => Rc::new(Value::BuiltinFunction( + BuiltinFunction::IntegerMultiply1(*value), + )), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_MULTIPLY + ), + }, + BuiltinFunction::IntegerMultiply1(other) => match arg { + Value::Integer(value) => Rc::new(Value::Integer(other * value)), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_MULTIPLY + ), + }, + BuiltinFunction::IntegerEq => match arg { + Value::Integer(value) => { + Rc::new(Value::BuiltinFunction(BuiltinFunction::IntegerEq1(*value))) + } + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_EQ + ), + }, + BuiltinFunction::IntegerEq1(other) => match arg { + Value::Integer(value) => Rc::new(if other == value { + runtime::make_boolean_true_function() + } else { + runtime::make_boolean_false_function() + }), + _ => panic!( + "[runtime] tried to apply non-integer value to {}", + B_INTEGER_EQ + ), + }, + } +} -- cgit v1.3