restructuring things

This commit is contained in:
Shautvast 2025-11-25 17:55:54 +01:00
parent 0e50042bb0
commit d1658bbec6
3 changed files with 132 additions and 116 deletions

View file

@ -5,7 +5,7 @@ use crate::compiler::assembly_pass::Op::{
Dup, Equal, Get, Goto, GotoIf, GotoIfNot, Greater, GreaterEqual, Less, LessEqual, ListGet, Dup, Equal, Get, Goto, GotoIf, GotoIfNot, Greater, GreaterEqual, Less, LessEqual, ListGet,
Multiply, Negate, Not, NotEqual, Or, Pop, Print, Return, Shr, Subtract, 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::ast_pass::{Expression, Function, Parameter, Statement};
use crate::compiler::tokens::TokenType; use crate::compiler::tokens::TokenType;
use crate::compiler::tokens::TokenType::Unknown; use crate::compiler::tokens::TokenType::Unknown;
@ -186,38 +186,6 @@ impl AsmPass {
Statement::GuardStatement { .. } => { Statement::GuardStatement { .. } => {
unimplemented!("guard statement") 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(()) Ok(())
} }
@ -233,6 +201,22 @@ impl AsmPass {
IfExpression { IfExpression {
condition, condition,
then_branch, 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, else_branch,
} => { } => {
self.compile_expression(namespace, condition, symbols, registry)?; self.compile_expression(namespace, condition, symbols, registry)?;
@ -455,6 +439,38 @@ impl AsmPass {
self.compile_expression(namespace, upper, symbols, registry)?; self.compile_expression(namespace, upper, symbols, registry)?;
self.compile_expression(namespace, lower, 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(()) Ok(())
} }

View file

@ -1,7 +1,7 @@
use crate::builtins::globals::GLOBAL_FUNCTIONS; use crate::builtins::globals::GLOBAL_FUNCTIONS;
use crate::compiler::ast_pass::Expression::{ use crate::compiler::ast_pass::Expression::{
Assignment, FieldGet, FunctionCall, IfExpression, LetExpression, ListGet, MapGet, MethodCall, Assignment, FieldGet, FunctionCall, IfElseExpression, IfExpression, LetExpression, ListGet,
NamedParameter, Stop, Variable, MapGet, MethodCall, NamedParameter, Stop, Variable,
}; };
use crate::compiler::tokens::TokenType::{ use crate::compiler::tokens::TokenType::{
Bang, Bool, Char, Colon, DateTime, Dot, Else, Eof, Eol, Equal, False, FloatingPoint, Fn, For, 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]) { } else if self.match_token(&[TokenType::Pipe]) {
self.guard_declaration(symbol_table) self.guard_declaration(symbol_table)
} else { } else {
self.statement(symbol_table) self.expr_statement(symbol_table)
} }
} }
@ -284,15 +284,26 @@ impl AstCompiler {
Ok(Statement::FunctionStmt { function }) Ok(Statement::FunctionStmt { function })
} }
fn statement(&mut self, symbol_table: &mut SymbolTable) -> Stmt { fn inc_indent(&mut self) {
if self.match_token(&[For]) { self.indent.push(self.indent.last().unwrap() + 1);
self.for_statement(symbol_table)
} else {
self.expr_statement(symbol_table)
}
} }
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."))?; let loop_var = self.consume(&Identifier, Expected("loop variable name."))?;
self.consume(&In, Expected("'in' after loop variable name."))?; self.consume(&In, Expected("'in' after loop variable name."))?;
let range = self.expression(symbol_table)?; let range = self.expression(symbol_table)?;
@ -301,27 +312,14 @@ impl AstCompiler {
self.inc_indent(); self.inc_indent();
let body = self.compile(symbol_table)?; let body = self.compile(symbol_table)?;
Ok(Statement::ForStatement { Ok(Expression::ForStatement {
loop_var, loop_var,
range, range: Box::new(range),
body, 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 { fn let_exp(&mut self, symbol_table: &mut SymbolTable) -> Expr {
if self.match_token(&[Let]) {
if self.peek().token_type.is_type() { if self.peek().token_type.is_type() {
return Err(self.raise(CompilerError::KeywordNotAllowedAsIdentifier( return Err(self.raise(CompilerError::KeywordNotAllowedAsIdentifier(
self.peek().token_type.clone(), self.peek().token_type.clone(),
@ -358,9 +356,6 @@ impl AstCompiler {
} else { } else {
Err(self.raise(UninitializedVariable))? Err(self.raise(UninitializedVariable))?
} }
} else {
self.expression(symbol_table)
}
} }
fn expression(&mut self, symbol_table: &mut SymbolTable) -> Expr { fn expression(&mut self, symbol_table: &mut SymbolTable) -> Expr {
@ -499,20 +494,23 @@ impl AstCompiler {
self.inc_indent(); self.inc_indent();
let then_branch = self.compile(symbol_table)?; 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(&Else, Expected("'else' after if condition."))?;
self.consume(&Colon, Expected("':' after 'else'."))?; self.consume(&Colon, Expected("':' after 'else'."))?;
self.inc_indent(); self.inc_indent();
Some(self.compile(symbol_table)?)
Ok(IfElseExpression {
condition: Box::new(condition),
then_branch,
else_branch: Some(self.compile(symbol_table)?),
})
} else { } else {
None
};
Ok(IfExpression { Ok(IfExpression {
condition: Box::new(condition), condition: Box::new(condition),
then_branch, then_branch,
else_branch,
}) })
}
} else { } else {
self.get(symbol_table) self.get(symbol_table)
} }
@ -854,11 +852,6 @@ pub enum Statement {
if_expr: Expression, if_expr: Expression,
then_expr: Expression, then_expr: Expression,
}, },
ForStatement {
loop_var: Token,
range: Expression,
body: Vec<Statement>,
},
} }
impl Statement { impl Statement {
@ -868,7 +861,6 @@ impl Statement {
Statement::FunctionStmt { function, .. } => function.name.line, Statement::FunctionStmt { function, .. } => function.name.line,
Statement::ObjectStmt { name, .. } => name.line, Statement::ObjectStmt { name, .. } => name.line,
Statement::GuardStatement { if_expr, .. } => if_expr.line(), Statement::GuardStatement { if_expr, .. } => if_expr.line(),
Statement::ForStatement { loop_var, .. } => loop_var.line,
} }
} }
} }
@ -973,6 +965,10 @@ pub enum Expression {
IfExpression { IfExpression {
condition: Box<Expression>, condition: Box<Expression>,
then_branch: Vec<Statement>, then_branch: Vec<Statement>,
},
IfElseExpression {
condition: Box<Expression>,
then_branch: Vec<Statement>,
else_branch: Option<Vec<Statement>>, else_branch: Option<Vec<Statement>>,
}, },
LetExpression { LetExpression {
@ -980,6 +976,11 @@ pub enum Expression {
var_type: TokenType, var_type: TokenType,
initializer: Box<Expression>, initializer: Box<Expression>,
}, },
ForStatement {
loop_var: Token,
range: Box<Expression>,
body: Vec<Statement>,
},
} }
impl Expression { impl Expression {
@ -1002,7 +1003,9 @@ impl Expression {
ListGet { .. } => 0, ListGet { .. } => 0,
FieldGet { .. } => 0, FieldGet { .. } => 0,
IfExpression { condition, .. } => condition.line(), IfExpression { condition, .. } => condition.line(),
IfElseExpression { condition, .. } => condition.line(),
LetExpression { name, .. } => name.line, LetExpression { name, .. } => name.line,
Expression::ForStatement { loop_var, .. } => loop_var.line,
} }
} }
} }

View file

@ -2,11 +2,7 @@ use crate::compiler::ast_pass::{Expression, Parameter, Statement};
use crate::builtins::lookup; use crate::builtins::lookup;
use crate::errors::CompilerError; use crate::errors::CompilerError;
use crate::errors::CompilerError::{IncompatibleTypes, UndeclaredVariable}; use crate::errors::CompilerError::{IncompatibleTypes, UndeclaredVariable};
use crate::compiler::tokens::TokenType::{ 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};
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::{Token, TokenType}; use crate::compiler::tokens::{Token, TokenType};
use log::debug; use log::debug;
use std::collections::HashMap; use std::collections::HashMap;
@ -218,13 +214,14 @@ pub fn infer_type(expr: &Expression, symbols: &HashMap<String, Symbol>) -> Token
} }
} }
Expression::Stop { .. } => Unknown, Expression::Stop { .. } => Unknown,
// Expression::PathMatch { .. } => Unknown,
Expression::NamedParameter { .. } => Unknown, Expression::NamedParameter { .. } => Unknown,
Expression::ListGet { .. } => Unknown, Expression::ListGet { .. } => Unknown,
Expression::MapGet { .. } => Unknown, Expression::MapGet { .. } => Unknown,
Expression::FieldGet { .. } => Unknown, Expression::FieldGet { .. } => Unknown,
Expression::Range { lower, .. } => infer_type(lower, symbols), Expression::Range { lower, .. } => infer_type(lower, symbols),
Expression::IfExpression { .. } => Unknown, Expression::IfExpression { .. } => Unknown,
Expression::LetExpression { initializer,.. } => infer_type(initializer, symbols), Expression::IfElseExpression { .. } => Unknown,
Expression::LetExpression { .. } => Void,
Expression::ForStatement { .. } => Void,
} }
} }