Add if-statements, fix some bugs

This commit is contained in:
Sofia 2026-03-16 15:36:29 +02:00
parent 1f14f2b9f9
commit eaf5e9a30a
2 changed files with 49 additions and 39 deletions

View File

@ -112,10 +112,20 @@ impl Statement {
match self {
Statement::Assignment(access_modifier, names, expr_list) => {
instructions.push(Instruction::LoadNil(
scope.register_counter.0 + 1,
scope.register_counter.0 + names.len() as u16,
));
let new_registers = if *access_modifier == Some(AccessModifier::Local) {
let min_reg = scope.register_counter.0 + 1;
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();
for expr in &expr_list.0 {
@ -131,57 +141,45 @@ impl Statement {
instructions.extend(instr);
expr_regs.extend(regs);
}
match access_modifier {
Some(AccessModifier::Local) => {
for (i, name) in names.iter().enumerate() {
scope.locals.insert(
name.kind.clone(),
expr_regs
.get(i)
.cloned()
.unwrap_or(scope.register_counter.0 + i as u16),
);
instructions.push(Instruction::Move(
*new_registers.get(i).unwrap(),
expr_regs.get(i).cloned().unwrap(),
));
scope
.locals
.insert(name.kind.clone(), *new_registers.get(i).unwrap());
}
dbg!(&scope.locals);
}
Some(AccessModifier::Global) => {
for (i, name) in names.iter().enumerate() {
let global = state.get_constant(&Constant::String(name.kind.clone()));
instructions.push(Instruction::SetGlobal(
expr_regs
.get(i)
.cloned()
.unwrap_or(scope.register_counter.0 + i as u16),
expr_regs.get(i).cloned().unwrap(),
global,
));
}
}
None => {
for (i, name) in names.iter().enumerate() {
if scope.locals.contains_key(&name.kind) {
scope.locals.insert(
name.kind.clone(),
expr_regs
.get(i)
.cloned()
.unwrap_or(scope.register_counter.0 + i as u16),
);
if let Some(reg) = scope.locals.get(&name.kind) {
instructions.push(Instruction::Move(
*reg,
expr_regs.get(i).cloned().unwrap(),
));
} else if let Some(upval_reg) = scope.upvalues.get(&name.kind) {
instructions.push(Instruction::SetUpVal(
*upval_reg,
expr_regs
.get(i)
.cloned()
.unwrap_or(scope.register_counter.0 + i as u16),
expr_regs.get(i).cloned().unwrap(),
));
} else {
let global =
state.get_constant(&Constant::String(name.kind.clone()));
instructions.push(Instruction::SetGlobal(
expr_regs
.get(i)
.cloned()
.unwrap_or(scope.register_counter.0 + i as u16),
expr_regs.get(i).cloned().unwrap(),
global,
));
}
@ -218,13 +216,22 @@ impl Statement {
*ret_register = new_reg;
}
dbg!(&ret_registers);
instructions.push(Instruction::Return(
*ret_registers.first().unwrap_or(&scope.register_counter.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) => {
let (instr, _) = expr.kind.compile(state, scope, None);
instructions.extend(instr);
@ -333,15 +340,17 @@ impl Expression {
.insert(param.kind.clone(), inner_scope.register_counter.next());
}
inner_scope.highest_upvalue =
scope.highest_upvalue + inner_scope.register_counter.0;
inner_scope.highest_upvalue = scope.highest_upvalue + scope.register_counter.0;
inner_scope.upvalues = scope.upvalues.clone();
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);
}
dbg!(&inner_scope.highest_upvalue);
dbg!(&inner_scope.upvalues);
let instructions = block.compile(state, &mut inner_scope);
state.prototypes.push(instructions);

View File

@ -274,7 +274,7 @@ impl ClosureRunner {
}
Instruction::Test(a, b, c) => {
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,
};
if is_true {
@ -355,6 +355,7 @@ impl ClosureRunner {
.max()
.unwrap_or(0);
dbg!(&self.stack);
let mut upvalues = self.closure.upvalues.clone();
for (reg, value) in &self.stack {
upvalues.insert(
@ -363,6 +364,7 @@ impl ClosureRunner {
);
}
dbg!(&upvalues);
self.stack.insert(
*reg,
Value::Function(Closure {
@ -388,7 +390,6 @@ impl ClosureRunner {
for i in reg_start..=reg_end {
ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil));
}
// dbg!(&self.closure.upvalues);
return Some(ret_values);
}
Instruction::Add(res, lhs, rhs) => {