71 lines
1.6 KiB
Plaintext
71 lines
1.6 KiB
Plaintext
import "@source/lexer"
|
|
|
|
hide TokenId :: alias lexer.TokenId
|
|
hide Token :: alias lexer.Token
|
|
|
|
NodeId :: distinct u32
|
|
ExtraId :: distinct u32
|
|
|
|
NO_ID_NODE :: maxval!(NodeId)
|
|
NO_ID_EXTRA :: maxval!(ExtraId)
|
|
|
|
# unsafe access on its own; NodeKind serves as a the tag
|
|
# that determines the variant.
|
|
NodeData :: union {
|
|
token_id TokenId
|
|
node_id NodeId
|
|
extra_id ExtraId
|
|
}
|
|
|
|
Node :: struct {
|
|
kind NodeKind
|
|
main_token TokenId
|
|
|
|
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:
|
|
# * 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
|
|
}
|
|
|
|
# todo: render ast nodes as source code
|
|
|
|
render proc(node @Node, tokens []Token) void { }
|
|
|
|
render_literal proc(node @Node, tokens []Token, program []u8) []u8 ! lexer.ScanError {
|
|
tok :: tokens[node.main_token]
|
|
match node.kind {
|
|
.literal_int, .literal_float: {
|
|
result :: try lexer.scan_number(tok.start, program)
|
|
return program[tok.start..result.end]
|
|
}
|
|
.literal_string: {
|
|
result :: try lexer.scan_string(tok.start, program)
|
|
return program[tok.start..result.end]
|
|
}
|
|
else: unreachable
|
|
}
|
|
}
|