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