137 lines
2.4 KiB
Odin
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)
|
|
}
|
|
}
|
|
|