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 // ------------------------------------------- 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 type LiteralExpr = IntegerLiteral | RealLiteral | BoolLiteral
struct VoidExpr {} struct VoidExpr {}
@@ -105,6 +105,11 @@ struct Function {
name string name string
} }
struct TypeCast {
expr Expr
type string
}
// ------------------------------------------- Statements // ------------------------------------------- Statements
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl
@@ -194,8 +199,8 @@ fn (mut p Parser) parse_primary() Expr {
.real {RealLiteral{token.text.f32()}} .real {RealLiteral{token.text.f32()}}
.boolean {BoolLiteral{token.text == 'true'}} .boolean {BoolLiteral{token.text == 'true'}}
.identifier {Variable{token.text}} .identifier {Variable{token.text}}
.type {TypeExpr{token.text}}
.kw_fn {Function{token.text}} .kw_fn {Function{token.text}}
.type {p.parse_type(token.text)}
else {parse_error("Unexpected Token")} 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 { fn (mut p Parser) parse_binary(left Expr, op string) BinaryExpr {
p.next() p.next()
right := p.parse_expr() 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 { 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 return info.type
} }
TypeCast {expr.type}
else {"Tried getting type of unexpected Expr"} 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 // ------------------------------------------- Statements
@@ -269,6 +307,8 @@ fn (mut p Parser) parse_statement() Stmt {
} }
} }
fn (mut p Parser) parse_var_decl() VarDecl { fn (mut p Parser) parse_var_decl() VarDecl {
p.expect(.kw_let) p.expect(.kw_let)
@@ -350,7 +390,6 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt {
p.expect(.kw_return) p.expect(.kw_return)
token := p.peek() token := p.peek()
p.dump_token()
mut expr := Expr{} mut expr := Expr{}
expr = match token.type { expr = match token.type {
.integer {IntegerLiteral{token.text.int()}} .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 { fn (mut p Parser) parse_block(no_scope bool) Block {
p.expect(.lbracket) p.expect(.lbracket)

View File

@@ -1,9 +1,2 @@
fn foo() int { let a real = 5.1;
let y int = 2; let x real = 7.0 + real(int(a) + int(7.0));
let z int = y*2;
return y;
}
fn bar() real {
return 5.5;
}