Add if-statements, fix some bugs
This commit is contained in:
parent
1f14f2b9f9
commit
eaf5e9a30a
@ -112,10 +112,20 @@ impl Statement {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(access_modifier, names, expr_list) => {
|
Statement::Assignment(access_modifier, names, expr_list) => {
|
||||||
instructions.push(Instruction::LoadNil(
|
let new_registers = if *access_modifier == Some(AccessModifier::Local) {
|
||||||
scope.register_counter.0 + 1,
|
let min_reg = scope.register_counter.0 + 1;
|
||||||
scope.register_counter.0 + names.len() as u16,
|
let max_reg = scope.register_counter.0 + names.len() as u16;
|
||||||
));
|
instructions.push(Instruction::LoadNil(min_reg, max_reg));
|
||||||
|
scope.register_counter.0 += names.len() as u16;
|
||||||
|
|
||||||
|
let mut new_registers = Vec::new();
|
||||||
|
for i in min_reg..=max_reg {
|
||||||
|
new_registers.push(i);
|
||||||
|
}
|
||||||
|
new_registers
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
let mut expr_regs = Vec::new();
|
let mut expr_regs = Vec::new();
|
||||||
for expr in &expr_list.0 {
|
for expr in &expr_list.0 {
|
||||||
@ -131,57 +141,45 @@ impl Statement {
|
|||||||
instructions.extend(instr);
|
instructions.extend(instr);
|
||||||
expr_regs.extend(regs);
|
expr_regs.extend(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
match access_modifier {
|
match access_modifier {
|
||||||
Some(AccessModifier::Local) => {
|
Some(AccessModifier::Local) => {
|
||||||
for (i, name) in names.iter().enumerate() {
|
for (i, name) in names.iter().enumerate() {
|
||||||
scope.locals.insert(
|
instructions.push(Instruction::Move(
|
||||||
name.kind.clone(),
|
*new_registers.get(i).unwrap(),
|
||||||
expr_regs
|
expr_regs.get(i).cloned().unwrap(),
|
||||||
.get(i)
|
));
|
||||||
.cloned()
|
scope
|
||||||
.unwrap_or(scope.register_counter.0 + i as u16),
|
.locals
|
||||||
);
|
.insert(name.kind.clone(), *new_registers.get(i).unwrap());
|
||||||
}
|
}
|
||||||
dbg!(&scope.locals);
|
|
||||||
}
|
}
|
||||||
Some(AccessModifier::Global) => {
|
Some(AccessModifier::Global) => {
|
||||||
for (i, name) in names.iter().enumerate() {
|
for (i, name) in names.iter().enumerate() {
|
||||||
let global = state.get_constant(&Constant::String(name.kind.clone()));
|
let global = state.get_constant(&Constant::String(name.kind.clone()));
|
||||||
instructions.push(Instruction::SetGlobal(
|
instructions.push(Instruction::SetGlobal(
|
||||||
expr_regs
|
expr_regs.get(i).cloned().unwrap(),
|
||||||
.get(i)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or(scope.register_counter.0 + i as u16),
|
|
||||||
global,
|
global,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
for (i, name) in names.iter().enumerate() {
|
for (i, name) in names.iter().enumerate() {
|
||||||
if scope.locals.contains_key(&name.kind) {
|
if let Some(reg) = scope.locals.get(&name.kind) {
|
||||||
scope.locals.insert(
|
instructions.push(Instruction::Move(
|
||||||
name.kind.clone(),
|
*reg,
|
||||||
expr_regs
|
expr_regs.get(i).cloned().unwrap(),
|
||||||
.get(i)
|
));
|
||||||
.cloned()
|
|
||||||
.unwrap_or(scope.register_counter.0 + i as u16),
|
|
||||||
);
|
|
||||||
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
|
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
|
||||||
instructions.push(Instruction::SetUpVal(
|
instructions.push(Instruction::SetUpVal(
|
||||||
*upval_reg,
|
*upval_reg,
|
||||||
expr_regs
|
expr_regs.get(i).cloned().unwrap(),
|
||||||
.get(i)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or(scope.register_counter.0 + i as u16),
|
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
let global =
|
let global =
|
||||||
state.get_constant(&Constant::String(name.kind.clone()));
|
state.get_constant(&Constant::String(name.kind.clone()));
|
||||||
instructions.push(Instruction::SetGlobal(
|
instructions.push(Instruction::SetGlobal(
|
||||||
expr_regs
|
expr_regs.get(i).cloned().unwrap(),
|
||||||
.get(i)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or(scope.register_counter.0 + i as u16),
|
|
||||||
global,
|
global,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -218,13 +216,22 @@ impl Statement {
|
|||||||
*ret_register = new_reg;
|
*ret_register = new_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(&ret_registers);
|
|
||||||
instructions.push(Instruction::Return(
|
instructions.push(Instruction::Return(
|
||||||
*ret_registers.first().unwrap_or(&scope.register_counter.0),
|
*ret_registers.first().unwrap_or(&scope.register_counter.0),
|
||||||
*ret_registers.last().unwrap_or(&0),
|
*ret_registers.last().unwrap_or(&0),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Statement::If(node, block) => todo!(),
|
Statement::If(expr, block) => {
|
||||||
|
let (instr, regs) = expr.kind.compile(state, scope, Some(1));
|
||||||
|
instructions.extend(instr);
|
||||||
|
|
||||||
|
let local = scope.register_counter.next();
|
||||||
|
instructions.push(Instruction::Test(local, *regs.first().unwrap(), 0));
|
||||||
|
|
||||||
|
let block_instructions = block.compile(state, scope);
|
||||||
|
instructions.push(Instruction::Jmp(block_instructions.len() as i32));
|
||||||
|
instructions.extend(block_instructions);
|
||||||
|
}
|
||||||
Statement::Expression(expr) => {
|
Statement::Expression(expr) => {
|
||||||
let (instr, _) = expr.kind.compile(state, scope, None);
|
let (instr, _) = expr.kind.compile(state, scope, None);
|
||||||
instructions.extend(instr);
|
instructions.extend(instr);
|
||||||
@ -333,15 +340,17 @@ impl Expression {
|
|||||||
.insert(param.kind.clone(), inner_scope.register_counter.next());
|
.insert(param.kind.clone(), inner_scope.register_counter.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
inner_scope.highest_upvalue =
|
inner_scope.highest_upvalue = scope.highest_upvalue + scope.register_counter.0;
|
||||||
scope.highest_upvalue + inner_scope.register_counter.0;
|
|
||||||
inner_scope.upvalues = scope.upvalues.clone();
|
inner_scope.upvalues = scope.upvalues.clone();
|
||||||
|
|
||||||
for (name, reg) in &scope.locals {
|
for (name, reg) in &scope.locals {
|
||||||
let new_reg = *reg + inner_scope.highest_upvalue + 1;
|
let new_reg = *reg + inner_scope.highest_upvalue;
|
||||||
inner_scope.upvalues.insert(name.clone(), new_reg);
|
inner_scope.upvalues.insert(name.clone(), new_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg!(&inner_scope.highest_upvalue);
|
||||||
|
dbg!(&inner_scope.upvalues);
|
||||||
|
|
||||||
let instructions = block.compile(state, &mut inner_scope);
|
let instructions = block.compile(state, &mut inner_scope);
|
||||||
state.prototypes.push(instructions);
|
state.prototypes.push(instructions);
|
||||||
|
|
||||||
|
|||||||
@ -274,7 +274,7 @@ impl ClosureRunner {
|
|||||||
}
|
}
|
||||||
Instruction::Test(a, b, c) => {
|
Instruction::Test(a, b, c) => {
|
||||||
let is_true = match self.stack.get(b).unwrap_or(&Value::Nil) {
|
let is_true = match self.stack.get(b).unwrap_or(&Value::Nil) {
|
||||||
Value::Number(val) => (*val as u16) == *c,
|
Value::Number(val) => (LuaNumber::from_bits(*val) as u16) == *c,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if is_true {
|
if is_true {
|
||||||
@ -355,6 +355,7 @@ impl ClosureRunner {
|
|||||||
.max()
|
.max()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
dbg!(&self.stack);
|
||||||
let mut upvalues = self.closure.upvalues.clone();
|
let mut upvalues = self.closure.upvalues.clone();
|
||||||
for (reg, value) in &self.stack {
|
for (reg, value) in &self.stack {
|
||||||
upvalues.insert(
|
upvalues.insert(
|
||||||
@ -363,6 +364,7 @@ impl ClosureRunner {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg!(&upvalues);
|
||||||
self.stack.insert(
|
self.stack.insert(
|
||||||
*reg,
|
*reg,
|
||||||
Value::Function(Closure {
|
Value::Function(Closure {
|
||||||
@ -388,7 +390,6 @@ impl ClosureRunner {
|
|||||||
for i in reg_start..=reg_end {
|
for i in reg_start..=reg_end {
|
||||||
ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil));
|
ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil));
|
||||||
}
|
}
|
||||||
// dbg!(&self.closure.upvalues);
|
|
||||||
return Some(ret_values);
|
return Some(ret_values);
|
||||||
}
|
}
|
||||||
Instruction::Add(res, lhs, rhs) => {
|
Instruction::Add(res, lhs, rhs) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user