type cast
This commit is contained in:
48
parser.v
48
parser.v
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user