Create parser for if statements

This commit is contained in:
Slendi 2024-02-08 15:41:01 +02:00
parent d8b6505a89
commit f51a8817aa
3 changed files with 53 additions and 5 deletions

View File

@ -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
}

View File

@ -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) }

View File

@ -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")