comparison lwcc/tree.c @ 495:5b8871fd7503

Merged previous lwcc development branch into mainline.
author William Astle <lost@l-w.ca>
date Mon, 05 Aug 2019 21:27:09 -0600
parents a3e277c58df9
children 1bd2d590d734
comparison
equal deleted inserted replaced
493:6073f4a33475 495:5b8871fd7503
1 /*
2 lwcc/tree.c
3
4 Copyright © 2013 William Astle
5
6 This file is part of LWTOOLS.
7
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation, either version 3 of the License, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <stdarg.h>
23 #include <string.h>
24 #include <lw_alloc.h>
25 #include <lw_string.h>
26
27 #include "tree.h"
28
29 static char *node_names[] = {
30 "NONE",
31 "PROGRAM",
32 "DECL",
33 "TYPE_CHAR",
34 "TYPE_SHORT",
35 "TYPE_INT",
36 "TYPE_LONG",
37 "TYPE_LONGLONG",
38 "IDENT",
39 "TYPE_PTR",
40 "TYPE_SCHAR",
41 "TYPE_UCHAR",
42 "TYPE_USHORT",
43 "TYPE_UINT",
44 "TYPE_ULONG",
45 "TYPE_ULONGLONG",
46 "TYPE_VOID",
47 "TYPE_FLOAT",
48 "TYPE_DOUBLE",
49 "TYPE_LDOUBLE",
50 "FUNDEF",
51 "FUNDECL",
52 "FUNARGS",
53 "BLOCK",
54 };
55
56
57
58 node_t *node_create(int type, ...)
59 {
60 node_t *r;
61 int nargs = 0;
62 va_list args;
63
64 va_start(args, type);
65 r = lw_alloc(sizeof(node_t));
66 memset(r, 0, sizeof(node_t));
67 r -> type = type;
68
69 switch (type)
70 {
71 case NODE_DECL:
72 nargs = 2;
73 break;
74
75 case NODE_TYPE_PTR:
76 nargs = 1;
77 break;
78
79 case NODE_IDENT:
80 r -> strval = lw_strdup(va_arg(args, char *));
81 break;
82
83 case NODE_FUNDEF:
84 nargs = 4;
85 break;
86
87 case NODE_FUNDECL:
88 nargs = 3;
89 break;
90 }
91
92 while (nargs--)
93 {
94 node_addchild(r, va_arg(args, node_t *));
95 }
96 va_end(args);
97 return r;
98 }
99
100 void node_destroy(node_t *node)
101 {
102 node_t *n;
103
104 while (node -> children)
105 {
106 n = node -> children -> next_child;
107 node_destroy(node -> children);
108 node -> children = n;
109 }
110 lw_free(node -> strval);
111 lw_free(node);
112 }
113
114 void node_addchild(node_t *node, node_t *nn)
115 {
116 node_t *tmp;
117
118 if (!nn)
119 return;
120
121 nn -> parent = node;
122 nn -> next_child = NULL;
123 if (node -> children)
124 {
125 for (tmp = node -> children; tmp -> next_child; tmp = tmp -> next_child)
126 /* do nothing */ ;
127 tmp -> next_child = nn;
128 }
129 else
130 {
131 node -> children = nn;
132 }
133 }
134
135 void node_removechild(node_t *node, node_t *nn)
136 {
137 node_t **pp;
138 node_t *np;
139
140 if (!node)
141 node = nn -> parent;
142
143 pp = &(node -> children);
144 for (np = node -> children; np; np = np -> next_child)
145 {
146 if (np -> next_child == nn)
147 break;
148 pp = &((*pp) -> next_child);
149 }
150 if (!np)
151 return;
152
153 *pp = nn -> next_child;
154 nn -> parent = NULL;
155 nn -> next_child = NULL;
156 }
157
158 void node_removechild_destroy(node_t *node, node_t *nn)
159 {
160 node_removechild(node, nn);
161 node_destroy(nn);
162 }
163
164 static void node_display_aux(node_t *node, FILE *f, int level)
165 {
166 node_t *nn;
167 int i;
168
169 for (i = 0; i < level * 4; i++)
170 fputc(' ', f);
171 fprintf(f, "(%s ", node_names[node -> type]);
172 if (node -> strval)
173 fprintf(f, "\"%s\" ", node -> strval);
174 fputc('\n', f);
175 for (nn = node -> children; nn; nn = nn -> next_child)
176 node_display_aux(nn, f, level + 1);
177 for (i = 0; i < level * 4; i++)
178 fputc(' ', f);
179 fputc(')', f);
180 fputc('\n', f);
181 }
182
183 void node_display(node_t *node, FILE *f)
184 {
185 node_display_aux(node, f, 0);
186 }