Add assignment for deeper tables

This commit is contained in:
Sofia 2026-03-17 20:04:20 +02:00
parent af80cd43b3
commit 4c8f52de1a
3 changed files with 76 additions and 3 deletions

View File

@ -1,3 +1,29 @@
global b = 5
function add(x)
return function (y)
x = x + 1
b = b + 1
return x + y, 1, 2, b
end
end
function min(x, y)
local m = x
if y < x then
m = y
end
return m
end
global sometable = {}
sometable.hello = "there"
sometable["hello"] = {}
sometable["hello"].there = "my dude"
print(max(11, 9))
print(add(10)(15))
print(add(10)(15))
print(b)
print(min(11, 9))
print(10 - 15)
print("hello there!")

View File

@ -213,7 +213,8 @@ impl Statement {
None => {
for (i, (name, indexes)) in names.iter().enumerate() {
if indexes.len() > 0 {
let table_reg = if let Some(reg) = scope.locals.get(&name.kind) {
let mut table_reg = if let Some(reg) = scope.locals.get(&name.kind)
{
*reg
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
let local = scope.register_counter.next();
@ -228,7 +229,20 @@ impl Statement {
};
if indexes.len() > 1 {
todo!()
for (_, index) in indexes
.iter()
.enumerate()
.take_while(|(i, _)| *i != indexes.len() - 1)
{
let (instr, index_reg) =
index.kind.compile(state, scope, Some(1));
instructions.extend(instr);
instructions.push(Instruction::GetTable(
table_reg,
table_reg,
*index_reg.first().unwrap(),
));
}
}
let (instr, index_reg) =

View File

@ -51,6 +51,8 @@ pub enum Instruction {
SetUpVal(u16, u16),
/// R(A)[R(B)] := R(C)
SetTable(u16, u16, u16),
/// R(A) := R(B)[R(C)]
GetTable(u16, u16, u16),
/// R(A) := {}
NewTable(u16),
/// R(A) := R(B) + R(C)
@ -94,6 +96,9 @@ impl Debug for Instruction {
Instruction::SetTable(arg0, arg1, arg2) => {
write!(f, "SETTABLE {} {} {}", arg0, arg1, arg2)
}
Instruction::GetTable(arg0, arg1, arg2) => {
write!(f, "GETTABLE {} {} {}", arg0, arg1, arg2)
}
Instruction::NewTable(arg0) => write!(f, "NEWTABLE {}", arg0),
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
@ -614,6 +619,34 @@ impl ClosureRunner {
None => todo!(),
}
}
Instruction::GetTable(res, tablereg, indexreg) => {
let value = match self.stack.get(tablereg).cloned() {
Some(value) => {
let table = value.borrow();
if let Value::Table(table) = &*table {
let table = table.borrow();
let index_value = self
.stack
.get(indexreg)
.map(|v| v.borrow().clone())
.unwrap_or(Value::Nil)
.as_indexable()?;
let value = table.get(&index_value);
match value {
Some(value) => StackValue::Value(value.clone()),
None => StackValue::Value(Value::Nil),
}
} else {
return Err(RuntimeError::NotTable(table.clone()));
}
}
None => {
return Err(RuntimeError::NotTable(Value::Nil));
}
};
self.set_stack(*res, value);
}
Instruction::NewTable(reg) => {
self.set_stack(
*reg,