Move to VTableBuilder for IntObj VTable, add __splat__ impl

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2022-02-04 18:43:55 -08:00
parent 9e5b1b3176
commit 3b034052e5

View File

@@ -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::<IntObj>();
let rhs = rhs_ptr.as_any().downcast_ref::<IntObj>();
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::<IntObj>() {
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::<IntObj>() {
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<Self> {
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::<IntObj>() {
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::<IntObj>() {
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,