From f71008e8c2345f212d0db14179deee37a363c1e6 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 14 Mar 2026 19:33:22 +0200 Subject: [PATCH] Get compliation to work --- src/compile.rs | 61 ++++++++++++++++++++++++++++++++++++-------------- src/main.rs | 5 ++++- src/vm.rs | 14 +++++++++++- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/compile.rs b/src/compile.rs index 580f1f9..fa203b5 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -38,11 +38,13 @@ impl LocalCounter { } impl Block { - pub fn find_constants(&self) -> HashSet { + pub fn find_constants(&self, scope: &mut Scope) -> HashSet { let mut constants = HashSet::new(); + let mut inner_scope = scope.clone(); + for statement in &self.statements { - constants.extend(statement.kind.find_constants()); + constants.extend(statement.kind.find_constants(&mut inner_scope)); } constants @@ -51,8 +53,9 @@ impl Block { pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec { let mut instructions = Vec::new(); + let mut inner_scope = scope.clone(); for statement in &self.statements { - instructions.extend(statement.kind.compile(state, &mut scope.clone())); + instructions.extend(statement.kind.compile(state, &mut inner_scope)); } instructions @@ -60,21 +63,23 @@ impl Block { } impl Statement { - pub fn find_constants(&self) -> HashSet { + pub fn find_constants(&self, scope: &mut Scope) -> HashSet { match self { Statement::Assignment(access, name, expr) => { let mut constants = HashSet::new(); if *access == AccessModifier::Global { 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 } - Statement::Return(expr) => expr.kind.find_constants(), + Statement::Return(expr) => expr.kind.find_constants(scope), Statement::If(cond, then) => { let mut constants = HashSet::new(); - constants.extend(cond.kind.find_constants()); - constants.extend(then.find_constants()); + constants.extend(cond.kind.find_constants(scope)); + constants.extend(then.find_constants(scope)); constants } } @@ -108,21 +113,27 @@ impl Statement { } impl Expression { - pub fn find_constants(&self) -> HashSet { + pub fn find_constants(&self, scope: &mut Scope) -> HashSet { match self { - Expression::ValueRef(_) => HashSet::new(), - Expression::BinOp(_, lhs, rhs) => { + Expression::ValueRef(name) => { let mut constants = HashSet::new(); - constants.extend(lhs.kind.find_constants()); - constants.extend(rhs.kind.find_constants()); + if !scope.locals.contains_key(name) { + constants.insert(Constant::String(name.clone())); + } 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) => { let mut constants = HashSet::new(); - constants.extend(expr.kind.find_constants()); + constants.extend(expr.kind.find_constants(scope)); for param in ¶ms.kind.0 { - constants.extend(param.kind.find_constants()); + constants.extend(param.kind.find_constants(scope)); } 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) } - 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]) + } } } } diff --git a/src/main.rs b/src/main.rs index e35f89f..0bd5a59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,10 @@ fn main() { dbg!(&chunk); - let constants = chunk.find_constants().into_iter().collect::>(); + let constants = chunk + .find_constants(&mut Default::default()) + .into_iter() + .collect::>(); dbg!(&constants); let instructions = chunk.compile(&mut compile::State { constants }, &mut Default::default()); diff --git a/src/vm.rs b/src/vm.rs index 0127cd5..f242f48 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -22,7 +22,7 @@ impl Debug for Constant { } } -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy)] pub enum Instruction { /// R(A) := R(B) 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)) 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), + } + } +}