1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
package ast
import "../token"
import "core:bytes"
THIRTY_TWO_KILOBYTES := 262144
Node :: union {
Program,
Statement,
Expression,
}
Program :: struct {
statements: []Statement,
}
Statement :: union {
Let_Statement,
Return_Statement,
}
Let_Statement :: struct {
token: token.Token,
name: Identifier,
value: Expression,
}
Return_Statement :: struct {
token: token.Token,
return_value: Expression,
}
Expression_Statement :: struct {
token: token.Token,
expression: Expression,
}
Expression :: union {
Identifier,
}
Identifier :: struct {
token: token.Token,
value: string,
}
token_literal :: proc(node: Node) -> (literal: string) {
switch n in node {
case Program:
if len(n.statements) > 0 {
stmt: Node = n.statements[0]
literal = token_literal(stmt)
}
case Statement:
switch s in n {
case Let_Statement:
literal = token.literal(s.token)
case Return_Statement:
literal = token.literal(s.token)
case Expression_Statement:
literal = token.literal(s.token)
}
case Expression:
switch e in n {
case Identifier:
literal = token.literal(e.token)
}
}
return literal
}
node_to_string :: proc(node: Node) -> string {
out: bytes.Buffer
bytes.buffer_init_allocator(&out, 4, THIRTY_TWO_KILOBYTES, context.temp_allocator)
switch n in node {
case Program:
for stmt in n {
bytes.buffer_write_string(&out, node_to_string(n))
}
case Statement:
switch s in n {
case Let_Statement:
bytes.buffer_write_string(&out, token.literal(s.token) + " ")
bytes.buffer_write_string(&out, node_to_string(s.name))
bytes.buffer_write_string(&out, " = ")
if s.value != nil {
bytes.buffer_write_string(&out, node_to_string(s.value))
}
bytes.buffer_write_string(&out, ";")
case Return_Statement:
bytes.buffer_write_string(&out, token.literal(s.token) + " ")
if s.return_value != nil {
bytes.buffer_write_string(&out, node_to_string(s.return_value))
}
case Expression_Statement:
if s.expression != nil {
bytes.buffer_write_string(&out, node_to_string(s.expression))
}
}
case Expression:
switch e in n {
case Identifier:
literal = token.literal(e.token)
}
}
return bytes.buffer_to_string(&out)
}
|