general decl parsing

This commit is contained in:
2026-08-02 22:31:33 +02:00
parent a0ba0865ff
commit 469415a5b4
2 changed files with 54 additions and 10 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ test import "@source/lexer"
program ::
`# literals
`x :: 123
`x int :: 123
main proc() void {
strpool.strings = strpool.init(mem.c_allocator)
+53 -9
View File
@@ -7,9 +7,10 @@ import "@std/enums/enummap"
import "@source/lexer"
NodeId :: distinct u32
ExtraId :: distinct NodeId
ExtraId :: distinct u32
NO_ID :: maxval!(NodeId)
NO_ID_NODE :: maxval!(NodeId)
NO_ID_EXTRA :: maxval!(ExtraId)
Diagnostic :: struct {
code ErrorCode
@@ -39,6 +40,7 @@ hide TokenId :: alias lexer.TokenId
hide TokenKind :: alias lexer.TokenKind
NodeData :: union {
token_id TokenId
node_id NodeId
extra_id ExtraId
}
@@ -47,17 +49,32 @@ Node :: struct {
kind NodeKind
main_token TokenId
data0 NodeData = NodeData{ node_id = NO_ID }
data1 NodeData = NodeData{ node_id = NO_ID }
data0 NodeData = NodeData{ node_id = NO_ID_NODE }
data1 NodeData = NodeData{ node_id = NO_ID_NODE }
}
NodeKind :: enum {
# LITERALS:
# * main_token: token literal
literal_int
literal_float
literal_string
# IDENTIFIER EXPR:
# * main_token: token literal
expr_identifier
expr_unary
expr_binary
decl
# DECL:
# * main_token: symbol name (identifier)
# * data0: ExtraId
# + extra[data0]: NodeId - type identifier node
# + extra[data0 + 1]: NodeId - initializer expression
# * data1: TokenId of either `::` or `=` indicating mutability
stmt_decl
invalid
}
@@ -94,21 +111,33 @@ parse_decl proc(state @mut State) NodeId ! ParseError {
ident_token :: state.next_token
state.next_token += 1
# check for type
# todo: make a parse_type proc for this
type_id :: if (state.tokens[state.next_token].kind == .ident)
try parse_primary(state)
else
NO_ID_NODE
# expect `::` (immutable assignment)
try expect(state, .double_colon)
mutability_tok_id :: state.next_token
state.next_token += 1
# expect expression
expr :: try parse_primary(state)
expr_id :: try parse_primary(state)
# expect statement terminator (newline)
try expect_either(state, &[.newline, .eof])
state.next_token += 1
extra_start :: try add_extra(&state.extra, type_id)
_ = try add_extra(&state.extra, expr_id)
decl :: try add_node(&state.nodes, Node{
kind = .decl,
kind = .stmt_decl,
main_token = ident_token,
data0 = NodeData{ node_id = expr },
data0 = NodeData{ extra_id = extra_start },
data1 = NodeData{ token_id = mutability_tok_id },
})
return decl
@@ -130,6 +159,10 @@ parse_primary proc(state @mut State) NodeId ! mem.AllocError {
kind = .literal_string,
main_token = start_token,
})
.ident: try add_node(&state.nodes, Node{
kind = .expr_identifier,
main_token = start_token,
})
else: try add_node(&state.nodes, Node{
kind = .invalid,
main_token = start_token,
@@ -153,6 +186,17 @@ hide add_node proc(nodes @mut std.ArrayList(Node), node Node) NodeId ! mem.Alloc
}
hide node_id proc(idx uint) NodeId {
debug.assert(u64(idx) < u64(NO_ID))
debug.assert(u64(idx) < u64(NO_ID_NODE))
return NodeId(idx)
}
hide add_extra proc(extra @mut std.ArrayList(NodeId), id_node NodeId) ExtraId ! mem.AllocError {
id_extra :: extra_id(extra.items.len)
try arraylist.append(extra, id_node)
return id_extra
}
hide extra_id proc(idx uint) ExtraId {
debug.assert(u64(idx) < u64(NO_ID_EXTRA))
return ExtraId(idx)
}