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 :: program ::
`# literals `# literals
`x :: 123 `x int :: 123
main proc() void { main proc() void {
strpool.strings = strpool.init(mem.c_allocator) strpool.strings = strpool.init(mem.c_allocator)
+53 -9
View File
@@ -7,9 +7,10 @@ import "@std/enums/enummap"
import "@source/lexer" import "@source/lexer"
NodeId :: distinct u32 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 { Diagnostic :: struct {
code ErrorCode code ErrorCode
@@ -39,6 +40,7 @@ hide TokenId :: alias lexer.TokenId
hide TokenKind :: alias lexer.TokenKind hide TokenKind :: alias lexer.TokenKind
NodeData :: union { NodeData :: union {
token_id TokenId
node_id NodeId node_id NodeId
extra_id ExtraId extra_id ExtraId
} }
@@ -47,17 +49,32 @@ Node :: struct {
kind NodeKind kind NodeKind
main_token TokenId main_token TokenId
data0 NodeData = NodeData{ node_id = NO_ID } data0 NodeData = NodeData{ node_id = NO_ID_NODE }
data1 NodeData = NodeData{ node_id = NO_ID } data1 NodeData = NodeData{ node_id = NO_ID_NODE }
} }
NodeKind :: enum { NodeKind :: enum {
# LITERALS:
# * main_token: token literal
literal_int literal_int
literal_float literal_float
literal_string literal_string
# IDENTIFIER EXPR:
# * main_token: token literal
expr_identifier
expr_unary expr_unary
expr_binary 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 invalid
} }
@@ -94,21 +111,33 @@ parse_decl proc(state @mut State) NodeId ! ParseError {
ident_token :: state.next_token ident_token :: state.next_token
state.next_token += 1 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) # expect `::` (immutable assignment)
try expect(state, .double_colon) try expect(state, .double_colon)
mutability_tok_id :: state.next_token
state.next_token += 1 state.next_token += 1
# expect expression # expect expression
expr :: try parse_primary(state) expr_id :: try parse_primary(state)
# expect statement terminator (newline) # expect statement terminator (newline)
try expect_either(state, &[.newline, .eof]) try expect_either(state, &[.newline, .eof])
state.next_token += 1 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{ decl :: try add_node(&state.nodes, Node{
kind = .decl, kind = .stmt_decl,
main_token = ident_token, main_token = ident_token,
data0 = NodeData{ node_id = expr }, data0 = NodeData{ extra_id = extra_start },
data1 = NodeData{ token_id = mutability_tok_id },
}) })
return decl return decl
@@ -130,6 +159,10 @@ parse_primary proc(state @mut State) NodeId ! mem.AllocError {
kind = .literal_string, kind = .literal_string,
main_token = start_token, 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{ else: try add_node(&state.nodes, Node{
kind = .invalid, kind = .invalid,
main_token = start_token, 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 { 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) 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)
}