From d1658bbec670f2dac39615f995afdda10d35ff92 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Tue, 25 Nov 2025 17:55:54 +0100 Subject: [PATCH] restructuring things --- src/compiler/assembly_pass.rs | 82 ++++++++++-------- src/compiler/ast_pass.rs | 155 +++++++++++++++++----------------- src/symbol_builder.rs | 11 +-- 3 files changed, 132 insertions(+), 116 deletions(-) diff --git a/src/compiler/assembly_pass.rs b/src/compiler/assembly_pass.rs index 82fdd55..86426a1 100644 --- a/src/compiler/assembly_pass.rs +++ b/src/compiler/assembly_pass.rs @@ -5,7 +5,7 @@ use crate::compiler::assembly_pass::Op::{ Dup, Equal, Get, Goto, GotoIf, GotoIfNot, Greater, GreaterEqual, Less, LessEqual, ListGet, Multiply, Negate, Not, NotEqual, Or, Pop, Print, Return, Shr, Subtract, }; -use crate::compiler::ast_pass::Expression::{IfExpression, NamedParameter}; +use crate::compiler::ast_pass::Expression::{IfElseExpression, IfExpression, NamedParameter}; use crate::compiler::ast_pass::{Expression, Function, Parameter, Statement}; use crate::compiler::tokens::TokenType; use crate::compiler::tokens::TokenType::Unknown; @@ -186,38 +186,6 @@ impl AsmPass { Statement::GuardStatement { .. } => { unimplemented!("guard statement") } - Statement::ForStatement { - loop_var, - range, - body, - } => { - // 1. step var index - let step_const_index = self.emit_constant(Value::I64(1)); - // 2. range expression - self.compile_expression(namespace, range, symbols, registry)?; - //save the constants for lower and upper bounds of the range - let start_index = self.chunk.constants.len() - 1; - let end_index = self.chunk.constants.len() - 2; - - let name = loop_var.lexeme.as_str(); - let loop_var_name_index = self.chunk.add_var(&loop_var.token_type, name); - self.vars.insert(name.to_string(), loop_var_name_index); - - // 3. start index - self.emit(Constant(start_index)); - self.emit(Assign(loop_var_name_index)); - - let return_addr = self.chunk.code.len(); - self.compile_statements(body, symbols, registry, namespace)?; - self.emit(Get(loop_var_name_index)); - self.emit(Constant(step_const_index)); - self.emit(Add); - self.emit(Assign(loop_var_name_index)); - self.emit(Constant(end_index)); - self.emit(Get(loop_var_name_index)); - self.emit(GreaterEqual); - self.emit(GotoIf(return_addr)); - } } Ok(()) } @@ -233,6 +201,22 @@ impl AsmPass { IfExpression { condition, then_branch, + } => { + self.compile_expression(namespace, condition, symbols, registry)?; + + self.emit(Dup); + self.emit(GotoIfNot(0)); // placeholder + let goto_addr1 = self.chunk.code.len() - 1; + self.emit(Pop); + self.compile_statements(then_branch, symbols, registry, namespace)?; + self.emit(Goto(0)); + let goto_addr2 = self.chunk.code.len() - 1; // placeholder + self.chunk.code[goto_addr1] = GotoIfNot(self.chunk.code.len()); + self.chunk.code[goto_addr2] = Op::Goto(self.chunk.code.len()); + } + IfElseExpression { + condition, + then_branch, else_branch, } => { self.compile_expression(namespace, condition, symbols, registry)?; @@ -455,6 +439,38 @@ impl AsmPass { self.compile_expression(namespace, upper, symbols, registry)?; self.compile_expression(namespace, lower, symbols, registry)?; } + Expression::ForStatement { + loop_var, + range, + body, + } => { + // 1. step var index + let step_const_index = self.emit_constant(Value::I64(1)); + // 2. range expression + self.compile_expression(namespace, range, symbols, registry)?; + //save the constants for lower and upper bounds of the range + let start_index = self.chunk.constants.len() - 1; + let end_index = self.chunk.constants.len() - 2; + + let name = loop_var.lexeme.as_str(); + let loop_var_name_index = self.chunk.add_var(&loop_var.token_type, name); + self.vars.insert(name.to_string(), loop_var_name_index); + + // 3. start index + self.emit(Constant(start_index)); + self.emit(Assign(loop_var_name_index)); + + let return_addr = self.chunk.code.len(); + self.compile_statements(body, symbols, registry, namespace)?; + self.emit(Get(loop_var_name_index)); + self.emit(Constant(step_const_index)); + self.emit(Add); + self.emit(Assign(loop_var_name_index)); + self.emit(Constant(end_index)); + self.emit(Get(loop_var_name_index)); + self.emit(GreaterEqual); + self.emit(GotoIf(return_addr)); + } } Ok(()) } diff --git a/src/compiler/ast_pass.rs b/src/compiler/ast_pass.rs index a649016..a088538 100644 --- a/src/compiler/ast_pass.rs +++ b/src/compiler/ast_pass.rs @@ -1,7 +1,7 @@ use crate::builtins::globals::GLOBAL_FUNCTIONS; use crate::compiler::ast_pass::Expression::{ - Assignment, FieldGet, FunctionCall, IfExpression, LetExpression, ListGet, MapGet, MethodCall, - NamedParameter, Stop, Variable, + Assignment, FieldGet, FunctionCall, IfElseExpression, IfExpression, LetExpression, ListGet, + MapGet, MethodCall, NamedParameter, Stop, Variable, }; use crate::compiler::tokens::TokenType::{ Bang, Bool, Char, Colon, DateTime, Dot, Else, Eof, Eol, Equal, False, FloatingPoint, Fn, For, @@ -128,7 +128,7 @@ impl AstCompiler { } else if self.match_token(&[TokenType::Pipe]) { self.guard_declaration(symbol_table) } else { - self.statement(symbol_table) + self.expr_statement(symbol_table) } } @@ -284,15 +284,26 @@ impl AstCompiler { Ok(Statement::FunctionStmt { function }) } - fn statement(&mut self, symbol_table: &mut SymbolTable) -> Stmt { - if self.match_token(&[For]) { - self.for_statement(symbol_table) - } else { - self.expr_statement(symbol_table) - } + fn inc_indent(&mut self) { + self.indent.push(self.indent.last().unwrap() + 1); } - fn for_statement(&mut self, symbol_table: &mut SymbolTable) -> Stmt { + fn expr_statement(&mut self, symbol_table: &mut SymbolTable) -> Stmt { + let expr = if self.match_token(&[For]) { + self.for_expression(symbol_table)? + } else if self.match_token(&[Let]) { + let expr = self.let_exp(symbol_table)?; + if !self.is_at_end() { + self.consume(&Eol, Expected("end of line after expression."))?; + } + expr + } else { + self.expression(symbol_table)? + }; + Ok(Statement::ExpressionStmt { expression: expr }) + } + + fn for_expression(&mut self, symbol_table: &mut SymbolTable) -> Expr { let loop_var = self.consume(&Identifier, Expected("loop variable name."))?; self.consume(&In, Expected("'in' after loop variable name."))?; let range = self.expression(symbol_table)?; @@ -301,65 +312,49 @@ impl AstCompiler { self.inc_indent(); let body = self.compile(symbol_table)?; - Ok(Statement::ForStatement { + Ok(Expression::ForStatement { loop_var, - range, + range: Box::new(range), body, }) } - fn inc_indent(&mut self) { - self.indent.push(self.indent.last().unwrap() + 1); - } - - fn expr_statement(&mut self, symbol_table: &mut SymbolTable) -> Stmt { - let expr = self.let_exp(symbol_table)?; - if !self.is_at_end() { - self.consume(&Eol, Expected("end of line after expression."))?; - } - Ok(Statement::ExpressionStmt { expression: expr }) - } - fn let_exp(&mut self, symbol_table: &mut SymbolTable) -> Expr { - if self.match_token(&[Let]) { - if self.peek().token_type.is_type() { - return Err(self.raise(CompilerError::KeywordNotAllowedAsIdentifier( - self.peek().token_type.clone(), - ))); - } - let name_token = self.consume(&Identifier, Expected("variable name."))?; + if self.peek().token_type.is_type() { + return Err(self.raise(CompilerError::KeywordNotAllowedAsIdentifier( + self.peek().token_type.clone(), + ))); + } + let name_token = self.consume(&Identifier, Expected("variable name."))?; - let declared_type = if self.check(&Colon) { - self.advance(); - Some(self.advance().token_type.clone()) - } else { - None - }; - - if self.match_token(&[Equal]) { - let initializer = self.expression(symbol_table)?; - let declared_type = declared_type.unwrap_or(Unknown); - let inferred_type = infer_type(&initializer, symbol_table); - let var_type = - calculate_type(&declared_type, &inferred_type).map_err(|e| self.raise(e))?; - symbol_table.insert( - name_token.lexeme.clone(), - Symbol::Variable { - name: name_token.lexeme.clone(), - var_type: var_type.clone(), - }, - ); - - Ok(LetExpression { - name: name_token, - var_type, - initializer: Box::new(initializer), - }) - } else { - Err(self.raise(UninitializedVariable))? - } + let declared_type = if self.check(&Colon) { + self.advance(); + Some(self.advance().token_type.clone()) } else { - self.expression(symbol_table) + None + }; + + if self.match_token(&[Equal]) { + let initializer = self.expression(symbol_table)?; + let declared_type = declared_type.unwrap_or(Unknown); + let inferred_type = infer_type(&initializer, symbol_table); + let var_type = + calculate_type(&declared_type, &inferred_type).map_err(|e| self.raise(e))?; + symbol_table.insert( + name_token.lexeme.clone(), + Symbol::Variable { + name: name_token.lexeme.clone(), + var_type: var_type.clone(), + }, + ); + + Ok(LetExpression { + name: name_token, + var_type, + initializer: Box::new(initializer), + }) + } else { + Err(self.raise(UninitializedVariable))? } } @@ -499,20 +494,23 @@ impl AstCompiler { self.inc_indent(); let then_branch = self.compile(symbol_table)?; - let else_branch = if self.check(&Else) { + if self.check(&Else) { self.consume(&Else, Expected("'else' after if condition."))?; self.consume(&Colon, Expected("':' after 'else'."))?; self.inc_indent(); - Some(self.compile(symbol_table)?) + + Ok(IfElseExpression { + condition: Box::new(condition), + then_branch, + else_branch: Some(self.compile(symbol_table)?), + }) } else { - None - }; - Ok(IfExpression { - condition: Box::new(condition), - then_branch, - else_branch, - }) + Ok(IfExpression { + condition: Box::new(condition), + then_branch, + }) + } } else { self.get(symbol_table) } @@ -854,11 +852,6 @@ pub enum Statement { if_expr: Expression, then_expr: Expression, }, - ForStatement { - loop_var: Token, - range: Expression, - body: Vec, - }, } impl Statement { @@ -868,7 +861,6 @@ impl Statement { Statement::FunctionStmt { function, .. } => function.name.line, Statement::ObjectStmt { name, .. } => name.line, Statement::GuardStatement { if_expr, .. } => if_expr.line(), - Statement::ForStatement { loop_var, .. } => loop_var.line, } } } @@ -973,6 +965,10 @@ pub enum Expression { IfExpression { condition: Box, then_branch: Vec, + }, + IfElseExpression { + condition: Box, + then_branch: Vec, else_branch: Option>, }, LetExpression { @@ -980,6 +976,11 @@ pub enum Expression { var_type: TokenType, initializer: Box, }, + ForStatement { + loop_var: Token, + range: Box, + body: Vec, + }, } impl Expression { @@ -1002,7 +1003,9 @@ impl Expression { ListGet { .. } => 0, FieldGet { .. } => 0, IfExpression { condition, .. } => condition.line(), + IfElseExpression { condition, .. } => condition.line(), LetExpression { name, .. } => name.line, + Expression::ForStatement { loop_var, .. } => loop_var.line, } } } diff --git a/src/symbol_builder.rs b/src/symbol_builder.rs index 27e0b07..0c398eb 100644 --- a/src/symbol_builder.rs +++ b/src/symbol_builder.rs @@ -2,11 +2,7 @@ use crate::compiler::ast_pass::{Expression, Parameter, Statement}; use crate::builtins::lookup; use crate::errors::CompilerError; use crate::errors::CompilerError::{IncompatibleTypes, UndeclaredVariable}; -use crate::compiler::tokens::TokenType::{ - Bool, DateTime, F32, F64, FloatingPoint, Greater, GreaterEqual, I32, I64, Integer, Less, - LessEqual, ListType, MapType, Minus, ObjectType, Plus, SignedInteger, StringType, U32, U64, - Unknown, UnsignedInteger, -}; +use crate::compiler::tokens::TokenType::{Bool, DateTime, F32, F64, FloatingPoint, Greater, GreaterEqual, I32, I64, Integer, Less, LessEqual, ListType, MapType, Minus, ObjectType, Plus, SignedInteger, StringType, U32, U64, Unknown, UnsignedInteger, Void}; use crate::compiler::tokens::{Token, TokenType}; use log::debug; use std::collections::HashMap; @@ -218,13 +214,14 @@ pub fn infer_type(expr: &Expression, symbols: &HashMap) -> Token } } Expression::Stop { .. } => Unknown, - // Expression::PathMatch { .. } => Unknown, Expression::NamedParameter { .. } => Unknown, Expression::ListGet { .. } => Unknown, Expression::MapGet { .. } => Unknown, Expression::FieldGet { .. } => Unknown, Expression::Range { lower, .. } => infer_type(lower, symbols), Expression::IfExpression { .. } => Unknown, - Expression::LetExpression { initializer,.. } => infer_type(initializer, symbols), + Expression::IfElseExpression { .. } => Unknown, + Expression::LetExpression { .. } => Void, + Expression::ForStatement { .. } => Void, } }