From 232a729fe25d44ee8d32d123fd83c2337e4aaaf8 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 20 Mar 2026 20:25:17 +0200 Subject: [PATCH] Add metatable to Tables --- src/vm/mod.rs | 24 +++++++++++++++--------- src/vm/value.rs | 19 +++++++++++-------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 23e944b..7a3a1cc 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -474,7 +474,10 @@ impl ClosureRunner { { self.set_stack( *reg, - StackValue::Value(Value::Table(self.closure.environment.clone())), + StackValue::Value(Value::Table { + contents: self.closure.environment.clone(), + metatable: Box::new(Value::Nil), + }), ); } else { let environment = self.closure.environment.borrow_mut().clone(); @@ -507,7 +510,7 @@ impl ClosureRunner { match table { Some(value) => { let mut table = value.borrow_mut(); - if let Value::Table(table) = &mut *table { + if let Value::Table { contents, .. } = &mut *table { let index_value = self .stack .get(indexreg) @@ -521,10 +524,10 @@ impl ClosureRunner { .unwrap_or(Value::Nil); match value { Value::Nil => { - table.borrow_mut().remove(&index_value); + contents.borrow_mut().remove(&index_value); } _ => { - table.borrow_mut().insert(index_value, value); + contents.borrow_mut().insert(index_value, value); } } } else { @@ -538,8 +541,8 @@ impl ClosureRunner { let value = match self.stack.get(tablereg).cloned() { Some(value) => { let table = value.borrow(); - if let Value::Table(table) = &*table { - let table = table.borrow(); + if let Value::Table { contents, .. } = &*table { + let table = contents.borrow(); let index_value = self .stack .get(indexreg) @@ -567,12 +570,12 @@ impl ClosureRunner { match table { Some(value) => { let mut table = value.borrow_mut(); - if let Value::Table(table) = &mut *table { + if let Value::Table { contents, .. } = &mut *table { let mut counter = *start_idx as i64; for i in self.function_register..self.top { let value = self.get_stack(i + 1); match value { - StackValue::Value(value) => table.borrow_mut().insert( + StackValue::Value(value) => contents.borrow_mut().insert( IndexableValue::Integer(LuaInteger(counter)), value.clone(), ), @@ -589,7 +592,10 @@ impl ClosureRunner { Instruction::NewTable(reg) => { self.set_stack( *reg, - StackValue::Value(Value::Table(Rc::new(RefCell::new(HashMap::new())))), + StackValue::Value(Value::Table { + contents: Rc::new(RefCell::new(HashMap::new())), + metatable: Box::new(Value::Nil), + }), ); } Instruction::Jmp(b) => { diff --git a/src/vm/value.rs b/src/vm/value.rs index 8332dbd..58835f6 100644 --- a/src/vm/value.rs +++ b/src/vm/value.rs @@ -136,7 +136,10 @@ pub enum Value { RustFunction(Rc>), Function(Closure), Nil, - Table(Table), + Table { + contents: Table, + metatable: Box, + }, } impl Value { @@ -151,7 +154,7 @@ impl Value { } Value::Function(closure) => Ok(IndexableValue::Function(closure.prototype)), Value::Nil => Err(RuntimeError::InvalidTableIndex(self)), - Value::Table(_) => Err(RuntimeError::InvalidTableIndex(self)), + Value::Table { .. } => Err(RuntimeError::InvalidTableIndex(self)), } } @@ -201,7 +204,7 @@ impl Display for Value { } Value::Function(closure) => write!(f, "", closure.prototype), Value::Nil => write!(f, "nil"), - Value::Table(_) => write!(f, ""), + Value::Table { .. } => write!(f, "
"), } } } @@ -514,8 +517,8 @@ impl Value { pub fn len(&self) -> Result { match self { Value::String(value) => Ok(Self::Integer(LuaInteger(value.len() as i64))), - Value::Table(table) => { - let table = table.borrow(); + Value::Table { contents, .. } => { + let table = contents.borrow(); let mut int_indexes = table .keys() .filter(|v| match v { @@ -585,7 +588,7 @@ impl Value { Value::RustFunction(_) => true, Value::Function(_) => true, Value::Nil => false, - Value::Table(_) => true, + Value::Table { .. } => true, } } } @@ -602,9 +605,9 @@ impl Debug for Value { .debug_tuple(&format!("Function({})", closure.prototype)) .finish(), Value::Nil => write!(f, "Nil"), - Value::Table(hash_map) => { + Value::Table { contents, .. } => { let mut table = f.debug_struct("Table"); - for (key, value) in hash_map.borrow().iter() { + for (key, value) in contents.borrow().iter() { table.field(&format!("{:?}", key), value); } table.finish()