Add metatable to Tables
This commit is contained in:
parent
4ac41e7df1
commit
232a729fe2
@ -474,7 +474,10 @@ impl ClosureRunner {
|
|||||||
{
|
{
|
||||||
self.set_stack(
|
self.set_stack(
|
||||||
*reg,
|
*reg,
|
||||||
StackValue::Value(Value::Table(self.closure.environment.clone())),
|
StackValue::Value(Value::Table {
|
||||||
|
contents: self.closure.environment.clone(),
|
||||||
|
metatable: Box::new(Value::Nil),
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let environment = self.closure.environment.borrow_mut().clone();
|
let environment = self.closure.environment.borrow_mut().clone();
|
||||||
@ -507,7 +510,7 @@ impl ClosureRunner {
|
|||||||
match table {
|
match table {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let mut table = value.borrow_mut();
|
let mut table = value.borrow_mut();
|
||||||
if let Value::Table(table) = &mut *table {
|
if let Value::Table { contents, .. } = &mut *table {
|
||||||
let index_value = self
|
let index_value = self
|
||||||
.stack
|
.stack
|
||||||
.get(indexreg)
|
.get(indexreg)
|
||||||
@ -521,10 +524,10 @@ impl ClosureRunner {
|
|||||||
.unwrap_or(Value::Nil);
|
.unwrap_or(Value::Nil);
|
||||||
match value {
|
match value {
|
||||||
Value::Nil => {
|
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 {
|
} else {
|
||||||
@ -538,8 +541,8 @@ impl ClosureRunner {
|
|||||||
let value = match self.stack.get(tablereg).cloned() {
|
let value = match self.stack.get(tablereg).cloned() {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let table = value.borrow();
|
let table = value.borrow();
|
||||||
if let Value::Table(table) = &*table {
|
if let Value::Table { contents, .. } = &*table {
|
||||||
let table = table.borrow();
|
let table = contents.borrow();
|
||||||
let index_value = self
|
let index_value = self
|
||||||
.stack
|
.stack
|
||||||
.get(indexreg)
|
.get(indexreg)
|
||||||
@ -567,12 +570,12 @@ impl ClosureRunner {
|
|||||||
match table {
|
match table {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let mut table = value.borrow_mut();
|
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;
|
let mut counter = *start_idx as i64;
|
||||||
for i in self.function_register..self.top {
|
for i in self.function_register..self.top {
|
||||||
let value = self.get_stack(i + 1);
|
let value = self.get_stack(i + 1);
|
||||||
match value {
|
match value {
|
||||||
StackValue::Value(value) => table.borrow_mut().insert(
|
StackValue::Value(value) => contents.borrow_mut().insert(
|
||||||
IndexableValue::Integer(LuaInteger(counter)),
|
IndexableValue::Integer(LuaInteger(counter)),
|
||||||
value.clone(),
|
value.clone(),
|
||||||
),
|
),
|
||||||
@ -589,7 +592,10 @@ impl ClosureRunner {
|
|||||||
Instruction::NewTable(reg) => {
|
Instruction::NewTable(reg) => {
|
||||||
self.set_stack(
|
self.set_stack(
|
||||||
*reg,
|
*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) => {
|
Instruction::Jmp(b) => {
|
||||||
|
|||||||
@ -136,7 +136,10 @@ pub enum Value {
|
|||||||
RustFunction(Rc<RefCell<dyn RustFunction>>),
|
RustFunction(Rc<RefCell<dyn RustFunction>>),
|
||||||
Function(Closure),
|
Function(Closure),
|
||||||
Nil,
|
Nil,
|
||||||
Table(Table),
|
Table {
|
||||||
|
contents: Table,
|
||||||
|
metatable: Box<Value>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
@ -151,7 +154,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
Value::Function(closure) => Ok(IndexableValue::Function(closure.prototype)),
|
Value::Function(closure) => Ok(IndexableValue::Function(closure.prototype)),
|
||||||
Value::Nil => Err(RuntimeError::InvalidTableIndex(self)),
|
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, "<function({})>", closure.prototype),
|
Value::Function(closure) => write!(f, "<function({})>", closure.prototype),
|
||||||
Value::Nil => write!(f, "nil"),
|
Value::Nil => write!(f, "nil"),
|
||||||
Value::Table(_) => write!(f, "<table>"),
|
Value::Table { .. } => write!(f, "<table>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,8 +517,8 @@ impl Value {
|
|||||||
pub fn len(&self) -> Result<Value, RuntimeError> {
|
pub fn len(&self) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Value::String(value) => Ok(Self::Integer(LuaInteger(value.len() as i64))),
|
Value::String(value) => Ok(Self::Integer(LuaInteger(value.len() as i64))),
|
||||||
Value::Table(table) => {
|
Value::Table { contents, .. } => {
|
||||||
let table = table.borrow();
|
let table = contents.borrow();
|
||||||
let mut int_indexes = table
|
let mut int_indexes = table
|
||||||
.keys()
|
.keys()
|
||||||
.filter(|v| match v {
|
.filter(|v| match v {
|
||||||
@ -585,7 +588,7 @@ impl Value {
|
|||||||
Value::RustFunction(_) => true,
|
Value::RustFunction(_) => true,
|
||||||
Value::Function(_) => true,
|
Value::Function(_) => true,
|
||||||
Value::Nil => false,
|
Value::Nil => false,
|
||||||
Value::Table(_) => true,
|
Value::Table { .. } => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,9 +605,9 @@ impl Debug for Value {
|
|||||||
.debug_tuple(&format!("Function({})", closure.prototype))
|
.debug_tuple(&format!("Function({})", closure.prototype))
|
||||||
.finish(),
|
.finish(),
|
||||||
Value::Nil => write!(f, "Nil"),
|
Value::Nil => write!(f, "Nil"),
|
||||||
Value::Table(hash_map) => {
|
Value::Table { contents, .. } => {
|
||||||
let mut table = f.debug_struct("Table");
|
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.field(&format!("{:?}", key), value);
|
||||||
}
|
}
|
||||||
table.finish()
|
table.finish()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user