Move builtin object methods from src/obj.rs to src/builtins.rs

Builtin functions are now living in the builtins file. They're still
part of BaseObjInst but they just are in a different file. Also,
implement the base "not" function.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-09-24 11:50:51 -07:00
parent 3a7c04686a
commit 4b5d2af117
3 changed files with 111 additions and 91 deletions

View File

@@ -5,6 +5,25 @@ use crate::obj::function::{FunctionResult, FunctionState};
use crate::obj::*;
use crate::vm::Vm;
pub fn init_global_builtins(builtins: &mut HashMap<String, ObjP>) {
macro_rules! builtins {
($($builtin:ident / $argc:expr),* $(,)?) => {
$({
let builtin_function = builtins.create_builtin_function(stringify!($builtin), $builtin, $argc);
builtins.insert(
stringify!($builtin).to_string(),
builtin_function
);
})*
}
}
builtins! {
print/1,
println/1,
}
}
// TODO builtins.rs - need a good macro to help reduce this repetition.
// The main problem is that "macros cannot expand to match arms".
// Thus, if we try to do something like this:
@@ -15,6 +34,10 @@ use crate::vm::Vm;
//
// This would probably be doable in a procedural macro.
////////////////////////////////////////////////////////////////////////////////
// Global functions
////////////////////////////////////////////////////////////////////////////////
pub(crate) fn println(vm: &mut Vm, state: FunctionState) -> FunctionResult {
match state {
FunctionState::Begin => {
@@ -55,21 +78,94 @@ pub(crate) fn print(vm: &mut Vm, state: FunctionState) -> FunctionResult {
}
}
pub fn init_builtins(builtins: &mut HashMap<String, ObjP>) {
macro_rules! builtins {
($($builtin:ident / $argc:expr),* $(,)?) => {
$({
let builtin_function = builtins.create_builtin_function(stringify!($builtin), $builtin, $argc);
builtins.insert(
stringify!($builtin).to_string(),
builtin_function
);
})*
//
// Base function implementations
//
impl BaseObjInst {
pub(crate) fn add(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __add__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn sub(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __sub__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn mul(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __mul__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn div(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __div__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn and(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __and__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn or(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __or__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn ne(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __ne__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn eq(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __eq__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn gt(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __gt__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn ge(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __ge__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn lt(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __lt__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn le(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __le__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
pub(crate) fn pos(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __pos__ function (self: {:?})", vm.frame_stack()[0].borrow())
}
pub(crate) fn neg(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __neg__ function (self: {:?})", vm.frame_stack()[0].borrow())
}
pub(crate) fn not(vm: &mut Vm, state: FunctionState) -> FunctionResult {
match state {
FunctionState::Begin => {
let obj = vm.peek();
let method_type = vm.builtins().get("Method").unwrap().clone();
let to_bool = obj
.borrow_mut()
.get_attr_lazy(obj.clone(), method_type, "to_bool")
.expect("no to_bool");
to_bool.borrow().call(vm, 0);
FunctionResult::Yield(0)
}
FunctionState::Resume(0) => {
let value = vm.peek().borrow().is_truthy();
vm.create_bool(!value).into()
}
_ => unreachable!(),
}
}
builtins! {
print/1,
println/1,
pub(crate) fn to_bool(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
vm.create_bool(vm.frame_stack()[0].borrow().is_truthy())
.into()
}
pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let str_value = format!("{}", vm.frame_stack()[0].borrow());
vm.create_str(str_value).into()
}
}

View File

@@ -56,7 +56,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// initialize type system
let mut builtins = HashMap::new();
obj::init_types(&mut builtins);
crate::builtins::init_builtins(&mut builtins);
crate::builtins::init_global_builtins(&mut builtins);
// compile
let (chunk, constants, globals) = compiler::Compiler::new(&builtins).compile(&ast)?;

View File

@@ -324,87 +324,11 @@ pub trait Obj: Debug + Display + Any + Trace {
////////////////////////////////////////////////////////////////////////////////
#[derive(Debug, Default, Trace)]
struct BaseObjInst {
pub(crate) struct BaseObjInst {
attrs: Attrs,
is_instantiated: bool,
}
//
// Base function implementations
//
impl BaseObjInst {
fn add(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __add__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn sub(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __sub__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn mul(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __mul__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn div(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __div__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn and(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __and__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn or(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __or__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn ne(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __ne__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn eq(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __eq__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn gt(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __gt__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn ge(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __ge__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn lt(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __lt__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn le(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __le__ function (self: {:?}, rhs: {:?})", vm.frame_stack()[0].borrow(), vm.frame_stack()[1].borrow())
}
fn pos(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __pos__ function (self: {:?})", vm.frame_stack()[0].borrow())
}
fn neg(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __neg__ function (self: {:?})", vm.frame_stack()[0].borrow())
}
fn not(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
todo!("Raise some kind of not implemented/not callable error for __not__ function (self: {:?})", vm.frame_stack()[0].borrow())
}
fn to_bool(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
vm.create_bool(vm.frame_stack()[0].borrow().is_truthy())
.into()
}
fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let str_value = format!("{}", vm.frame_stack()[0].borrow());
vm.create_str(str_value).into()
}
}
impl Finalize for BaseObjInst {
fn finalize(&self) {}
}