2024-09-24 09:03:34 -07:00
|
|
|
macro_rules! impl_base_obj {
|
2024-09-25 10:22:03 -07:00
|
|
|
($base_name:ident, $type_name:ident) => {
|
|
|
|
|
fn instantiate(&mut self) {
|
|
|
|
|
let ty = $crate::obj::BUILTINS.with_borrow(|builtins| {
|
|
|
|
|
builtins
|
|
|
|
|
.get(stringify!($type_name))
|
|
|
|
|
.expect(concat!("no ", stringify!($type_name)))
|
|
|
|
|
.clone()
|
|
|
|
|
});
|
2024-09-26 11:07:12 -07:00
|
|
|
self.set_attr("__ty__", ty);
|
2024-09-25 10:22:03 -07:00
|
|
|
self.$base_name.instantiate();
|
2024-09-24 09:03:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn is_instantiated(&self) -> bool {
|
|
|
|
|
self.$base_name.is_instantiated()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn attrs(&self) -> &$crate::obj::Attrs {
|
|
|
|
|
self.$base_name.attrs()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn attrs_mut(&mut self) -> &mut $crate::obj::Attrs {
|
|
|
|
|
self.$base_name.attrs_mut()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn as_any(&self) -> &dyn std::any::Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-09-25 10:22:03 -07:00
|
|
|
($type_name:ident) => {
|
|
|
|
|
impl_base_obj! { base, $type_name }
|
2024-09-24 09:03:34 -07:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! impl_create {
|
|
|
|
|
($($arg:ident : $ty:ty),* $(,)?) => {
|
2024-09-30 15:15:41 -07:00
|
|
|
// TODO - obj::macros::impl_create - remove this #[allow(dead_code)] designator
|
|
|
|
|
#[allow(dead_code)]
|
2024-09-25 10:22:03 -07:00
|
|
|
pub fn create($($arg : $ty ),*) -> $crate::obj::ObjP {
|
2024-09-30 15:15:41 -07:00
|
|
|
let ptr = $crate::obj::make_ptr(Self::new($($arg),*));
|
2024-09-25 10:22:03 -07:00
|
|
|
ptr.borrow_mut().instantiate();
|
2024-09-24 09:03:34 -07:00
|
|
|
ptr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 15:15:41 -07:00
|
|
|
macro_rules! impl_do_call {
|
|
|
|
|
($name:ident) => {
|
|
|
|
|
pub(crate) fn do_call(
|
|
|
|
|
vm: &mut $crate::vm::Vm,
|
|
|
|
|
state: $crate::obj::function::FunctionState,
|
|
|
|
|
) -> $crate::obj::function::FunctionResult {
|
|
|
|
|
match state {
|
|
|
|
|
$crate::obj::function::FunctionState::Begin => {
|
|
|
|
|
// get the top item off the stack and call to_float on it
|
|
|
|
|
let arg = vm.peek();
|
|
|
|
|
let method = if let Some(method) =
|
|
|
|
|
arg.borrow().get_vtable_attr(arg.clone(), stringify!($name))
|
|
|
|
|
{
|
|
|
|
|
method
|
|
|
|
|
} else {
|
|
|
|
|
// TODO builtins::do_call - throw exception when target doesn't have a
|
|
|
|
|
// to_$name method
|
|
|
|
|
// BLOCKED-ON: exceptions
|
|
|
|
|
todo!(
|
|
|
|
|
concat!("{} does not have a ", stringify!($name), " method"),
|
|
|
|
|
arg.borrow().ty_name()
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
vm.push(method.clone());
|
|
|
|
|
method.borrow().call(vm, 0);
|
|
|
|
|
|
|
|
|
|
// resume execution
|
|
|
|
|
$crate::obj::function::FunctionResult::Yield(0)
|
|
|
|
|
}
|
|
|
|
|
$crate::obj::function::FunctionState::Resume(0) => {
|
|
|
|
|
$crate::obj::function::FunctionResult::Return
|
|
|
|
|
}
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-24 09:03:34 -07:00
|
|
|
pub(crate) use impl_base_obj;
|
|
|
|
|
pub(crate) use impl_create;
|
2024-09-30 15:15:41 -07:00
|
|
|
pub(crate) use impl_do_call;
|