diff --git a/src/builtins.rs b/src/builtins.rs index fb1cb9e..eaa4f10 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -1,5 +1,5 @@ //! Builtin functions. -use crate::obj::function::{BuiltinFunctionInst, FunctionResult, FunctionState}; +use crate::obj::function::{BuiltinFunction, FunctionResult, FunctionState}; use crate::obj::*; use crate::vm::Vm; @@ -7,7 +7,7 @@ pub fn init_global_builtins() { macro_rules! builtins { ($($builtin:ident / $argc:expr),* $(,)?) => { $({ - let builtin_function = BuiltinFunctionInst::create(stringify!($builtin), $builtin, $argc); + let builtin_function = BuiltinFunction::create(stringify!($builtin), $builtin, $argc); $crate::obj::BUILTINS.with_borrow_mut(|builtins| builtins.insert( stringify!($builtin).to_string(), @@ -50,7 +50,7 @@ pub(crate) fn println(vm: &mut Vm, state: FunctionState) -> FunctionResult { } FunctionState::Resume(0) => { println!("{}", vm.frame_stack()[0].borrow()); - NilInst::create().into() + Nil::create().into() } _ => unreachable!(), } @@ -69,17 +69,17 @@ pub(crate) fn print(vm: &mut Vm, state: FunctionState) -> FunctionResult { } FunctionState::Resume(0) => { print!("{}", vm.frame_stack()[0].borrow()); - NilInst::create().into() + Nil::create().into() } _ => unreachable!(), } } //////////////////////////////////////////////////////////////////////////////// -// BaseObjInst implementations +// BaseObj implementations //////////////////////////////////////////////////////////////////////////////// -impl BaseObjInst { +impl BaseObj { // // Common functions // @@ -103,11 +103,11 @@ impl BaseObjInst { pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let str_value = format!("{}", vm.frame_stack()[0].borrow()); - StrInst::create(str_value).into() + Str::create(str_value).into() } pub(crate) fn to_bool(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - BoolInst::create(vm.frame_stack()[0].borrow().is_truthy()).into() + Bool::create(vm.frame_stack()[0].borrow().is_truthy()).into() } // @@ -118,14 +118,14 @@ impl BaseObjInst { let lhs = vm.frame_stack()[0].borrow(); let rhs = vm.frame_stack()[1].borrow(); let result = lhs.is_truthy() && rhs.is_truthy(); - BoolInst::create(result).into() + Bool::create(result).into() } pub(crate) fn or(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let lhs = vm.frame_stack()[0].borrow(); let rhs = vm.frame_stack()[1].borrow(); let result = lhs.is_truthy() || rhs.is_truthy(); - BoolInst::create(result).into() + Bool::create(result).into() } pub(crate) fn ne(vm: &mut Vm, state: FunctionState) -> FunctionResult { @@ -145,7 +145,7 @@ impl BaseObjInst { } FunctionState::Resume(0) => { let result = !vm.peek().borrow().is_truthy(); - BoolInst::create(result).into() + Bool::create(result).into() } _ => { unreachable!() @@ -157,7 +157,7 @@ impl BaseObjInst { let lhs = vm.frame_stack()[0].borrow(); let rhs = vm.frame_stack()[1].borrow(); let equals = lhs.equals(&*rhs); - BoolInst::create(equals).into() + Bool::create(equals).into() } pub(crate) fn not(vm: &mut Vm, state: FunctionState) -> FunctionResult { @@ -173,7 +173,7 @@ impl BaseObjInst { } FunctionState::Resume(0) => { let value = vm.peek().borrow().is_truthy(); - BoolInst::create(!value).into() + Bool::create(!value).into() } _ => unreachable!(), } @@ -185,7 +185,7 @@ impl BaseObjInst { pub(crate) fn not_implemented_un(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let fname = &vm.frame().name; - // TODO BaseObjInst::not_implemented_un - throw an exception of some kind for not + // TODO BaseObj::not_implemented_un - throw an exception of some kind for not // implemented/not available errors on unary operators // BLOCKED-ON: exceptions todo!( @@ -196,7 +196,7 @@ impl BaseObjInst { } pub(crate) fn not_implemented_bin(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - // TODO BaseObjInst::not_implemented_un - throw an exception of some kind for not + // TODO BaseObj::not_implemented_un - throw an exception of some kind for not // implemented/not available errors on unary operators // BLOCKED-ON: exceptions let fname = &vm.frame().name; @@ -205,30 +205,29 @@ impl BaseObjInst { } //////////////////////////////////////////////////////////////////////////////// -// StrInst implementations +// Str implementations //////////////////////////////////////////////////////////////////////////////// -impl StrInst { +impl Str { pub(crate) fn to_str(_vm: &mut Vm, _state: FunctionState) -> FunctionResult { // top item of the stack should just be ourselves, so return immediately FunctionResult::Return } pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - let escaped: String = - with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| { - str_inst.str_value().as_str().escape_default().collect() - }); - StrInst::create(format!("'{}'", escaped)).into() + let escaped: String = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| { + str_inst.str_value().as_str().escape_default().collect() + }); + Str::create(format!("'{}'", escaped)).into() } pub(crate) fn to_int(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let parsed: Result = - with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| { + with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| { str_inst.str_value().parse() }); match parsed { - Ok(int) => IntInst::create(int).into(), - // TODO StrInst::to_int - throw an exception when we fail to parse an integer + Ok(int) => Int::create(int).into(), + // TODO Str::to_int - throw an exception when we fail to parse an integer // BLOCKED-ON - exceptions Err(e) => todo!("error parsing string to an integer: {}", e), } @@ -236,61 +235,61 @@ impl StrInst { pub(crate) fn to_float(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let parsed: Result = - with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| { + with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| { str_inst.str_value().parse() }); match parsed { - Ok(float) => FloatInst::create(float).into(), - // TODO StrInst::to_int - throw an exception when we fail to parse an integer + Ok(float) => Float::create(float).into(), + // TODO Str::to_int - throw an exception when we fail to parse an integer // BLOCKED-ON - exceptions Err(e) => todo!("error parsing string to a float: {}", e), } } pub(crate) fn len(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - let len = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| { + let len = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| { str_inst.str_value().len() as i64 }); - IntInst::create(len).into() + Int::create(len).into() } pub(crate) fn add(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let lhs = vm.frame_stack()[0].clone(); let rhs = vm.frame_stack()[1].clone(); - if !obj_is_inst::(&rhs) { - // TODO StrInst::add - throw an exception when the RHS is not a string + if !obj_is_inst::(&rhs) { + // TODO Str::add - throw an exception when the RHS is not a string // BLOCKED-ON: exceptions todo!( "can only concatenate Str, got {} instead", - rhs.borrow().type_name() + rhs.borrow().ty_name() ) } let new = format!("{}{}", lhs.borrow(), rhs.borrow()); - StrInst::create(new).into() + Str::create(new).into() } pub(crate) fn mul(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let lhs = vm.frame_stack()[0].clone(); let rhs = vm.frame_stack()[1].clone(); - let repeat_count = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + let repeat_count = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { int_inst.int_value() } else { - // TODO StrInst::mul - throw an exception when the RHS is not an int + // TODO Str::mul - throw an exception when the RHS is not an int // BLOCKED-ON: exceptions todo!( "can only repeat Str with Int, got {} instead", - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; let repeat_count = repeat_count.max(0) as usize; let new = format!("{}", lhs.borrow()).repeat(repeat_count); - StrInst::create(new).into() + Str::create(new).into() } } //////////////////////////////////////////////////////////////////////////////// -// IntInst implementations +// Int implementations //////////////////////////////////////////////////////////////////////////////// macro_rules! int_bin_op_math { @@ -299,18 +298,18 @@ macro_rules! int_bin_op_math { 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 lhs_value = with_obj_downcast(lhs, Int::int_value); - let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { - IntInst::create(lhs_value $op int_inst.int_value()) - } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { - FloatInst::create(lhs_value as f64 $op float_inst.float_value()) + let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + Int::create(lhs_value $op int_inst.int_value()) + } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { + Float::create(lhs_value as f64 $op float_inst.float_value()) } else { - // TODO IntInst arithmetic operator - throw an exception when RHS is not Int, Float + // TODO Int arithmetic operator - throw an exception when RHS is not Int, Float // BLOCKED-ON: exceptions todo!( concat!("cannot use '", stringify!($op), "' operator with Int and {}"), - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; result.into() @@ -324,18 +323,18 @@ macro_rules! int_bin_op_logical { 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 lhs_value = with_obj_downcast(lhs, Int::int_value); - let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { - BoolInst::create(lhs_value $op int_inst.int_value()) - } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { - BoolInst::create((lhs_value as f64) $op float_inst.float_value()) + let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + Bool::create(lhs_value $op int_inst.int_value()) + } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { + Bool::create((lhs_value as f64) $op float_inst.float_value()) } else { - // TODO IntInst logical operator - throw an exception when RHS is not Int, Float + // TODO Int logical operator - throw an exception when RHS is not Int, Float // BLOCKED-ON: exceptions todo!( concat!("cannot use '", stringify!($op), "' operator with Int and {}"), - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; result.into() @@ -343,14 +342,14 @@ macro_rules! int_bin_op_logical { } } -impl IntInst { +impl Int { pub(crate) fn to_int(_vm: &mut Vm, _state: FunctionState) -> FunctionResult { FunctionResult::Return } pub(crate) fn to_float(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - let int_value = with_obj_downcast(vm.frame_stack()[0].clone(), IntInst::int_value); - FloatInst::create(int_value as f64).into() + let int_value = with_obj_downcast(vm.frame_stack()[0].clone(), Int::int_value); + Float::create(int_value as f64).into() } int_bin_op_math!(add, +); @@ -361,28 +360,28 @@ impl IntInst { 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 lhs_value = with_obj_downcast(lhs, Int::int_value); - let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { - IntInst::create(lhs_value * int_inst.int_value()) - } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { - FloatInst::create(lhs_value as f64 * float_inst.float_value()) - } else if let Some(str_inst) = rhs.borrow().as_any().downcast_ref::() { - // TODO IntInst::mul - maybe convert this to just call Str.mul with arguments reversed? + let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + Int::create(lhs_value * int_inst.int_value()) + } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { + Float::create(lhs_value as f64 * float_inst.float_value()) + } else if let Some(str_inst) = rhs.borrow().as_any().downcast_ref::() { + // TODO Int::mul - maybe convert this to just call Str.mul with arguments reversed? // Just so we have the same logic here - StrInst::create(str_inst.str_value().repeat(lhs_value as usize)) + Str::create(str_inst.str_value().repeat(lhs_value as usize)) } else { - // TODO IntInst::mul - throw an exception when RHS is not Int, Float, Str + // TODO Int::mul - throw an exception when RHS is not Int, Float, Str // BLOCKED-ON: exceptions todo!( "cannot use '*' operator with Int and {}", - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; result.into() } - // TODO IntInst::div - handle divide by zero + // TODO Int::div - handle divide by zero // BLOCKED-ON: exceptions // NOTE - we will probably need to get rid of the macro here to handle that :( int_bin_op_math!(div, /); @@ -397,19 +396,19 @@ impl IntInst { 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); - IntInst::create(value.abs()).into() + let value = with_obj_downcast(lhs, Int::int_value); + Int::create(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); - IntInst::create(-value).into() + let value = with_obj_downcast(lhs, Int::int_value); + Int::create(-value).into() } } //////////////////////////////////////////////////////////////////////////////// -// FloatInst implementations +// Float implementations //////////////////////////////////////////////////////////////////////////////// macro_rules! float_bin_op_math { @@ -418,18 +417,18 @@ macro_rules! float_bin_op_math { let lhs = vm.frame_stack()[0].clone(); let rhs = vm.frame_stack()[1].clone(); - let lhs_value = with_obj_downcast(lhs, FloatInst::float_value); + let lhs_value = with_obj_downcast(lhs, Float::float_value); - let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { - FloatInst::create(lhs_value $op int_inst.int_value() as f64) - } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { - FloatInst::create(lhs_value $op float_inst.float_value()) + let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + Float::create(lhs_value $op int_inst.int_value() as f64) + } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { + Float::create(lhs_value $op float_inst.float_value()) } else { - // TODO IntInst arithmetic operator - throw an exception when RHS is not Int, Float + // TODO Int arithmetic operator - throw an exception when RHS is not Int, Float // BLOCKED-ON: exceptions todo!( concat!("cannot use '", stringify!($op), "' operator with Float and {}"), - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; result.into() @@ -443,18 +442,18 @@ macro_rules! float_bin_op_logical { let lhs = vm.frame_stack()[0].clone(); let rhs = vm.frame_stack()[1].clone(); - let lhs_value = with_obj_downcast(lhs, FloatInst::float_value); + let lhs_value = with_obj_downcast(lhs, Float::float_value); - let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { - BoolInst::create(lhs_value $op int_inst.int_value() as f64) - } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { - BoolInst::create(lhs_value $op float_inst.float_value()) + let result = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::() { + Bool::create(lhs_value $op int_inst.int_value() as f64) + } else if let Some(float_inst) = rhs.borrow().as_any().downcast_ref::() { + Bool::create(lhs_value $op float_inst.float_value()) } else { - // TODO IntInst logical operator - throw an exception when RHS is not Int, Float + // TODO Int logical operator - throw an exception when RHS is not Int, Float // BLOCKED-ON: exceptions todo!( concat!("cannot use '", stringify!($op), "' operator with Float and {}"), - rhs.borrow().type_name() + rhs.borrow().ty_name() ) }; result.into() @@ -462,10 +461,10 @@ macro_rules! float_bin_op_logical { } } -impl FloatInst { +impl Float { pub(crate) fn to_int(vm: &mut Vm, _state: FunctionState) -> FunctionResult { - let float_value = with_obj_downcast(vm.frame_stack()[0].clone(), FloatInst::float_value); - IntInst::create(float_value as i64).into() + let float_value = with_obj_downcast(vm.frame_stack()[0].clone(), Float::float_value); + Int::create(float_value as i64).into() } pub(crate) fn to_float(_vm: &mut Vm, _state: FunctionState) -> FunctionResult { @@ -487,13 +486,13 @@ impl FloatInst { pub(crate) fn pos(vm: &mut Vm, _state: FunctionState) -> FunctionResult { let lhs = vm.frame_stack()[0].clone(); - let value = with_obj_downcast(lhs, FloatInst::float_value); - FloatInst::create(value.abs()).into() + let value = with_obj_downcast(lhs, Float::float_value); + Float::create(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, FloatInst::float_value); - FloatInst::create(-value).into() + let value = with_obj_downcast(lhs, Float::float_value); + Float::create(-value).into() } } diff --git a/src/compiler.rs b/src/compiler.rs index 6c9aad8..55a2123 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -8,7 +8,7 @@ use common_macros::hash_map; use thiserror::Error; use crate::ast::*; -use crate::obj::function::UserFunctionInst; +use crate::obj::function::UserFunction; use crate::obj::*; use crate::token::TokenKind; use crate::vm::*; @@ -665,11 +665,7 @@ impl StmtVisitor for Compiler { // object created, if it were a function object, will be what we're assigning it to, but I // want to be 100% sure instead of 99%. let obj = self.constants.last().unwrap().as_ref(); - if let Some(fun) = obj - .borrow_mut() - .as_any_mut() - .downcast_mut::() - { + if let Some(fun) = obj.borrow_mut().as_any_mut().downcast_mut::() { fun.set_name(Rc::new(name.to_string())); } @@ -678,7 +674,7 @@ impl StmtVisitor for Compiler { fn visit_set_stmt(&mut self, stmt: &SetStmt) -> Result<()> { self.compile_expr(&stmt.expr)?; - let name = self.insert_constant(StrInst::create(&stmt.name.text))?; + let name = self.insert_constant(Str::create(&stmt.name.text))?; self.compile_expr(&stmt.rhs)?; self.emit(stmt_line_number(stmt), Op::SetAttr(name)); Ok(()) @@ -697,7 +693,7 @@ impl StmtVisitor for Compiler { if let Some(expr) = &stmt.expr { self.compile_expr(expr)?; } else { - let nil = self.insert_constant(NilInst::create())?; + let nil = self.insert_constant(Nil::create())?; self.emit(stmt_line_number(stmt), Op::PushConstant(nil)); } self.emit(stmt_line_number(stmt), Op::Return); @@ -707,7 +703,7 @@ impl StmtVisitor for Compiler { // condition self.compile_expr(&stmt.condition)?; // call obj.to_bool() - let bool_attr = self.insert_constant(StrInst::create("to_bool"))?; + let bool_attr = self.insert_constant(Str::create("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(); @@ -779,7 +775,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(StrInst::create("to_bool"))?; + let constant_id = self.insert_constant(Str::create("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(); @@ -793,14 +789,14 @@ impl ExprVisitor for Compiler { let name = OP_NAMES .get(&expr.op.kind) .expect("invalid binary operator"); - let constant_id = self.insert_constant(StrInst::create(name))?; + let constant_id = self.insert_constant(Str::create(name))?; self.emit(expr_line_number(expr), Op::GetAttr(constant_id)); self.compile_expr(&expr.rhs)?; // 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(StrInst::create("to_bool"))?; + let constant_id = self.insert_constant(Str::create("to_bool"))?; self.emit(expr_line_number(&*expr.rhs), Op::GetAttr(constant_id)); self.emit(expr_line_number(&*expr.rhs), Op::Call(0)); } @@ -838,7 +834,7 @@ impl ExprVisitor for Compiler { }); self.compile_expr(&expr.expr)?; let name = OP_NAMES.get(&expr.op.kind).expect("invalid unary operator"); - let constant_id = self.insert_constant(StrInst::create(name))?; + let constant_id = self.insert_constant(Str::create(name))?; self.emit(expr_line_number(expr), Op::GetAttr(constant_id)); self.emit(expr_line_number(expr), Op::Call(0)); Ok(()) @@ -862,7 +858,7 @@ impl ExprVisitor for Compiler { fn visit_get_expr(&mut self, expr: &GetExpr) -> Result<()> { self.compile_expr(&expr.expr)?; - let constant_id = self.insert_constant(StrInst::create(&expr.name.text))?; + let constant_id = self.insert_constant(Str::create(&expr.name.text))?; self.emit(expr_line_number(expr), Op::GetAttr(constant_id)); Ok(()) } @@ -888,29 +884,28 @@ impl ExprVisitor for Compiler { } TokenKind::Number => { let obj = if expr.token.text.contains('.') { - FloatInst::create(expr.token.text.parse().unwrap()) + Float::create(expr.token.text.parse().unwrap()) } else if expr.token.text.starts_with("0x") || expr.token.text.starts_with("0X") { - IntInst::create(i64::from_str_radix(&expr.token.text[2..], 16).unwrap()) + Int::create(i64::from_str_radix(&expr.token.text[2..], 16).unwrap()) } else if expr.token.text.starts_with("0b") || expr.token.text.starts_with("0B") { - IntInst::create(i64::from_str_radix(&expr.token.text[2..], 2).unwrap()) + Int::create(i64::from_str_radix(&expr.token.text[2..], 2).unwrap()) } else { - IntInst::create(expr.token.text.parse().unwrap()) + Int::create(expr.token.text.parse().unwrap()) }; let constant_id = self.insert_constant(obj)?; self.emit(expr_line_number(expr), Op::PushConstant(constant_id)); } TokenKind::String => { - let constant_id = - self.insert_constant(StrInst::create(unescape(&expr.token.text)))?; + let constant_id = self.insert_constant(Str::create(unescape(&expr.token.text)))?; self.emit(expr_line_number(expr), Op::PushConstant(constant_id)); } TokenKind::True | TokenKind::False => { let constant_id = - self.insert_constant(BoolInst::create(expr.token.kind == TokenKind::True))?; + self.insert_constant(Bool::create(expr.token.kind == TokenKind::True))?; self.emit(expr_line_number(expr), Op::PushConstant(constant_id)); } TokenKind::Nil => { - let constant_id = self.insert_constant(NilInst::create())?; + let constant_id = self.insert_constant(Nil::create())?; self.emit(expr_line_number(expr), Op::PushConstant(constant_id)); } _ => unreachable!(), @@ -968,7 +963,7 @@ impl ExprVisitor for Compiler { } // always end with a "return nil" - let nil = self.insert_constant(NilInst::create())?; + let nil = self.insert_constant(Nil::create())?; self.emit(end_line, Op::PushConstant(nil)); self.emit(end_line, Op::Return); @@ -976,7 +971,7 @@ impl ExprVisitor for Compiler { // create the function let chunk = self.chunks.pop().unwrap(); - let fun = UserFunctionInst::create(chunk, expr.params.len() as Argc); + let fun = UserFunction::create(chunk, expr.params.len() as Argc); // register the function as a constant let fun_constant = self.insert_constant(fun)?; diff --git a/src/disassemble.rs b/src/disassemble.rs index 191a773..96de307 100644 --- a/src/disassemble.rs +++ b/src/disassemble.rs @@ -1,4 +1,4 @@ -use crate::obj::function::UserFunctionInst; +use crate::obj::function::UserFunction; use crate::obj::ObjP; use crate::vm::{Chunk, JumpOpArg, Op}; @@ -151,11 +151,7 @@ pub fn disassemble(chunk: &Chunk, constants: &Vec, globals: &Vec) disassemble_chunk(chunk, constants, globals); for constant in constants { - if let Some(fun) = constant - .borrow() - .as_any() - .downcast_ref::() - { + if let Some(fun) = constant.borrow().as_any().downcast_ref::() { println!(); println!( "== {} starting on line {}", diff --git a/src/obj.rs b/src/obj.rs index 70c0482..c1cad14 100644 --- a/src/obj.rs +++ b/src/obj.rs @@ -18,7 +18,7 @@ use crate::obj::macros::*; use crate::vm::{Argc, Vm}; pub type Ptr = Gc>; -pub type ObjP = Ptr; +pub type ObjP = Ptr; pub type Attrs = HashMap; // TODO obj::with_obj_downcast - optimize downcasts of "known" types with an unchecked downcast @@ -26,7 +26,7 @@ pub type Attrs = HashMap; /// Downcast an object pointer to a concrete type, and do something with that object. pub fn with_obj_downcast(ptr: ObjP, closure: impl FnOnce(&T) -> Out) -> Out where - T: Obj + 'static, + T: Object + 'static, { let borrowed = ptr.borrow(); if let Some(obj) = borrowed.as_any().downcast_ref::() { @@ -43,7 +43,7 @@ where /// Downcast an object pointer to a concrete type, and do something with that object. pub fn with_obj_downcast_mut(ptr: ObjP, closure: impl FnOnce(&mut T) -> Out) -> Out where - T: Obj + 'static, + T: Object + 'static, { let mut borrowed = ptr.borrow_mut(); if let Some(obj) = borrowed.as_any_mut().downcast_mut::() { @@ -59,15 +59,15 @@ where pub fn obj_is_inst(ptr: &ObjP) -> bool where - T: Obj + 'static, + T: Object + 'static, { let borrowed = ptr.borrow(); borrowed.as_any().downcast_ref::().is_some() } -pub fn upcast_obj(ptr: Ptr) -> ObjP { +pub fn upcast_obj(ptr: Ptr) -> ObjP { unsafe { - let ptr = Ptr::into_raw(ptr) as *const GcCell; + let ptr = Ptr::into_raw(ptr) as *const GcCell; Ptr::from_raw(ptr) } } @@ -88,7 +88,7 @@ pub fn init_types() { ),* $(,)? ) => {{ $( - let $name = make_ptr(TypeInst::new(stringify!($name))); + let $name = make_ptr(Ty::new(stringify!($name))); BUILTINS.with_borrow_mut(|builtins| builtins.insert(stringify!($name).to_string(), $name.clone())); )* @@ -97,16 +97,16 @@ pub fn init_types() { // setting up these fundamental types. $({ let base_type = $base_type.clone(); - $name.borrow_mut().set_attr("__type__", base_type); - with_obj_downcast_mut($name.clone(), |type_inst: &mut TypeInst| { type_inst.base.is_instantiated = true; }); + $name.borrow_mut().set_attr("__ty__", base_type); + with_obj_downcast_mut($name.clone(), |ty: &mut Ty| { ty.base.is_instantiated = true; }); })* $({ $( let vtable_name = stringify!($vtable_name); let vtable_value = $vtable_value; - with_obj_downcast_mut($name.clone(), |type_inst: &mut TypeInst| { - type_inst.vtable.insert(vtable_name.to_string(), vtable_value); + with_obj_downcast_mut($name.clone(), |ty: &mut Ty| { + ty.vtable.insert(vtable_name.to_string(), vtable_value); }); )* })* @@ -115,82 +115,82 @@ pub fn init_types() { types! { // base type - base_type: Type, + base_type: Ty, // type definitions - Type { + Ty { // Conversion methods - to_str => BuiltinFunctionInst::create("to_str", BaseObjInst::to_str, 1), - to_repr => BuiltinFunctionInst::create("to_repr", BaseObjInst::to_repr, 1), - to_bool => BuiltinFunctionInst::create("to_bool", BaseObjInst::to_bool, 1), - to_int => BuiltinFunctionInst::create("to_int", BaseObjInst::not_implemented_un, 1), - to_float => BuiltinFunctionInst::create("to_float", BaseObjInst::not_implemented_un, 1), - len => BuiltinFunctionInst::create("len", BaseObjInst::not_implemented_un, 1), + to_str => BuiltinFunction::create("to_str", BaseObj::to_str, 1), + to_repr => BuiltinFunction::create("to_repr", BaseObj::to_repr, 1), + to_bool => BuiltinFunction::create("to_bool", BaseObj::to_bool, 1), + to_int => BuiltinFunction::create("to_int", BaseObj::not_implemented_un, 1), + to_float => BuiltinFunction::create("to_float", BaseObj::not_implemented_un, 1), + len => BuiltinFunction::create("len", BaseObj::not_implemented_un, 1), // Operators - __add__ => BuiltinFunctionInst::create("__add__", BaseObjInst::not_implemented_bin, 2), - __sub__ => BuiltinFunctionInst::create("__sub__", BaseObjInst::not_implemented_bin, 2), - __mul__ => BuiltinFunctionInst::create("__mul__", BaseObjInst::not_implemented_bin, 2), - __div__ => BuiltinFunctionInst::create("__div__", BaseObjInst::not_implemented_bin, 2), - __and__ => BuiltinFunctionInst::create("__and__", BaseObjInst::and, 2), - __or__ => BuiltinFunctionInst::create("__or__", BaseObjInst::or, 2), - __ne__ => BuiltinFunctionInst::create("__ne__", BaseObjInst::ne, 2), - __eq__ => BuiltinFunctionInst::create("__eq__", BaseObjInst::eq, 2), - __gt__ => BuiltinFunctionInst::create("__gt__", BaseObjInst::not_implemented_bin, 2), - __ge__ => BuiltinFunctionInst::create("__ge__", BaseObjInst::not_implemented_bin, 2), - __lt__ => BuiltinFunctionInst::create("__lt__", BaseObjInst::not_implemented_bin, 2), - __le__ => BuiltinFunctionInst::create("__le__", BaseObjInst::not_implemented_bin, 2), - __pos__ => BuiltinFunctionInst::create("__pos__", BaseObjInst::not_implemented_un, 1), - __neg__ => BuiltinFunctionInst::create("__neg__", BaseObjInst::not_implemented_un, 1), - __not__ => BuiltinFunctionInst::create("__not__", BaseObjInst::not, 1), + __add__ => BuiltinFunction::create("__add__", BaseObj::not_implemented_bin, 2), + __sub__ => BuiltinFunction::create("__sub__", BaseObj::not_implemented_bin, 2), + __mul__ => BuiltinFunction::create("__mul__", BaseObj::not_implemented_bin, 2), + __div__ => BuiltinFunction::create("__div__", BaseObj::not_implemented_bin, 2), + __and__ => BuiltinFunction::create("__and__", BaseObj::and, 2), + __or__ => BuiltinFunction::create("__or__", BaseObj::or, 2), + __ne__ => BuiltinFunction::create("__ne__", BaseObj::ne, 2), + __eq__ => BuiltinFunction::create("__eq__", BaseObj::eq, 2), + __gt__ => BuiltinFunction::create("__gt__", BaseObj::not_implemented_bin, 2), + __ge__ => BuiltinFunction::create("__ge__", BaseObj::not_implemented_bin, 2), + __lt__ => BuiltinFunction::create("__lt__", BaseObj::not_implemented_bin, 2), + __le__ => BuiltinFunction::create("__le__", BaseObj::not_implemented_bin, 2), + __pos__ => BuiltinFunction::create("__pos__", BaseObj::not_implemented_un, 1), + __neg__ => BuiltinFunction::create("__neg__", BaseObj::not_implemented_un, 1), + __not__ => BuiltinFunction::create("__not__", BaseObj::not, 1), }, - Obj { }, + Object { }, Str { // Conversion methods - to_str => BuiltinFunctionInst::create("to_str", StrInst::to_str, 1), - to_repr => BuiltinFunctionInst::create("to_repr", StrInst::to_repr, 1), - to_int => BuiltinFunctionInst::create("to_int", StrInst::to_int, 1), - to_float => BuiltinFunctionInst::create("to_float", StrInst::to_float, 1), - len => BuiltinFunctionInst::create("len", StrInst::len, 1), + to_str => BuiltinFunction::create("to_str", Str::to_str, 1), + to_repr => BuiltinFunction::create("to_repr", Str::to_repr, 1), + to_int => BuiltinFunction::create("to_int", Str::to_int, 1), + to_float => BuiltinFunction::create("to_float", Str::to_float, 1), + len => BuiltinFunction::create("len", Str::len, 1), // Operators - __add__ => BuiltinFunctionInst::create("__add__", StrInst::add, 2), - __mul__ => BuiltinFunctionInst::create("__mul__", StrInst::mul, 2), + __add__ => BuiltinFunction::create("__add__", Str::add, 2), + __mul__ => BuiltinFunction::create("__mul__", Str::mul, 2), // .lower, .upper, .slice, etc }, Int { // Conversion methods - to_int => BuiltinFunctionInst::create("to_int", IntInst::to_int, 1), - to_float => BuiltinFunctionInst::create("to_float", IntInst::to_float, 1), + to_int => BuiltinFunction::create("to_int", Int::to_int, 1), + to_float => BuiltinFunction::create("to_float", Int::to_float, 1), // Operators - __add__ => BuiltinFunctionInst::create("__add__", IntInst::add, 2), - __sub__ => BuiltinFunctionInst::create("__sub__", IntInst::sub, 2), - __mul__ => BuiltinFunctionInst::create("__mul__", IntInst::mul, 2), - __div__ => BuiltinFunctionInst::create("__div__", IntInst::div, 2), - //__eq__ => BuiltinFunctionInst::create("__eq__", IntInst::eq, 2), - __gt__ => BuiltinFunctionInst::create("__gt__", IntInst::gt, 2), - __ge__ => BuiltinFunctionInst::create("__ge__", IntInst::ge, 2), - __lt__ => BuiltinFunctionInst::create("__lt__", IntInst::lt, 2), - __le__ => BuiltinFunctionInst::create("__le__", IntInst::le, 2), - __pos__ => BuiltinFunctionInst::create("__pos__", IntInst::pos, 1), - __neg__ => BuiltinFunctionInst::create("__neg__", IntInst::neg, 1), + __add__ => BuiltinFunction::create("__add__", Int::add, 2), + __sub__ => BuiltinFunction::create("__sub__", Int::sub, 2), + __mul__ => BuiltinFunction::create("__mul__", Int::mul, 2), + __div__ => BuiltinFunction::create("__div__", Int::div, 2), + //__eq__ => BuiltinFunction::create("__eq__", Int::eq, 2), + __gt__ => BuiltinFunction::create("__gt__", Int::gt, 2), + __ge__ => BuiltinFunction::create("__ge__", Int::ge, 2), + __lt__ => BuiltinFunction::create("__lt__", Int::lt, 2), + __le__ => BuiltinFunction::create("__le__", Int::le, 2), + __pos__ => BuiltinFunction::create("__pos__", Int::pos, 1), + __neg__ => BuiltinFunction::create("__neg__", Int::neg, 1), }, Float { // Conversion methods - to_int => BuiltinFunctionInst::create("to_int", FloatInst::to_int, 1), - to_float => BuiltinFunctionInst::create("to_float", FloatInst::to_float, 1), + to_int => BuiltinFunction::create("to_int", Float::to_int, 1), + to_float => BuiltinFunction::create("to_float", Float::to_float, 1), // Operators - __add__ => BuiltinFunctionInst::create("__add__", FloatInst::add, 2), - __sub__ => BuiltinFunctionInst::create("__sub__", FloatInst::sub, 2), - __mul__ => BuiltinFunctionInst::create("__mul__", FloatInst::mul, 2), - __div__ => BuiltinFunctionInst::create("__div__", FloatInst::div, 2), - __gt__ => BuiltinFunctionInst::create("__gt__", FloatInst::gt, 2), - __ge__ => BuiltinFunctionInst::create("__ge__", FloatInst::ge, 2), - __lt__ => BuiltinFunctionInst::create("__lt__", FloatInst::lt, 2), - __le__ => BuiltinFunctionInst::create("__le__", FloatInst::le, 2), - __pos__ => BuiltinFunctionInst::create("__pos__", FloatInst::pos, 1), - __neg__ => BuiltinFunctionInst::create("__neg__", FloatInst::neg, 1), + __add__ => BuiltinFunction::create("__add__", Float::add, 2), + __sub__ => BuiltinFunction::create("__sub__", Float::sub, 2), + __mul__ => BuiltinFunction::create("__mul__", Float::mul, 2), + __div__ => BuiltinFunction::create("__div__", Float::div, 2), + __gt__ => BuiltinFunction::create("__gt__", Float::gt, 2), + __ge__ => BuiltinFunction::create("__ge__", Float::ge, 2), + __lt__ => BuiltinFunction::create("__lt__", Float::lt, 2), + __le__ => BuiltinFunction::create("__le__", Float::le, 2), + __pos__ => BuiltinFunction::create("__pos__", Float::pos, 1), + __neg__ => BuiltinFunction::create("__neg__", Float::neg, 1), }, Bool { }, Nil { }, @@ -205,15 +205,15 @@ pub fn init_types() { /// /// I would implement this as a `From` but it doesn't seem to work for a foreign type, and I'm /// not sure why. -pub fn make_ptr(obj: T) -> ObjP { +pub fn make_ptr(obj: T) -> ObjP { upcast_obj(Ptr::new(GcCell::new(obj))) } //////////////////////////////////////////////////////////////////////////////// -// Obj +// Object //////////////////////////////////////////////////////////////////////////////// -pub trait Obj: Debug + Display + Any + Trace { +pub trait Object: Debug + Display + Any + Trace { fn instantiate(&mut self); fn is_instantiated(&self) -> bool; @@ -235,45 +235,42 @@ pub trait Obj: Debug + Display + Any + Trace { return attr; } - let mut type_inst = self.type_inst(); + let mut ty = self.ty(); loop { let vtable_entry = - with_obj_downcast_mut(type_inst.clone(), |type_inst: &mut TypeInst| { - type_inst.vtable.get(name).cloned() - }) - .map(|vtable_entry| { - let ptr = if obj_is_inst::(&vtable_entry) - || obj_is_inst::(&vtable_entry) - { - MethodInst::create(self_ptr.clone(), vtable_entry) - } else { - vtable_entry - }; - // TODO Obj::get_attr - cache the vtable result somehow? we aren't caching for - // speed, but rather so we don't have a million different method objects - // floating around. - //self.set_attr(name, ptr.clone()); - ptr - }); + with_obj_downcast_mut(ty.clone(), |ty: &mut Ty| ty.vtable.get(name).cloned()).map( + |vtable_entry| { + let ptr = if obj_is_inst::(&vtable_entry) + || obj_is_inst::(&vtable_entry) + { + Method::create(self_ptr.clone(), vtable_entry) + } else { + vtable_entry + }; + // TODO Object::get_attr - cache the vtable result somehow? we aren't caching for + // speed, but rather so we don't have a million different method objects + // floating around. + //self.set_attr(name, ptr.clone()); + ptr + }, + ); if vtable_entry.is_some() { return vtable_entry; } - let type_inst_copy = type_inst.borrow().type_inst(); - if type_inst.borrow().equals(&*type_inst_copy.borrow()) { + let ty_copy = ty.borrow().ty(); + if ty.borrow().equals(&*ty_copy.borrow()) { return None; } - type_inst = type_inst_copy; + ty = ty_copy; } } - fn type_inst(&self) -> ObjP { - self.get_attr("__type__").expect("no __type__") + fn ty(&self) -> ObjP { + self.get_attr("__ty__").expect("no __ty__") } - fn type_name(&self) -> Rc { - with_obj_downcast(self.type_inst(), |type_inst: &TypeInst| { - Rc::clone(&type_inst.name) - }) + fn ty_name(&self) -> Rc { + with_obj_downcast(self.ty(), |ty: &Ty| Rc::clone(&ty.name)) } fn arity(&self) -> Option { @@ -281,7 +278,7 @@ pub trait Obj: Debug + Display + Any + Trace { } fn call(&self, _vm: &mut Vm, _argc: Argc) { - // TODO Obj::call - need to handle "this object cannot be called" errors + // TODO Object::call - need to handle "this object cannot be called" errors // BLOCKED-ON: exceptions todo!("Raise some kind of not implemented/not callable error for non-callable objects") } @@ -290,7 +287,7 @@ pub trait Obj: Debug + Display + Any + Trace { true } - fn equals(&self, other: &dyn Obj) -> bool; + fn equals(&self, other: &dyn Object) -> bool; fn as_any(&self) -> &dyn Any; @@ -298,16 +295,16 @@ pub trait Obj: Debug + Display + Any + Trace { } //////////////////////////////////////////////////////////////////////////////// -// BaseObjInst +// BaseObj //////////////////////////////////////////////////////////////////////////////// #[derive(Default, Debug, Trace, Finalize)] -pub(crate) struct BaseObjInst { +pub(crate) struct BaseObj { attrs: Attrs, is_instantiated: bool, } -impl Clone for BaseObjInst { +impl Clone for BaseObj { fn clone(&self) -> Self { Self { attrs: self.attrs.clone(), @@ -316,13 +313,13 @@ impl Clone for BaseObjInst { } } -impl Display for BaseObjInst { +impl Display for BaseObj { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "", (self as *const _ as usize)) + write!(fmt, "", (self as *const _ as usize)) } } -impl Obj for BaseObjInst { +impl Object for BaseObj { fn instantiate(&mut self) { self.is_instantiated = true; } @@ -339,8 +336,8 @@ impl Obj for BaseObjInst { &mut self.attrs } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { // compare all attrs self.attrs.iter().all(|(k1, v1)| { other @@ -364,15 +361,15 @@ impl Obj for BaseObjInst { } //////////////////////////////////////////////////////////////////////////////// -// ObjInst +// Obj //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Trace, Finalize)] -pub struct ObjInst { - base: BaseObjInst, +pub struct Obj { + base: BaseObj, } -impl ObjInst { +impl Obj { pub fn new() -> Self { Self { base: Default::default(), @@ -382,37 +379,37 @@ impl ObjInst { impl_create!(); } -impl Display for ObjInst { +impl Display for Obj { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "", (self as *const _ as usize)) + write!(fmt, "", (self as *const _ as usize)) } } -impl Obj for ObjInst { - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { +impl Object for Obj { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { self.base.equals(&other.base) } else { false } } - impl_base_obj!(Obj); + impl_base_obj!(Object); } //////////////////////////////////////////////////////////////////////////////// -// TypeInst +// Ty //////////////////////////////////////////////////////////////////////////////// #[derive(Trace, Finalize)] -pub struct TypeInst { - base: BaseObjInst, +pub struct Ty { + base: BaseObj, #[unsafe_ignore_trace] name: Rc, vtable: HashMap, } -impl TypeInst { +impl Ty { pub fn new(name: impl ToString) -> Self { Self { name: Rc::new(name.to_string()), @@ -428,35 +425,35 @@ impl TypeInst { } } -impl Debug for TypeInst { +impl Debug for Ty { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( fmt, - "", + "", self.name, (self as *const _ as usize) ) } } -impl Display for TypeInst { +impl Display for Ty { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( fmt, - "", + "", self.name, (self as *const _ as usize) ) } } -impl Obj for TypeInst { - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { - // TODO TypeInst::equals : something more robust than this - // Types should hold equality if they have the same name - // the problem is that Type.get_attr("__type__") is going to return itself, so we have - // to go through attributes to specially exclude to the __type__ attribute if it points +impl Object for Ty { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { + // TODO Ty::equals : something more robust than this + // Tys should hold equality if they have the same name + // the problem is that Ty.get_attr("__ty__") is going to return itself, so we have + // to go through attributes to specially exclude to the __ty__ attribute if it points // to ourself. // How do we detect that it's pointing to ourself? I suppose pointers are the way self.name == other.name @@ -465,21 +462,21 @@ impl Obj for TypeInst { } } - impl_base_obj!(Type); + impl_base_obj!(Ty); } //////////////////////////////////////////////////////////////////////////////// -// StrInst +// Str //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Trace, Finalize)] -pub struct StrInst { - base: BaseObjInst, +pub struct Str { + base: BaseObj, #[unsafe_ignore_trace] str_value: Rc, } -impl StrInst { +impl Str { pub fn new(str_value: impl ToString) -> Self { Self { base: Default::default(), @@ -494,19 +491,19 @@ impl StrInst { } } -impl Display for StrInst { +impl Display for Str { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.str_value) } } -impl Obj for StrInst { +impl Object for Str { fn is_truthy(&self) -> bool { !self.str_value.is_empty() } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { self.str_value == other.str_value } else { false @@ -517,16 +514,16 @@ impl Obj for StrInst { } //////////////////////////////////////////////////////////////////////////////// -// IntInst +// Int //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Trace, Finalize)] -pub struct IntInst { - base: BaseObjInst, +pub struct Int { + base: BaseObj, int_value: i64, } -impl IntInst { +impl Int { pub fn new(int_value: i64) -> Self { Self { int_value, @@ -541,21 +538,21 @@ impl IntInst { } } -impl Display for IntInst { +impl Display for Int { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.int_value) } } -impl Obj for IntInst { +impl Object for Int { fn is_truthy(&self) -> bool { self.int_value != 0 } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { self.int_value == other.int_value - } else if let Some(other) = other.as_any().downcast_ref::() { + } else if let Some(other) = other.as_any().downcast_ref::() { self.int_value as f64 == other.float_value } else { false @@ -566,16 +563,16 @@ impl Obj for IntInst { } //////////////////////////////////////////////////////////////////////////////// -// FloatInst +// Float //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Trace, Finalize)] -pub struct FloatInst { - base: BaseObjInst, +pub struct Float { + base: BaseObj, float_value: f64, } -impl FloatInst { +impl Float { pub fn new(float_value: f64) -> Self { Self { float_value, @@ -590,7 +587,7 @@ impl FloatInst { } } -impl Display for FloatInst { +impl Display for Float { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { // we want to force the .0 if it's a whole number if self.float_value == self.float_value.floor() { @@ -601,15 +598,15 @@ impl Display for FloatInst { } } -impl Obj for FloatInst { +impl Object for Float { fn is_truthy(&self) -> bool { self.float_value != 0.0 } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { self.float_value == other.float_value - } else if let Some(other) = other.as_any().downcast_ref::() { + } else if let Some(other) = other.as_any().downcast_ref::() { self.float_value == other.int_value as f64 } else { false @@ -620,16 +617,16 @@ impl Obj for FloatInst { } //////////////////////////////////////////////////////////////////////////////// -// BoolInst +// Bool //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Trace, Finalize)] -pub struct BoolInst { - base: BaseObjInst, +pub struct Bool { + base: BaseObj, bool_value: bool, } -impl BoolInst { +impl Bool { pub fn new(bool_value: bool) -> Self { Self { bool_value, @@ -644,19 +641,19 @@ impl BoolInst { } } -impl Display for BoolInst { +impl Display for Bool { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.bool_value) } } -impl Obj for BoolInst { +impl Object for Bool { fn is_truthy(&self) -> bool { self.bool_value } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { self.bool_value == other.bool_value } else { false @@ -667,15 +664,15 @@ impl Obj for BoolInst { } //////////////////////////////////////////////////////////////////////////////// -// NilInst +// Nil //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Default, Trace, Finalize)] -pub struct NilInst { - base: BaseObjInst, +pub struct Nil { + base: BaseObj, } -impl NilInst { +impl Nil { pub fn new() -> Self { Default::default() } @@ -683,19 +680,19 @@ impl NilInst { impl_create!(); } -impl Display for NilInst { +impl Display for Nil { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "nil") } } -impl Obj for NilInst { +impl Object for Nil { fn is_truthy(&self) -> bool { false } - fn equals(&self, other: &dyn Obj) -> bool { - other.as_any().downcast_ref::().is_some() + fn equals(&self, other: &dyn Object) -> bool { + other.as_any().downcast_ref::().is_some() } impl_base_obj!(Nil); @@ -709,49 +706,49 @@ impl Obj for NilInst { fn test_new_objects() { init_types(); - let type_value = TypeInst::create("Type"); - assert_eq!(&*type_value.borrow().type_name(), "Type"); + let type_value = Ty::create("Ty"); + assert_eq!(&*type_value.borrow().ty_name(), "Ty"); - let str_value = StrInst::create("asdfasdfasdfasdfasdf"); - assert_eq!(&*str_value.borrow().type_name(), "Str"); + let str_value = Str::create("asdfasdfasdfasdfasdf"); + assert_eq!(&*str_value.borrow().ty_name(), "Str"); - let int_value = IntInst::create(1234); - assert_eq!(&*int_value.borrow().type_name(), "Int"); + let int_value = Int::create(1234); + assert_eq!(&*int_value.borrow().ty_name(), "Int"); - let float_value = FloatInst::create(1234.5678); - assert_eq!(&*float_value.borrow().type_name(), "Float"); + let float_value = Float::create(1234.5678); + assert_eq!(&*float_value.borrow().ty_name(), "Float"); - let nil_value = NilInst::create(); - assert_eq!(&*nil_value.borrow().type_name(), "Nil"); + let nil_value = Nil::create(); + assert_eq!(&*nil_value.borrow().ty_name(), "Nil"); } #[test] fn test_obj_equals() { init_types(); - let int1 = IntInst::create(1234); - let int2 = IntInst::create(1234); + let int1 = Int::create(1234); + let int2 = Int::create(1234); assert!(int1.borrow().equals(&*int2.borrow())); assert!(int2.borrow().equals(&*int1.borrow())); - let float1 = FloatInst::create(1234.0); + let float1 = Float::create(1234.0); assert!(int1.borrow().equals(&*float1.borrow())); assert!(float1.borrow().equals(&*int2.borrow())); // self-equality - let str1 = StrInst::create("1234"); + let str1 = Str::create("1234"); assert!(str1.borrow().equals(&*str1.borrow())); - let str2 = StrInst::create("1234"); + let str2 = Str::create("1234"); assert!(str1.borrow().equals(&*str2.borrow())); assert!(str2.borrow().equals(&*str1.borrow())); assert!(!str1.borrow().equals(&*float1.borrow())); assert!(!str1.borrow().equals(&*int1.borrow())); - let obj1 = ObjInst::create(); - let obj2 = ObjInst::create(); + let obj1 = Obj::create(); + let obj2 = Obj::create(); assert!(obj1.borrow().equals(&*obj2.borrow())); // these objects aren't equal anymore @@ -766,14 +763,14 @@ fn test_obj_equals() { #[test] fn test_obj_vtable() { init_types(); - let str1 = StrInst::create("asdfasdfasdf"); + let str1 = Str::create("asdfasdfasdf"); let to_string_ptr = str1.borrow_mut().get_vtable_attr(str1.clone(), "to_str"); assert!(to_string_ptr.is_some()); let to_string_ptr = to_string_ptr.unwrap(); - assert!(obj_is_inst::(&to_string_ptr)); - with_obj_downcast(to_string_ptr.clone(), |method: &MethodInst| { + assert!(obj_is_inst::(&to_string_ptr)); + with_obj_downcast(to_string_ptr.clone(), |method: &Method| { assert!(method.self_binding().borrow().equals(&*str1.borrow())); }); @@ -785,8 +782,8 @@ fn test_obj_vtable() { // this is like doing "asdfasdfasdf".to_string().to_string() let method_to_string_ptr = method_to_string_ptr.unwrap(); - assert!(obj_is_inst::(&method_to_string_ptr)); - with_obj_downcast(method_to_string_ptr.clone(), |method: &MethodInst| { + assert!(obj_is_inst::(&method_to_string_ptr)); + with_obj_downcast(method_to_string_ptr.clone(), |method: &Method| { assert!(method .self_binding() .borrow() diff --git a/src/obj/function.rs b/src/obj/function.rs index be53e44..0218f8d 100644 --- a/src/obj/function.rs +++ b/src/obj/function.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use gc::{Finalize, Trace}; use crate::obj::macros::*; -use crate::obj::{make_ptr, BaseObjInst, Obj, ObjP}; +use crate::obj::{make_ptr, BaseObj, ObjP, Object}; use crate::vm::{Argc, Chunk, Frame, Function, Vm}; //////////////////////////////////////////////////////////////////////////////// @@ -49,14 +49,14 @@ pub enum FunctionState { } //////////////////////////////////////////////////////////////////////////////// -// BuiltinFunctionInst +// BuiltinFunction //////////////////////////////////////////////////////////////////////////////// pub type BuiltinFunctionPtr = fn(vm: &mut Vm, function_state: FunctionState) -> FunctionResult; #[derive(Debug, Trace, Finalize)] -pub struct BuiltinFunctionInst { - base: BaseObjInst, +pub struct BuiltinFunction { + base: BaseObj, #[unsafe_ignore_trace] name: Rc, #[unsafe_ignore_trace] @@ -64,7 +64,7 @@ pub struct BuiltinFunctionInst { arity: Argc, } -impl BuiltinFunctionInst { +impl BuiltinFunction { pub fn new(name: impl ToString, function: BuiltinFunctionPtr, arity: Argc) -> Self { Self { base: Default::default(), @@ -85,7 +85,7 @@ impl BuiltinFunctionInst { } } -impl Display for BuiltinFunctionInst { +impl Display for BuiltinFunction { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( fmt, @@ -97,7 +97,7 @@ impl Display for BuiltinFunctionInst { } } -impl Obj for BuiltinFunctionInst { +impl Object for BuiltinFunction { fn arity(&self) -> Option { Some(self.arity) } @@ -111,10 +111,10 @@ impl Obj for BuiltinFunctionInst { vm.push_frame(new_frame); } - fn equals(&self, other: &dyn Obj) -> bool { - // TODO BuiltinFunctionInst::equals : need something more robust than checking addr_eq, + fn equals(&self, other: &dyn Object) -> bool { + // TODO BuiltinFunction::equals : need something more robust than checking addr_eq, // maybe check the self_binding pointer too? - if let Some(other) = other.as_any().downcast_ref::() { + if let Some(other) = other.as_any().downcast_ref::() { ptr::addr_eq(self, other) } else { false @@ -125,12 +125,12 @@ impl Obj for BuiltinFunctionInst { } //////////////////////////////////////////////////////////////////////////////// -// UserFunctionInst +// UserFunction //////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Clone, Trace, Finalize)] -pub struct UserFunctionInst { - base: BaseObjInst, +pub struct UserFunction { + base: BaseObj, #[unsafe_ignore_trace] name: Rc, #[unsafe_ignore_trace] @@ -139,7 +139,7 @@ pub struct UserFunctionInst { captures: Vec, } -impl UserFunctionInst { +impl UserFunction { pub fn new(chunk: Chunk, arity: Argc) -> Self { Self { base: Default::default(), @@ -169,7 +169,7 @@ impl UserFunctionInst { } } -impl Display for UserFunctionInst { +impl Display for UserFunction { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( fmt, @@ -181,7 +181,7 @@ impl Display for UserFunctionInst { } } -impl Obj for UserFunctionInst { +impl Object for UserFunction { fn arity(&self) -> Option { Some(self.arity) } @@ -199,9 +199,9 @@ impl Obj for UserFunctionInst { } } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { - // TODO UserFunctionInst::equals : need something more robust than checking addr_eq. + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { + // TODO UserFunction::equals : need something more robust than checking addr_eq. ptr::addr_eq(self, other) } else { false @@ -212,19 +212,19 @@ impl Obj for UserFunctionInst { } //////////////////////////////////////////////////////////////////////////////// -// MethodInst +// Method //////////////////////////////////////////////////////////////////////////////// #[derive(Trace, Finalize)] -pub struct MethodInst { - base: BaseObjInst, +pub struct Method { + base: BaseObj, self_binding: ObjP, function: ObjP, } -impl Debug for MethodInst { +impl Debug for Method { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("MethodInst") + fmt.debug_struct("Method") .field("base", &self.base) .field("self_binding", &format!("{}", self.self_binding.borrow())) .field("function", &self.function) @@ -232,7 +232,7 @@ impl Debug for MethodInst { } } -impl MethodInst { +impl Method { pub fn new(self_binding: ObjP, function: ObjP) -> Self { Self { base: Default::default(), @@ -252,13 +252,13 @@ impl MethodInst { } } -impl Display for MethodInst { +impl Display for Method { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.function.borrow()) } } -impl Obj for MethodInst { +impl Object for Method { fn arity(&self) -> Option { // Subtract one from the arity - this is because the VM uses arity() to check against the // number of arguments passed. @@ -273,8 +273,8 @@ impl Obj for MethodInst { self.function.borrow().call(vm, argc) } - fn equals(&self, other: &dyn Obj) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { + fn equals(&self, other: &dyn Object) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { ptr::addr_eq(&*self.self_binding, &*other.self_binding) && ptr::addr_eq(&*self.function, &*other.function) } else { diff --git a/src/obj/macros.rs b/src/obj/macros.rs index 837dd64..50b5fb8 100644 --- a/src/obj/macros.rs +++ b/src/obj/macros.rs @@ -7,7 +7,7 @@ macro_rules! impl_base_obj { .expect(concat!("no ", stringify!($type_name))) .clone() }); - self.set_attr("__type__", ty); + self.set_attr("__ty__", ty); self.$base_name.instantiate(); } diff --git a/src/vm.rs b/src/vm.rs index cb650bc..da4edc8 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -98,7 +98,7 @@ impl Vm { /// Create a new virtual machine with the given chunk, constants, and global names. pub fn new(chunk: Rc, constants: Vec, global_names: Vec) -> Self { // set up globals - let nil = NilInst::create(); + let nil = Nil::create(); let mut globals: Vec<_> = global_names.iter().map(|_| ObjP::clone(&nil)).collect(); let mut register_global = |name: &str, value: ObjP| { @@ -290,7 +290,7 @@ impl Vm { // need both declarations to borrow cell value let name_obj = Ptr::clone(&self.constants[constant_id as usize]); let name = - with_obj_downcast(name_obj, |name: &StrInst| Rc::clone(&name.str_value())); + with_obj_downcast(name_obj, |name: &Str| Rc::clone(&name.str_value())); let owner = self.pop(); let value = owner.borrow_mut().get_vtable_attr(owner.clone(), &name); if let Some(value) = value { @@ -309,7 +309,7 @@ impl Vm { Op::SetAttr(constant_id) => { let name_obj = Ptr::clone(&self.constants[constant_id as usize]); let name = - with_obj_downcast(name_obj, |name: &StrInst| Rc::clone(&name.str_value())); + with_obj_downcast(name_obj, |name: &Str| Rc::clone(&name.str_value())); let value = self.pop(); let target = self.pop(); @@ -378,10 +378,9 @@ impl Vm { // constants, we want to deep-clone this object so we don't alter any live // objects. // there is some room for optimization here so we aren't cloning the entire - // UserFunctionInst for every individual capture in a function. + // UserFunction for every individual capture in a function. let fun_ptr = self.pop(); - let mut fun: UserFunctionInst = - with_obj_downcast(fun_ptr, UserFunctionInst::clone); + let mut fun: UserFunction = with_obj_downcast(fun_ptr, UserFunction::clone); let frame_index = self.frames.len() - (depth as usize) - 1; let stack_base = self.frames[frame_index].stack_base; let value = Ptr::clone(&self.stack[stack_base + (slot as usize)]);