Create parser for if statements
This commit is contained in:
parent
d8b6505a89
commit
f51a8817aa
15
ast.odin
15
ast.odin
@ -20,6 +20,8 @@ NodeKind :: enum {
|
||||
Struct,
|
||||
Enum,
|
||||
Union,
|
||||
|
||||
If,
|
||||
}
|
||||
|
||||
Node :: struct {
|
||||
@ -134,3 +136,16 @@ node_print :: proc(node: ^Node, indent := 0) {
|
||||
}
|
||||
}
|
||||
|
||||
node_create_if :: proc(range: TextRange, condition, then, else_: ^Node) -> (ret: ^Node) {
|
||||
ret = new(Node)
|
||||
ret^ = {
|
||||
kind = .If,
|
||||
range = range,
|
||||
children = { condition, then },
|
||||
}
|
||||
if else_ != nil {
|
||||
append(&ret.children, else_)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -259,6 +259,7 @@ lexer_read_identifier :: proc(lexer: ^Lexer) -> Token {
|
||||
else if compare_dyn_arr_string(&str, "mut") { return token_create(.Mut, crange) }
|
||||
else if compare_dyn_arr_string(&str, "as") { return token_create(.As, crange) }
|
||||
else if compare_dyn_arr_string(&str, "in") { return token_create(.In, crange) }
|
||||
else if compare_dyn_arr_string(&str, "if") { return token_create(.If, crange) }
|
||||
else if compare_dyn_arr_string(&str, "else") { return token_create(.Else, crange) }
|
||||
else if compare_dyn_arr_string(&str, "elif") { return token_create(.Elif, crange) }
|
||||
else if compare_dyn_arr_string(&str, "for") { return token_create(.For, crange) }
|
||||
|
42
parser.odin
42
parser.odin
@ -51,17 +51,49 @@ parser_parse_block :: proc(parser: ^Parser, end: TokenKind) -> (ret: ^Node) {
|
||||
range := parser.tok.range
|
||||
statements : [dynamic]^Node
|
||||
for parser.tok.kind != end && parser.tok.kind != .EOF {
|
||||
append(&statements, parser_parse_statement(parser))
|
||||
stmt := parser_parse_statement(parser)
|
||||
if stmt != nil {
|
||||
append(&statements, stmt)
|
||||
}
|
||||
}
|
||||
expect(parser, end)
|
||||
return node_create_block(range, statements)
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
parser_parse_statement :: proc(parser: ^Parser) -> ^Node {
|
||||
ret := parser_parse_expression(parser)
|
||||
expect(parser, .Semicolon)
|
||||
return ret
|
||||
parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) {
|
||||
if accept(parser, .Semicolon) {
|
||||
ret = nil
|
||||
} else if parser.tok.kind == .If {
|
||||
range_beg := parser.tok.range
|
||||
expect(parser, .If)
|
||||
ret = parser_parse_if_statement(parser)
|
||||
ret.range.start = range_beg.start
|
||||
} else {
|
||||
ret = parser_parse_expression(parser)
|
||||
expect(parser, .Semicolon)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
parser_parse_if_statement :: proc(parser: ^Parser) -> ^Node {
|
||||
range := parser.tok.range
|
||||
expect(parser, .OpenParen)
|
||||
condition := parser_parse_expression(parser)
|
||||
expect(parser, .CloseParen)
|
||||
expect(parser, .OpenBrace)
|
||||
body := parser_parse_block(parser, .CloseBrace)
|
||||
if accept(parser, .Elif) {
|
||||
falsebody := parser_parse_if_statement(parser)
|
||||
return node_create_if(range, condition, body, falsebody)
|
||||
}
|
||||
if accept(parser, .Else) {
|
||||
expect(parser, .OpenBrace)
|
||||
falsebody := parser_parse_block(parser, .CloseBrace)
|
||||
return node_create_if(range, condition, body, falsebody)
|
||||
}
|
||||
return node_create_if(range, condition, body, nil)
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
|
Loading…
x
Reference in New Issue
Block a user