speedcat/ast.odin
2024-02-08 01:04:11 +02:00

137 lines
2.4 KiB
Odin

package main
import "core:fmt"
NodeKind :: enum {
Integer,
Float,
Character,
String,
Identifier,
Block,
BinaryExpression,
UnaryExpression,
FieldAccess,
IndexAccess,
FunctionCall,
Function,
Struct,
Enum,
Union,
}
Node :: struct {
kind: NodeKind,
range: TextRange,
children: [dynamic]^Node,
value: TokenValue,
value_token_kind: TokenKind,
}
node_create_value :: proc(kind: NodeKind, range: TextRange, value: TokenValue) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = kind,
range = range,
value = value,
}
return
}
node_create_block :: proc(range: TextRange, children: [dynamic]^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .Block,
range = range,
children = children,
}
return
}
node_create_binary :: proc(kind: TokenKind, range: TextRange, left: ^Node, right: ^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .BinaryExpression,
range = range,
children = { left, right },
value_token_kind = kind,
}
return
}
node_create_unary :: proc(kind: TokenKind, range: TextRange, operand: ^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .UnaryExpression,
range = range,
children = { operand },
value_token_kind = kind,
}
return
}
node_create_field_access :: proc(range: TextRange, left: ^Node, right: ^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .FieldAccess,
range = range,
children = { left, right },
}
return
}
node_create_index_access :: proc(range: TextRange, left: ^Node, right: ^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .IndexAccess,
range = range,
children = { left, right },
}
return
}
node_create_function_call :: proc(range: TextRange, name: ^Node, args: [dynamic]^Node) -> (ret: ^Node) {
ret = new(Node)
ret^ = {
kind = .FunctionCall,
range = range,
children = { name },
}
for arg in args {
append(&ret.children, arg)
}
return
}
node_print :: proc(node: ^Node, indent := 0) {
for i in 0..<indent {
fmt.printf(" ")
}
if node == nil {
fmt.println("nil")
}
fmt.printf("{}: {} ", node.kind, "TODO")
data, ok := node.value.([dynamic]u8)
if ok {
fmt.printf("\"")
for i in 0..<len(data) {
fmt.printf("%c", data[i])
}
fmt.printf("\" ")
} else {
fmt.printf("{} ", node.value)
}
if node.value_token_kind != .Invalid {
fmt.printf("{} ", node.value_token_kind)
}
fmt.println("")
for child in node.children {
node_print(child, indent + 1)
}
}