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 {
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
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),
|
__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 { },
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user