basic One2C code gen

This commit is contained in:
uan
2026-02-04 21:04:58 +01:00
parent 541d3c7c7f
commit ff30ef8153
7 changed files with 206 additions and 25 deletions

View File

@@ -2,6 +2,28 @@ module main
import term
// ------------------------------------------- Precedence
enum Precedence {
lowest
assignment // = , +=, -=
comparison // ==, !=, <, >
sum // +, -
product // *, /
prefix // -x, !x
call // function()
}
fn (p Parser) get_precedence(tok_type TokenType) Precedence {
return match tok_type {
.equals, .plus_eq, .minus_eq, .star_eq, .slash_eq { .assignment }
.eq_eq, .not_eq, .less_eq, .greater_eq { .comparison }
.plus, .minus { .sum }
.star, .slash { .product }
else { .lowest }
}
}
// ------------------------------------------- Symbol Table
type SymbolInfo = VarSymbolInfo | FuncSymbolInfo
@@ -70,7 +92,7 @@ fn (mut s SymbolTable) is_in_global_scope() bool {
// ------------------------------------------- Expressions
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr
struct VoidExpr {}
@@ -118,6 +140,11 @@ struct ParenExpr {
expr Expr
}
struct PrintExpr {
expr Expr
type string
}
// ------------------------------------------- Statements
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl
@@ -139,7 +166,7 @@ struct ExprStmt {
}
struct ReturnStmt {
value Expr
expr Expr
}
struct Block {
@@ -210,20 +237,20 @@ fn (mut p Parser) parse_primary() Expr {
.identifier {p.parse_ident(token.text)}
.type {p.parse_type(token.text)}
.lparen {p.parse_paren()}
.kw_print {p.parse_print()}
else {parse_error("Unexpected Token")}
}
}
fn (mut p Parser) parse_expr() Expr {
mut left := p.parse_primary()
fn (mut p Parser) parse_expr(prec Precedence) Expr {
mut expr := p.parse_primary()
match p.peek().type {
.plus, .minus, .star, .slash, .equals, .eq_eq, .not_eq, .less_eq, .greater_eq,
.plus_eq, .minus_eq, .star_eq, .slash_eq {
return p.parse_binary(left, p.peek().text)
}
else {return left}
for int(prec) < int(p.get_precedence(p.peek().type)) {
op_tok := p.next()
expr = p.parse_binary(expr, op_tok.text, p.get_precedence(op_tok.type))
}
return expr
}
fn (mut p Parser) parse_ident(ident string) Expr {
@@ -233,10 +260,19 @@ fn (mut p Parser) parse_ident(ident string) Expr {
}
}
fn (mut p Parser) parse_binary(left Expr, op string) BinaryExpr {
p.next()
right := p.parse_expr()
fn (mut p Parser) parse_print() PrintExpr {
p.expect(.lparen)
expr := p.parse_expr(.lowest)
p.expect(.rparen)
return PrintExpr{expr: expr, type: p.get_expr_type(expr)}
}
fn (mut p Parser) parse_binary(left Expr, op string, prec Precedence) BinaryExpr {
//p.next()
right := p.parse_expr(prec)
binary_expr := BinaryExpr{left, op, right}
if !p.is_op_valid_for_type(p.get_expr_type(left), op) {
parse_error("Illegal operation ${op} for type ${p.get_expr_type(left)}")
}
@@ -248,7 +284,7 @@ fn (mut p Parser) parse_type(type string) Expr {
if p.peek().type == .lparen {
p.next()
expr := p.parse_expr()
expr := p.parse_expr(.lowest)
p.expect(.rparen)
return TypeCast {
@@ -261,7 +297,7 @@ fn (mut p Parser) parse_type(type string) Expr {
}
fn (mut p Parser) parse_paren() ParenExpr {
expr := p.parse_expr()
expr := p.parse_expr(.lowest)
p.expect(.rparen)
return ParenExpr{expr: expr}
}
@@ -356,7 +392,7 @@ fn (mut p Parser) parse_var_decl() VarDecl {
}
p.expect(.equals)
val := p.parse_expr()
val := p.parse_expr(.lowest)
if type_tok.text == 'void' {
parse_error("Cannot declare a variable of type void")
@@ -402,9 +438,9 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
return_stmts := p.get_return_stmts_recursive(block)
for return_stmt in return_stmts {
if p.get_expr_type(return_stmt.value) != type_tok.text {
if p.get_expr_type(return_stmt.expr) != type_tok.text {
parse_error("Mismatch between declared return type (${type_tok.text}) \
and actual return type (${p.get_expr_type(return_stmt.value)})")
and actual return type (${p.get_expr_type(return_stmt.expr)})")
}
}
@@ -437,12 +473,12 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt {
p.expect(.semicolon)
}
return ReturnStmt {
value: expr
expr: expr
}
}
fn (mut p Parser) parse_expr_stmt() ExprStmt {
expr := p.parse_expr()
expr := p.parse_expr(.lowest)
p.expect(.semicolon)
return ExprStmt {