From 69431c4926a5aced585ed3c7149d19824f026280 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Sun, 16 Jan 2022 19:22:02 -0800 Subject: [PATCH] Add vm::builtins mod as a place for builtin functions to live Signed-off-by: Alek Ratzloff --- src/vm/builtins.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++ src/vm/machine.rs | 58 ++++---------------------------- src/vm/mod.rs | 1 + 3 files changed, 90 insertions(+), 52 deletions(-) create mode 100644 src/vm/builtins.rs diff --git a/src/vm/builtins.rs b/src/vm/builtins.rs new file mode 100644 index 0000000..037d9d6 --- /dev/null +++ b/src/vm/builtins.rs @@ -0,0 +1,83 @@ +use crate::object::{BuiltinExit, Int, Value}; +use crate::vm::{error::RuntimeError, machine::MachineBuilder}; + +impl MachineBuilder { + /// Registers all builtins for calling on the machine. + pub(super) fn register_builtins(&mut self) { + self.scope_stack.push_scope(); + + // + // panic + // + self.register_builtin_fun("panic", |machine, _| { + println!("!!! panic"); + println!("!!! top of stack"); + for (i, value) in machine.stack().iter().enumerate().rev() { + println!("!!! {}. {:?}", i, value); + } + println!("!!! bottom of stack"); + panic!(); + }); + + // + // if + // + self.register_builtin_fun("if", |machine, _| { + let if_false = machine.stack_pop()?; + let if_true = machine.stack_pop()?; + let condition = machine.stack_pop()?; + let value = if condition.is_truthy() { + if_true + } else { + if_false + }; + + if let Value::Quote(quote) = value { + Ok(BuiltinExit::Call(quote)) + } else { + return Err(RuntimeError::CannotCall( + "if statement requires quote value".to_string(), + ) + .into()); + } + }); + + // + // print + // + self.register_builtin_fun("print", |machine, _| { + let value = machine.stack_pop()?; + print!("{}", value); + Ok(BuiltinExit::Return) + }); + + // + // println + // + self.register_builtin_fun("println", |machine, _| { + let value = machine.stack_pop()?; + println!("{}", value); + Ok(BuiltinExit::Return) + }); + + // + // == + // + self.register_builtin_fun("==", |machine, _| { + let rhs = machine.stack_pop()?; + let lhs = machine.stack_pop()?; + machine.stack_push(Value::Int((lhs == rhs) as Int))?; + Ok(BuiltinExit::Return) + }); + + // + // ~= + // + self.register_builtin_fun("~=", |machine, _| { + let rhs = machine.stack_pop()?; + let lhs = machine.stack_pop()?; + machine.stack_push(Value::Int((lhs != rhs) as Int))?; + Ok(BuiltinExit::Return) + }); + } +} diff --git a/src/vm/machine.rs b/src/vm/machine.rs index da1c89b..96ee3e5 100644 --- a/src/vm/machine.rs +++ b/src/vm/machine.rs @@ -318,10 +318,10 @@ impl Machine { #[derive(Debug, Default)] pub struct MachineBuilder { - globals: BTreeMap, - scope_stack: ScopeStack, - max_stack_size: Option, - max_arena_objects: Option, + pub(super) globals: BTreeMap, + pub(super) scope_stack: ScopeStack, + pub(super) max_stack_size: Option, + pub(super) max_arena_objects: Option, } impl MachineBuilder { @@ -335,53 +335,7 @@ impl MachineBuilder { self } - /// Registers all builtins for calling on the machine. - fn register_builtins(&mut self) { - self.scope_stack.push_scope(); - self.register_builtin_fun("panic", |machine, _| { - println!("!!! panic"); - println!("!!! top of stack"); - for (i, value) in machine.stack().iter().enumerate().rev() { - println!("!!! {}. {:?}", i, value); - } - println!("!!! bottom of stack"); - panic!(); - }); - - self.register_builtin_fun("if", |machine, _| { - let if_false = machine.stack_pop()?; - let if_true = machine.stack_pop()?; - let condition = machine.stack_pop()?; - let value = if condition.is_truthy() { - if_true - } else { - if_false - }; - - if let Value::Quote(quote) = value { - Ok(BuiltinExit::Call(quote)) - } else { - return Err(RuntimeError::CannotCall( - "if statement requires quote value".to_string(), - ) - .into()); - } - }); - - self.register_builtin_fun("print", |machine, _| { - let value = machine.stack_pop()?; - print!("{}", value); - Ok(BuiltinExit::Return) - }); - - self.register_builtin_fun("println", |machine, _| { - let value = machine.stack_pop()?; - println!("{}", value); - Ok(BuiltinExit::Return) - }); - } - - fn register_builtin_fun( + pub(super) fn register_builtin_fun( &mut self, name: &str, fun: fn(&mut Machine, usize) -> Result, @@ -392,7 +346,7 @@ impl MachineBuilder { ); } - fn register_global(&mut self, name: &str, value: Value) { + pub(super) fn register_global(&mut self, name: &str, value: Value) { let word = self.scope_stack.insert_local(name); self.globals.insert(word, value); } diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 0dff4e1..b5c3770 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -1,3 +1,4 @@ +mod builtins; pub mod error; pub mod inst; pub mod machine;