Add assignment for deeper tables
This commit is contained in:
parent
af80cd43b3
commit
4c8f52de1a
@ -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 = {}
|
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!")
|
||||||
@ -213,7 +213,8 @@ impl Statement {
|
|||||||
None => {
|
None => {
|
||||||
for (i, (name, indexes)) in names.iter().enumerate() {
|
for (i, (name, indexes)) in names.iter().enumerate() {
|
||||||
if indexes.len() > 0 {
|
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
|
*reg
|
||||||
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
|
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
|
||||||
let local = scope.register_counter.next();
|
let local = scope.register_counter.next();
|
||||||
@ -228,7 +229,20 @@ impl Statement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if indexes.len() > 1 {
|
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) =
|
let (instr, index_reg) =
|
||||||
|
|||||||
33
src/vm.rs
33
src/vm.rs
@ -51,6 +51,8 @@ pub enum Instruction {
|
|||||||
SetUpVal(u16, u16),
|
SetUpVal(u16, u16),
|
||||||
/// R(A)[R(B)] := R(C)
|
/// R(A)[R(B)] := R(C)
|
||||||
SetTable(u16, u16, u16),
|
SetTable(u16, u16, u16),
|
||||||
|
/// R(A) := R(B)[R(C)]
|
||||||
|
GetTable(u16, u16, u16),
|
||||||
/// R(A) := {}
|
/// R(A) := {}
|
||||||
NewTable(u16),
|
NewTable(u16),
|
||||||
/// R(A) := R(B) + R(C)
|
/// R(A) := R(B) + R(C)
|
||||||
@ -94,6 +96,9 @@ impl Debug for Instruction {
|
|||||||
Instruction::SetTable(arg0, arg1, arg2) => {
|
Instruction::SetTable(arg0, arg1, arg2) => {
|
||||||
write!(f, "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::NewTable(arg0) => write!(f, "NEWTABLE {}", arg0),
|
||||||
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
|
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
|
||||||
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
|
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
|
||||||
@ -614,6 +619,34 @@ impl ClosureRunner {
|
|||||||
None => todo!(),
|
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) => {
|
Instruction::NewTable(reg) => {
|
||||||
self.set_stack(
|
self.set_stack(
|
||||||
*reg,
|
*reg,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user