diff --git a/src/compiler.rs b/src/compiler.rs index 1717374..509c5b9 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -705,8 +705,8 @@ impl StmtVisitor for Compiler<'_> { fn visit_if_stmt(&mut self, stmt: &IfStmt) -> Result<()> { // condition self.compile_expr(&stmt.condition)?; - // call obj.__bool__() - let bool_attr = self.insert_constant(self.create_str("__bool__"))?; + // call obj.to_bool() + let bool_attr = self.insert_constant(self.create_str("to_bool"))?; self.emit(expr_line_number(&*stmt.condition), Op::GetAttr(bool_attr)); self.emit(expr_line_number(&*stmt.condition), Op::Call(0)); let condition_patch_index = self.chunk().code.len(); @@ -778,7 +778,7 @@ impl ExprVisitor for Compiler<'_> { let mut exit_patch_index = 0; if let TokenKind::And | TokenKind::Or = expr.op.kind { - let constant_id = self.insert_constant(self.create_str("__bool__"))?; + let constant_id = self.insert_constant(self.create_str("to_bool"))?; self.emit(expr_line_number(&*expr.lhs), Op::GetAttr(constant_id)); self.emit(expr_line_number(&*expr.lhs), Op::Call(0)); exit_patch_index = self.chunk().code.len(); @@ -797,7 +797,7 @@ impl ExprVisitor for Compiler<'_> { // convert RHS to a bool if we're doing AND or OR if let TokenKind::And | TokenKind::Or = expr.op.kind { - let constant_id = self.insert_constant(self.create_str("__bool__"))?; + let constant_id = self.insert_constant(self.create_str("to_bool"))?; self.emit(expr_line_number(&*expr.rhs), Op::GetAttr(constant_id)); self.emit(expr_line_number(&*expr.rhs), Op::Call(0)); } diff --git a/src/obj.rs b/src/obj.rs index 75257e2..08a1876 100644 --- a/src/obj.rs +++ b/src/obj.rs @@ -97,7 +97,7 @@ pub fn init_types(builtins: &mut HashMap) { $( let vtable_name = stringify!($vtable_name); let vtable_value = $vtable_value; - with_obj_downcast_mut($name, |type_inst: &mut TypeInst| { + with_obj_downcast_mut($name.clone(), |type_inst: &mut TypeInst| { type_inst.vtable.insert(vtable_name.to_string(), vtable_value); }); )* @@ -110,7 +110,25 @@ pub fn init_types(builtins: &mut HashMap) { base_type: Type, // type definitions Type { + // Method conversion to_string => builtins.create_builtin_function("to_string", BaseObjInst::to_string, 1), + to_bool => builtins.create_builtin_function("to_bool", BaseObjInst::to_bool, 1), + // Operators + __add__ => builtins.create_builtin_function("__add__", BaseObjInst::add, 2), + __sub__ => builtins.create_builtin_function("__sub__", BaseObjInst::sub, 2), + __mul__ => builtins.create_builtin_function("__mul__", BaseObjInst::mul, 2), + __div__ => builtins.create_builtin_function("__div__", BaseObjInst::div, 2), + __and__ => builtins.create_builtin_function("__and__", BaseObjInst::and, 2), + __or__ => builtins.create_builtin_function("__or__", BaseObjInst::or, 2), + __ne__ => builtins.create_builtin_function("__ne__", BaseObjInst::ne, 2), + __eq__ => builtins.create_builtin_function("__eq__", BaseObjInst::eq, 2), + __gt__ => builtins.create_builtin_function("__gt__", BaseObjInst::gt, 2), + __ge__ => builtins.create_builtin_function("__ge__", BaseObjInst::ge, 2), + __lt__ => builtins.create_builtin_function("__lt__", BaseObjInst::lt, 2), + __le__ => builtins.create_builtin_function("__le__", BaseObjInst::le, 2), + __pos__ => builtins.create_builtin_function("__pos__", BaseObjInst::pos, 1), + __neg__ => builtins.create_builtin_function("__neg__", BaseObjInst::neg, 1), + __not__ => builtins.create_builtin_function("__not__", BaseObjInst::not, 1), }, Obj { }, Str { }, @@ -301,7 +319,75 @@ struct BaseObjInst { is_instantiated: bool, } +// +// Base function implementations +// + impl BaseObjInst { + fn add(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __add__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn sub(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __sub__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn mul(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __mul__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn div(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __div__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn and(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __and__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn or(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __or__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn ne(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __ne__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn eq(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __eq__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn gt(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __gt__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn ge(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __ge__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn lt(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __lt__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn le(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __le__ function (self: {:?}, rhs: {:?})", args[0].borrow(), args[1].borrow()) + } + + fn pos(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __pos__ function (self: {:?})", args[0].borrow()) + } + + fn neg(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __neg__ function (self: {:?})", args[0].borrow()) + } + + fn not(_vm: &mut Vm, args: Vec) -> ObjP { + todo!("Raise some kind of not implemented/not callable error for __not__ function (self: {:?})", args[0].borrow()) + } + + fn to_bool(vm: &mut Vm, args: Vec) -> ObjP { + vm.create_bool(args[0].borrow().is_truthy()) + } + fn to_string(vm: &mut Vm, args: Vec) -> ObjP { let str_value = format!("{}", &args[0].borrow()); vm.create_str(str_value)