Add vm::builtins mod as a place for builtin functions to live

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2022-01-16 19:22:02 -08:00
parent 4cf377ff1e
commit 69431c4926
3 changed files with 90 additions and 52 deletions

83
src/vm/builtins.rs Normal file
View File

@@ -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)
});
}
}

View File

@@ -318,10 +318,10 @@ impl Machine {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct MachineBuilder { pub struct MachineBuilder {
globals: BTreeMap<Word, Value>, pub(super) globals: BTreeMap<Word, Value>,
scope_stack: ScopeStack, pub(super) scope_stack: ScopeStack,
max_stack_size: Option<usize>, pub(super) max_stack_size: Option<usize>,
max_arena_objects: Option<usize>, pub(super) max_arena_objects: Option<usize>,
} }
impl MachineBuilder { impl MachineBuilder {
@@ -335,53 +335,7 @@ impl MachineBuilder {
self self
} }
/// Registers all builtins for calling on the machine. pub(super) fn register_builtin_fun(
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(
&mut self, &mut self,
name: &str, name: &str,
fun: fn(&mut Machine, usize) -> Result<BuiltinExit>, fun: fn(&mut Machine, usize) -> Result<BuiltinExit>,
@@ -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); let word = self.scope_stack.insert_local(name);
self.globals.insert(word, value); self.globals.insert(word, value);
} }

View File

@@ -1,3 +1,4 @@
mod builtins;
pub mod error; pub mod error;
pub mod inst; pub mod inst;
pub mod machine; pub mod machine;