Implement IntInst methods

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-09-24 16:57:22 -07:00
parent 890467e02c
commit c8d670ba59
3 changed files with 116 additions and 3 deletions

View File

@@ -187,7 +187,7 @@ impl BaseObjInst {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// StringInst implementations // StrInst implementations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
impl StrInst { impl StrInst {
pub(crate) fn to_str(_vm: &mut Vm, _state: FunctionState) -> FunctionResult { pub(crate) fn to_str(_vm: &mut Vm, _state: FunctionState) -> FunctionResult {
@@ -244,3 +244,102 @@ impl StrInst {
vm.create_str(new).into() vm.create_str(new).into()
} }
} }
////////////////////////////////////////////////////////////////////////////////
// IntInst implementations
////////////////////////////////////////////////////////////////////////////////
macro_rules! bin_op_math {
($function:ident, $op:tt) => {
pub(crate) fn $function(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let lhs = vm.frame_stack()[0].clone();
let rhs = vm.frame_stack()[1].clone();
let lhs_value = with_obj_downcast(lhs, IntInst::int_value);
let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::<IntInst>() {
vm.create_int(lhs_value $op int_inst.int_value())
} else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::<FloatInst>() {
vm.create_float(lhs_value as f64 $op float_inst.float_value())
} else {
todo!(
concat!("cannot use '", stringify!($op), "' operator with Int and {}"),
rhs.borrow().type_name()
)
};
result.into()
}
}
}
macro_rules! bin_op_logical {
($function:ident, $op:tt) => {
pub(crate) fn $function(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let lhs = vm.frame_stack()[0].clone();
let rhs = vm.frame_stack()[1].clone();
let lhs_value = with_obj_downcast(lhs, IntInst::int_value);
let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::<IntInst>() {
vm.create_bool(lhs_value $op int_inst.int_value())
} else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::<FloatInst>() {
vm.create_bool((lhs_value as f64) $op float_inst.float_value())
} else {
todo!(
concat!("cannot use '", stringify!($op), "' operator with Int and {}"),
rhs.borrow().type_name()
)
};
result.into()
}
}
}
impl IntInst {
bin_op_math!(add, +);
bin_op_math!(sub, -);
pub(crate) fn mul(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
// can't bin_op_math this one because it needs the string case
let lhs = vm.frame_stack()[0].clone();
let rhs = vm.frame_stack()[1].clone();
let lhs_value = with_obj_downcast(lhs, IntInst::int_value);
let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::<IntInst>() {
vm.create_int(lhs_value * int_inst.int_value())
} else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::<FloatInst>() {
vm.create_float(lhs_value as f64 * float_inst.float_value())
} else if let Some(str_inst) = rhs.borrow().as_any().downcast_ref::<StrInst>() {
vm.create_str(str_inst.str_value().repeat(lhs_value as usize))
} else {
todo!(
"cannot use '*' operator with Int and {}",
rhs.borrow().type_name()
)
};
result.into()
}
// TODO IntInst::div - handle divide by zero
// BLOCKED-ON: exceptions
// NOTE - we will probably need to get rid of the macro here to handle that :(
bin_op_math!(div, /);
bin_op_logical!(gt, >);
bin_op_logical!(ge, >=);
bin_op_logical!(lt, <);
bin_op_logical!(le, <=);
pub(crate) fn pos(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let lhs = vm.frame_stack()[0].clone();
let value = with_obj_downcast(lhs, IntInst::int_value);
vm.create_int(value.abs()).into()
}
pub(crate) fn neg(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let lhs = vm.frame_stack()[0].clone();
let value = with_obj_downcast(lhs, IntInst::int_value);
vm.create_int(-value).into()
}
}

View File

@@ -146,7 +146,19 @@ pub fn init_types(builtins: &mut HashMap<String, ObjP>) {
__add__ => builtins.create_builtin_function("__add__", StrInst::add, 2), __add__ => builtins.create_builtin_function("__add__", StrInst::add, 2),
__mul__ => builtins.create_builtin_function("__mul__", StrInst::mul, 2), __mul__ => builtins.create_builtin_function("__mul__", StrInst::mul, 2),
}, },
Int { }, Int {
// Operators
__add__ => builtins.create_builtin_function("__add__", IntInst::add, 2),
__sub__ => builtins.create_builtin_function("__sub__", IntInst::sub, 2),
__mul__ => builtins.create_builtin_function("__mul__", IntInst::mul, 2),
__div__ => builtins.create_builtin_function("__div__", IntInst::div, 2),
__gt__ => builtins.create_builtin_function("__gt__", IntInst::gt, 2),
__ge__ => builtins.create_builtin_function("__ge__", IntInst::ge, 2),
__lt__ => builtins.create_builtin_function("__lt__", IntInst::lt, 2),
__le__ => builtins.create_builtin_function("__le__", IntInst::le, 2),
__pos__ => builtins.create_builtin_function("__pos__", IntInst::pos, 2),
__neg__ => builtins.create_builtin_function("__neg__", IntInst::neg, 2),
},
Float { }, Float { },
Bool { }, Bool { },
Nil { }, Nil { },

View File

@@ -265,7 +265,9 @@ impl Vm {
let method_type = self.builtins().get("Method").unwrap().clone(); let method_type = self.builtins().get("Method").unwrap().clone();
loop { loop {
match self.dispatch() { let op = self.dispatch();
match op {
Op::Pop => { Op::Pop => {
self.pop(); self.pop();
} }