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,
|
Struct,
|
||||||
Enum,
|
Enum,
|
||||||
Union,
|
Union,
|
||||||
|
|
||||||
|
If,
|
||||||
}
|
}
|
||||||
|
|
||||||
Node :: struct {
|
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, "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, "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, "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, "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, "elif") { return token_create(.Elif, crange) }
|
||||||
else if compare_dyn_arr_string(&str, "for") { return token_create(.For, crange) }
|
else if compare_dyn_arr_string(&str, "for") { return token_create(.For, crange) }
|
||||||
|
40
parser.odin
40
parser.odin
@ -51,17 +51,49 @@ parser_parse_block :: proc(parser: ^Parser, end: TokenKind) -> (ret: ^Node) {
|
|||||||
range := parser.tok.range
|
range := parser.tok.range
|
||||||
statements : [dynamic]^Node
|
statements : [dynamic]^Node
|
||||||
for parser.tok.kind != end && parser.tok.kind != .EOF {
|
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)
|
expect(parser, end)
|
||||||
return node_create_block(range, statements)
|
return node_create_block(range, statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private = "file")
|
@(private = "file")
|
||||||
parser_parse_statement :: proc(parser: ^Parser) -> ^Node {
|
parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) {
|
||||||
ret := parser_parse_expression(parser)
|
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)
|
expect(parser, .Semicolon)
|
||||||
return ret
|
}
|
||||||
|
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")
|
@(private = "file")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user