33@use "string" as string
44
55pub const NodeKind -> enum {
6+ NODE_PROGRAM,
67 NODE_NUMBER,
78 NODE_BINARY,
89 NODE_UNARY,
@@ -11,6 +12,11 @@ pub const NodeKind -> enum {
1112
1213pub const ASTNode -> struct { type: int };
1314
15+ pub const Program -> struct {
16+ base: ASTNode,
17+ nodes: *ASTNode,
18+ };
19+
1420pub const Number -> struct {
1521 base: ASTNode,
1622 value: int
@@ -34,27 +40,14 @@ pub const Group -> struct {
3440 expr: *ASTNode
3541};
3642
37- #takes_ownership
38- pub const free_ast -> fn (node: *ASTNode) void {
39- if (node == cast<*ASTNode>(0)) {
40- return;
41- }
42-
43- if (node.type == NodeKind::NODE_NUMBER) {
44- // nothing inside to free
45- } elif (node.type == NodeKind::NODE_BINARY) {
46- let bin_node: *Binary = cast<*Binary>(node);
47- free_ast(bin_node.left);
48- free_ast(bin_node.right);
49- } elif (node.type == NodeKind::NODE_UNARY) {
50- let unary_node: *Unary = cast<*Unary>(node);
51- free_ast(unary_node.operand);
52- } elif (node.type == NodeKind::NODE_GROUP) {
53- let group_node: *Group = cast<*Group>(node);
54- free_ast(group_node.expr);
55- }
43+ #returns_ownership
44+ pub const create_program_node -> fn (nodes: *ASTNode) *ASTNode {
45+ let node: *Program = cast<*Program>(alloc(sizeof<Program>));
46+ let base_node: *ASTNode = cast<*ASTNode>(node);
5647
57- free(node);
48+ base_node.type = NodeKind::NODE_PROGRAM;
49+ node.nodes = nodes;
50+ return cast<*ASTNode>(node);
5851}
5952
6053#returns_ownership
@@ -100,10 +93,39 @@ pub const create_group_node -> fn (expr: *ASTNode) *ASTNode {
10093 return cast<*ASTNode>(node);
10194}
10295
96+ #takes_ownership
97+ pub const free_ast -> fn (node: *ASTNode) void {
98+ if (node == cast<*ASTNode>(0)) {
99+ return;
100+ }
101+
102+ if (node.type == NodeKind::NODE_PROGRAM) {
103+ let program_node: *Program = cast<*Program>(node);
104+ free_ast(program_node.nodes);
105+ } elif (node.type == NodeKind::NODE_NUMBER) {
106+ // nothing inside to free
107+ } elif (node.type == NodeKind::NODE_BINARY) {
108+ let bin_node: *Binary = cast<*Binary>(node);
109+ free_ast(bin_node.left);
110+ free_ast(bin_node.right);
111+ } elif (node.type == NodeKind::NODE_UNARY) {
112+ let unary_node: *Unary = cast<*Unary>(node);
113+ free_ast(unary_node.operand);
114+ } elif (node.type == NodeKind::NODE_GROUP) {
115+ let group_node: *Group = cast<*Group>(node);
116+ free_ast(group_node.expr);
117+ }
118+
119+ free(node);
120+ }
121+
103122pub const print_ast -> fn (node: *ASTNode) void {
104123 if (node == cast<*ASTNode>(0)) { return; }
105124
106- if (node.type == NodeKind::NODE_NUMBER) {
125+ if (node.type == NodeKind::NODE_PROGRAM) {
126+ let program_node: *Program = cast<*Program>(node);
127+ print_ast(program_node.nodes);
128+ } elif (node.type == NodeKind::NODE_NUMBER) {
107129 let num_node: *Number = cast<*Number>(node);
108130 output(num_node.value);
109131 } elif (node.type == NodeKind::NODE_BINARY) {
@@ -128,19 +150,4 @@ pub const print_ast -> fn (node: *ASTNode) void {
128150 print_ast(group_node.expr);
129151 output(")");
130152 }
131- }
132-
133- pub const main -> fn () int {
134- let node: *ASTNode = create_unary_node('-',
135- create_group_node(
136- create_binary_node('*',
137- create_binary_node('+',
138- create_number_node(5),
139- create_number_node(3)),
140- create_number_node(2))));
141- print_ast(node);
142- output("\n");
143- free_ast(node);
144-
145- return 0;
146153}
0 commit comments