Implement IntInst methods
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
101
src/builtins.rs
101
src/builtins.rs
@@ -187,7 +187,7 @@ impl BaseObjInst {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// StringInst implementations
|
||||
// StrInst implementations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
impl StrInst {
|
||||
pub(crate) fn to_str(_vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
@@ -244,3 +244,102 @@ impl StrInst {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
14
src/obj.rs
14
src/obj.rs
@@ -146,7 +146,19 @@ pub fn init_types(builtins: &mut HashMap<String, ObjP>) {
|
||||
__add__ => builtins.create_builtin_function("__add__", StrInst::add, 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 { },
|
||||
Bool { },
|
||||
Nil { },
|
||||
|
||||
Reference in New Issue
Block a user