Add declaration parsing

This commit is contained in:
Slendi 2024-02-09 01:40:52 +02:00
parent 8c8a395193
commit 90a495ba1b
5 changed files with 116 additions and 7 deletions

View File

@ -25,6 +25,7 @@ NodeKind :: enum {
Use, Use,
If, If,
VariableDeclaration,
} }
Node :: struct { Node :: struct {
@ -116,6 +117,7 @@ node_print :: proc(node: ^Node, indent := 0) {
} }
if node == nil { if node == nil {
fmt.println("nil") fmt.println("nil")
return
} }
fmt.printf("{}: {} ", node.kind, "TODO") fmt.printf("{}: {} ", node.kind, "TODO")
@ -195,3 +197,21 @@ node_create_if :: proc(range: TextRange, condition, then, else_: ^Node) -> (ret:
return return
} }
node_create_variable :: proc(range: TextRange, name, type_, value: ^Node, is_const: bool) -> (ret: ^Node) {
fmt.printf("Creating variable declaration for {} with value {}\n", name.value.([dynamic]u8), value)
ret = new(Node)
ret^ = {
kind = .VariableDeclaration,
range = range,
children = { name, type_, value },
value = is_const,
}
//if value != nil {
// fmt.printf("Appending value to variable declaration\n")
// append(&ret.children, value)
//}
return
}

View File

@ -181,6 +181,7 @@ lexer_next :: proc(lexer: ^Lexer) -> (ret: Token) {
case '?': ret = token_create(.Question, crange) case '?': ret = token_create(.Question, crange)
case ':': ret = token_create(.Colon, crange) case ':': ret = token_create(.Colon, crange)
case '.': ret = token_create(.Dot, crange) case '.': ret = token_create(.Dot, crange)
case ',': ret = token_create(.Comma, crange)
case ';': ret = token_create(.Semicolon, crange) case ';': ret = token_create(.Semicolon, crange)
case '"': ret = lexer_read_string(lexer, .String, '\"') case '"': ret = lexer_read_string(lexer, .String, '\"')
@ -276,6 +277,7 @@ lexer_read_identifier :: proc(lexer: ^Lexer) -> Token {
else if compare_dyn_arr_string(&str, "ret") { return token_create(.Ret, crange) } else if compare_dyn_arr_string(&str, "ret") { return token_create(.Ret, crange) }
else if compare_dyn_arr_string(&str, "static") { return token_create(.Static, crange) } else if compare_dyn_arr_string(&str, "static") { return token_create(.Static, crange) }
else if compare_dyn_arr_string(&str, "defer") { return token_create(.Defer, crange) } else if compare_dyn_arr_string(&str, "defer") { return token_create(.Defer, crange) }
else if compare_dyn_arr_string(&str, "let") { return token_create(.Let, crange) }
else if compare_dyn_arr_string(&str, "and") { return token_create(.And, crange) } else if compare_dyn_arr_string(&str, "and") { return token_create(.And, crange) }
else if compare_dyn_arr_string(&str, "or") { return token_create(.Or, crange) } else if compare_dyn_arr_string(&str, "or") { return token_create(.Or, crange) }

View File

@ -53,11 +53,19 @@ 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 {
if accept(parser, .Let) {
ret := parser_parse_definitions(parser)
expect(parser, .Semicolon)
for stmt in ret {
append(&statements, stmt)
}
} else {
stmt := parser_parse_statement(parser) stmt := parser_parse_statement(parser)
if stmt != nil { if stmt != nil {
append(&statements, stmt) append(&statements, stmt)
} }
} }
}
expect(parser, end) expect(parser, end)
return node_create_block(range, statements) return node_create_block(range, statements)
} }
@ -80,6 +88,76 @@ parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) {
return return
} }
@(private = "file")
parser_parse_type :: proc(parser: ^Parser) -> (ret: ^Node) {
// FIXME: Add more types
range := parser.tok.range
if parser.tok.kind == .Identifier {
ret = node_create_value(.Identifier, range, parser.tok.value.([dynamic]u8))
parser_next(parser)
} else {
append(&g_message_list, message_create(
.Error,
fmt.aprintf("Expected type, got {} at {}", parser.tok.kind, "TODO"),
parser.tok.range))
ret = nil
}
return
}
@(private = "file")
parser_parse_definitions :: proc(parser: ^Parser, end := TokenKind.Semicolon) -> [dynamic]^Node {
range := parser.tok.range
vars : [dynamic]^Node
type : ^Node = nil
are_constants := false
uninitialized := false
for parser.tok.kind != end && parser.tok.kind != .EOF {
names := [dynamic][dynamic]u8{}
for parser.tok.kind == .Identifier {
tok := parser.tok
if !expect(parser, .Identifier) {
break
}
append(&names, tok.value.([dynamic]u8))
}
expect(parser, .Colon)
if parser.tok.kind != .Colon && parser.tok.kind != .Assign {
type = parser_parse_type(parser)
}
if accept(parser, .Assign) {
are_constants = false
} else if accept(parser, .Colon) {
are_constants = true
} else {
uninitialized = true
}
for i in 0..<len(names) {
value : ^Node = nil
if uninitialized == false {
value = parser_parse_expression(parser)
}
fmt.printf("value: {}\n", value)
name_node := node_create_value(.Identifier, range, names[i])
append(&vars, node_create_variable(range, name_node, type, value, are_constants))
}
if !accept(parser, .Comma) {
break
}
type = nil
are_constants = false
uninitialized = false
}
return vars
}
@(private = "file") @(private = "file")
parser_parse_use_statement :: proc(parser: ^Parser) -> ^Node { parser_parse_use_statement :: proc(parser: ^Parser) -> ^Node {
range := parser.tok.range range := parser.tok.range

View File

@ -4,6 +4,11 @@ use lib "directory/long_library_name"
fmt.printf "%d + %d = %d File length: %d" a b a + b (io.file_size "file.txt") fmt.printf "%d + %d = %d File length: %d" a b a + b (io.file_size "file.txt")
fmt.println "Hello world!" fmt.println "Hello world!"
let a := 123
let uninitialized : u32
let multiple variables here : u32 = 1 2 3
let string : str, number : i32
if a == 1 { if a == 1 {
lol lol
} elif b == 2 { } elif b == 2 {

View File

@ -19,7 +19,6 @@ TokenKind :: enum {
Type, Type,
Use, Use,
Pub, Pub,
Let,
Mut, Mut,
As, As,
In, In,
@ -34,6 +33,7 @@ TokenKind :: enum {
Ret, Ret,
Static, Static,
Defer, Defer,
Let,
// Logical Operators Keywords // Logical Operators Keywords
And, And,
@ -80,6 +80,7 @@ TokenKind :: enum {
Colon, Colon,
Arrow, Arrow,
Dot, Dot,
Comma,
// Other // Other
Semicolon, Semicolon,
@ -96,6 +97,7 @@ TextRange :: struct {
} }
TokenValue :: union { TokenValue :: union {
bool,
u64, u64,
f64, f64,
[dynamic]u8, [dynamic]u8,
@ -140,3 +142,5 @@ token_create_f64 :: proc(kind: TokenKind, value: f64, range: TextRange) -> Token
}; };
} }