type cast

This commit is contained in:
uan
2026-02-04 15:20:52 +01:00
parent 7eb9e021dd
commit 56d873d9d3
2 changed files with 46 additions and 13 deletions

View File

@@ -70,7 +70,7 @@ fn (mut s SymbolTable) is_in_global_scope() bool {
// ------------------------------------------- Expressions
type Expr = VoidExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function
type Expr = VoidExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast
type LiteralExpr = IntegerLiteral | RealLiteral | BoolLiteral
struct VoidExpr {}
@@ -105,6 +105,11 @@ struct Function {
name string
}
struct TypeCast {
expr Expr
type string
}
// ------------------------------------------- Statements
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl
@@ -194,8 +199,8 @@ fn (mut p Parser) parse_primary() Expr {
.real {RealLiteral{token.text.f32()}}
.boolean {BoolLiteral{token.text == 'true'}}
.identifier {Variable{token.text}}
.type {TypeExpr{token.text}}
.kw_fn {Function{token.text}}
.type {p.parse_type(token.text)}
else {parse_error("Unexpected Token")}
}
}
@@ -216,7 +221,27 @@ fn (mut p Parser) parse_expr() Expr {
fn (mut p Parser) parse_binary(left Expr, op string) BinaryExpr {
p.next()
right := p.parse_expr()
return BinaryExpr{left, op, right}
binary_expr := BinaryExpr{left, op, right}
if !p.is_op_valid_for_type(p.get_expr_type(binary_expr), op) {
parse_error("Illegal operation ${op} for type ${p.get_expr_type(binary_expr)}")
}
return binary_expr
}
fn (mut p Parser) parse_type(type string) Expr {
if p.peek().type == .lparen {
p.next()
expr := p.parse_expr()
p.expect(.rparen)
return TypeCast {
expr: expr
type: type
}
}
return TypeExpr {name: type}
}
fn (mut p Parser) get_expr_type(expr Expr) string {
@@ -240,8 +265,21 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
}
return info.type
}
TypeCast {expr.type}
else {"Tried getting type of unexpected Expr"}
}
}
fn (mut p Parser) is_op_valid_for_type(type string, op string) bool {
legal_ops := match type {
'int' {['+', '-', '*', '/', '<', '>', '=']}
'real' {['+', '-', '*', '/', '<', '>', '=']}
'bool' {['=']}
else {[]}
}
return op in legal_ops
}
// ------------------------------------------- Statements
@@ -269,6 +307,8 @@ fn (mut p Parser) parse_statement() Stmt {
}
}
fn (mut p Parser) parse_var_decl() VarDecl {
p.expect(.kw_let)
@@ -350,7 +390,6 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt {
p.expect(.kw_return)
token := p.peek()
p.dump_token()
mut expr := Expr{}
expr = match token.type {
.integer {IntegerLiteral{token.text.int()}}
@@ -378,6 +417,7 @@ fn (mut p Parser) parse_expr_stmt() ExprStmt {
}
}
fn (mut p Parser) parse_block(no_scope bool) Block {
p.expect(.lbracket)