Files
honey/source/ast/ast.hon
T
2026-08-05 22:07:55 +02:00

70 lines
1.6 KiB
Plaintext

import "@source/lexer"
hide TokenId :: alias lexer.TokenId
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
}
}