control flow
This commit is contained in:
71
parser.v
71
parser.v
@@ -16,14 +16,14 @@ enum Precedence {
|
||||
}
|
||||
|
||||
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 }
|
||||
.dot { .access }
|
||||
else { .lowest }
|
||||
}
|
||||
return match tok_type {
|
||||
.equals, .plus_eq, .minus_eq, .star_eq, .slash_eq { .assignment }
|
||||
.eq_eq, .not_eq, .less_eq, .greater_eq, .less, .greater { .comparison }
|
||||
.plus, .minus { .sum }
|
||||
.star, .slash { .product }
|
||||
.dot { .access }
|
||||
else { .lowest }
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------- Symbol Table
|
||||
@@ -194,7 +194,7 @@ struct FnCall {
|
||||
|
||||
// ------------------------------------------- Statements
|
||||
|
||||
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl | Param | ClassDecl
|
||||
type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | IfStmt | ElseStmt | ElifStmt | FuncDecl | Param | ClassDecl
|
||||
|
||||
struct VarDecl {
|
||||
name string
|
||||
@@ -227,6 +227,20 @@ struct Block {
|
||||
stmts []Stmt
|
||||
}
|
||||
|
||||
struct IfStmt {
|
||||
condition Expr
|
||||
block Block
|
||||
}
|
||||
|
||||
struct ElseStmt {
|
||||
block Block
|
||||
}
|
||||
|
||||
struct ElifStmt {
|
||||
condition Expr
|
||||
block Block
|
||||
}
|
||||
|
||||
struct Param {
|
||||
name string
|
||||
type string
|
||||
@@ -425,11 +439,9 @@ fn (mut p Parser) parse_print() PrintExpr {
|
||||
}
|
||||
|
||||
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)}")
|
||||
}
|
||||
@@ -483,7 +495,7 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
|
||||
BinaryExpr {
|
||||
p.check_binary_expr_types(expr)
|
||||
left_t := p.get_expr_type(expr.left)
|
||||
if expr.op in ['<=', '==', '>=', '!='] {
|
||||
if expr.op in ['<=', '==', '>=', '!=', '<', '>'] {
|
||||
'bool'
|
||||
} else {
|
||||
left_t
|
||||
@@ -548,6 +560,9 @@ fn (mut p Parser) parse_statement() Stmt {
|
||||
.kw_fn {return p.parse_func_decl()}
|
||||
.lbracket {return p.parse_block(false)}
|
||||
.kw_class {return p.parse_class()}
|
||||
.kw_if {return p.parse_if()}
|
||||
.kw_else {return p.parse_else()}
|
||||
.kw_elif {return p.parse_elif()}
|
||||
else {return p.parse_expr_stmt()}
|
||||
}
|
||||
}
|
||||
@@ -693,13 +708,42 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt {
|
||||
|
||||
expr := p.parse_expr(.lowest)
|
||||
|
||||
p.next()
|
||||
p.expect(.semicolon)
|
||||
|
||||
return ReturnStmt {
|
||||
expr: expr
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_if() IfStmt {
|
||||
p.expect(.kw_if)
|
||||
cond := p.parse_expr(.lowest)
|
||||
if p.get_expr_type(cond) != 'bool' {
|
||||
parse_error('If condition must be of type bool')
|
||||
}
|
||||
block := p.parse_block(false)
|
||||
|
||||
return IfStmt {cond, block}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_else() ElseStmt {
|
||||
p.expect(.kw_else)
|
||||
block := p.parse_block(false)
|
||||
|
||||
return ElseStmt {block}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_elif() ElifStmt {
|
||||
p.expect(.kw_elif)
|
||||
cond := p.parse_expr(.lowest)
|
||||
if p.get_expr_type(cond) != 'bool' {
|
||||
parse_error('If condition must be of type bool')
|
||||
}
|
||||
block := p.parse_block(false)
|
||||
|
||||
return ElifStmt {cond, block}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_expr_stmt() ExprStmt {
|
||||
expr := p.parse_expr(.lowest)
|
||||
p.expect(.semicolon)
|
||||
@@ -729,7 +773,6 @@ fn (mut p Parser) parse_block(no_scope bool) Block {
|
||||
|
||||
p.expect(.rbracket)
|
||||
|
||||
|
||||
return_stmts := (statements.filter(it is ReturnStmt).map(it as ReturnStmt))
|
||||
if return_stmts.len > 0 && (return_stmts.len > 1 || Stmt(return_stmts[0]) != statements[statements.len - 1]) {
|
||||
parse_error("Unexpected use of return. Unreachable code")
|
||||
|
||||
Reference in New Issue
Block a user