From 3b034052e589d243c487c6e7a95d2ed23b52ac90 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Fri, 4 Feb 2022 18:43:55 -0800 Subject: [PATCH] Move to VTableBuilder for IntObj VTable, add __splat__ impl Signed-off-by: Alek Ratzloff --- src/obj/int.rs | 73 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/src/obj/int.rs b/src/obj/int.rs index 849c7ca..600a052 100644 --- a/src/obj/int.rs +++ b/src/obj/int.rs @@ -11,34 +11,55 @@ pub struct IntObj { vtable: VTable, } +thread_local! { + static VTABLE: VTable = VTableBuilder::default() + .with_builtin("__splat__", |machine, _| { + let rhs_ptr: ObjPtr = machine.stack_pop()?; + let lhs_ptr: ObjPtr = machine.stack_pop()?; + let lhs = lhs_ptr.as_any().downcast_ref::(); + let rhs = rhs_ptr.as_any().downcast_ref::(); + match (lhs, rhs) { + (Some(lhs), Some(rhs)) => { + let result = IntObj::new(lhs.value() * rhs.value()); + machine.stack_push(result)?; + Ok(BuiltinExit::Return) + } + (Some(_lhs), None) => { + Err(RuntimeError::WrongValue("int value (rhs)".to_string())) + }, + (None, Some(_rhs)) => { + Err(RuntimeError::WrongValue("int value (lhs)".to_string())) + } + (None, None) => { panic!("called an int builtin with no int values at all"); } + } + }) + .with_builtin("__bool__", |machine, _| { + let obj_ptr: ObjPtr = machine.stack_pop()?; + let obj: &(dyn Obj + 'static) = &*obj_ptr; + if let Some(int) = obj.as_any().downcast_ref::() { + let bool_ = BoolObj::new(int.value != 0); + machine.stack_push(bool_)?; + Ok(BuiltinExit::Return) + } else { + Err(RuntimeError::WrongValue("int".to_string())) + } + }) + .with_builtin("__str__", |machine, _| { + let obj_ptr: ObjPtr = machine.stack_pop()?; + let obj: &(dyn Obj + 'static) = &*obj_ptr; + if let Some(int) = obj.as_any().downcast_ref::() { + let string = StrObj::new(int.value.to_string()); + machine.stack_push(string)?; + Ok(BuiltinExit::Return) + } else { + Err(RuntimeError::WrongValue("int".to_string())) + } + }) + .finish(); +} + impl IntObj { pub fn new(value: Int) -> Gc { - thread_local! { - static VTABLE: VTable = vtable! { - "__bool__" => builtin_fn!("__bool__", |machine, _| { - let obj_ptr: ObjPtr = machine.stack_pop()?; - let obj: &(dyn Obj + 'static) = &*obj_ptr; - if let Some(int) = obj.as_any().downcast_ref::() { - let bool_ = BoolObj::new(int.value != 0); - machine.stack_push(bool_)?; - Ok(BuiltinExit::Return) - } else { - Err(RuntimeError::WrongValue("int".to_string())) - } - }), - "__str__" => builtin_fn!("__str__", |machine, _| { - let obj_ptr: ObjPtr = machine.stack_pop()?; - let obj: &(dyn Obj + 'static) = &*obj_ptr; - if let Some(int) = obj.as_any().downcast_ref::() { - let string = StrObj::new(int.value.to_string()); - machine.stack_push(string)?; - Ok(BuiltinExit::Return) - } else { - Err(RuntimeError::WrongValue("int".to_string())) - } - }), - }; - }; // TODO : intern int value Gc::new(IntObj { value,