Get compliation to work

This commit is contained in:
Sofia 2026-03-14 19:33:22 +02:00
parent 50f6459abe
commit f71008e8c2
3 changed files with 61 additions and 19 deletions

View File

@ -38,11 +38,13 @@ impl LocalCounter {
} }
impl Block { impl Block {
pub fn find_constants(&self) -> HashSet<Constant> { pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
let mut inner_scope = scope.clone();
for statement in &self.statements { for statement in &self.statements {
constants.extend(statement.kind.find_constants()); constants.extend(statement.kind.find_constants(&mut inner_scope));
} }
constants constants
@ -51,8 +53,9 @@ impl Block {
pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec<Instruction> { pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec<Instruction> {
let mut instructions = Vec::new(); let mut instructions = Vec::new();
let mut inner_scope = scope.clone();
for statement in &self.statements { for statement in &self.statements {
instructions.extend(statement.kind.compile(state, &mut scope.clone())); instructions.extend(statement.kind.compile(state, &mut inner_scope));
} }
instructions instructions
@ -60,21 +63,23 @@ impl Block {
} }
impl Statement { impl Statement {
pub fn find_constants(&self) -> HashSet<Constant> { pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
match self { match self {
Statement::Assignment(access, name, expr) => { Statement::Assignment(access, name, expr) => {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
if *access == AccessModifier::Global { if *access == AccessModifier::Global {
constants.insert(Constant::String(name.kind.clone())); constants.insert(Constant::String(name.kind.clone()));
} else {
scope.locals.insert(name.kind.clone(), 0);
} }
constants.extend(expr.kind.find_constants()); constants.extend(expr.kind.find_constants(scope));
constants constants
} }
Statement::Return(expr) => expr.kind.find_constants(), Statement::Return(expr) => expr.kind.find_constants(scope),
Statement::If(cond, then) => { Statement::If(cond, then) => {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
constants.extend(cond.kind.find_constants()); constants.extend(cond.kind.find_constants(scope));
constants.extend(then.find_constants()); constants.extend(then.find_constants(scope));
constants constants
} }
} }
@ -108,21 +113,27 @@ impl Statement {
} }
impl Expression { impl Expression {
pub fn find_constants(&self) -> HashSet<Constant> { pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
match self { match self {
Expression::ValueRef(_) => HashSet::new(), Expression::ValueRef(name) => {
Expression::BinOp(_, lhs, rhs) => {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
constants.extend(lhs.kind.find_constants()); if !scope.locals.contains_key(name) {
constants.extend(rhs.kind.find_constants()); constants.insert(Constant::String(name.clone()));
}
constants constants
} }
Expression::FunctionDefinition(_, block) => block.find_constants(), Expression::BinOp(_, lhs, rhs) => {
let mut constants = HashSet::new();
constants.extend(lhs.kind.find_constants(scope));
constants.extend(rhs.kind.find_constants(scope));
constants
}
Expression::FunctionDefinition(_, block) => block.find_constants(scope),
Expression::FunctionCall(expr, params) => { Expression::FunctionCall(expr, params) => {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
constants.extend(expr.kind.find_constants()); constants.extend(expr.kind.find_constants(scope));
for param in &params.kind.0 { for param in &params.kind.0 {
constants.extend(param.kind.find_constants()); constants.extend(param.kind.find_constants(scope));
} }
constants constants
} }
@ -195,9 +206,25 @@ impl Expression {
)); ));
} }
instructions.push(Instruction::Call(
function_register,
params.kind.0.len() as u16,
return_regs.len() as u16 + 1,
));
(instructions, return_regs) (instructions, return_regs)
} }
Expression::Literal(literal) => todo!(), Expression::Literal(literal) => {
let mut instructions = Vec::new();
let reg = scope.register_counter.next();
instructions.push(Instruction::GetGlobal(
reg,
state.get_constant(&match literal {
Literal::Number(value) => Constant::Number(value.to_bits()),
}),
));
(instructions, vec![reg])
}
} }
} }
} }

View File

@ -27,7 +27,10 @@ fn main() {
dbg!(&chunk); dbg!(&chunk);
let constants = chunk.find_constants().into_iter().collect::<Vec<_>>(); let constants = chunk
.find_constants(&mut Default::default())
.into_iter()
.collect::<Vec<_>>();
dbg!(&constants); dbg!(&constants);
let instructions = chunk.compile(&mut compile::State { constants }, &mut Default::default()); let instructions = chunk.compile(&mut compile::State { constants }, &mut Default::default());

View File

@ -22,7 +22,7 @@ impl Debug for Constant {
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum Instruction { pub enum Instruction {
/// R(A) := R(B) /// R(A) := R(B)
Move(u16, u16), Move(u16, u16),
@ -36,3 +36,15 @@ pub enum Instruction {
/// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1)) /// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1))
Call(u16, u16, u16), Call(u16, u16, u16),
} }
impl Debug for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Move(arg0, arg1) => write!(f, "MOVE {} {}", arg0, arg1),
Self::LoadK(arg0, arg1) => write!(f, "LOADK {} {}", arg0, arg1),
Self::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1),
Self::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
Self::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2),
}
}
}