String literals, proper compound statement parsing.
[mcc.git] / stree.c
blobd723f26f16616953adf4882fa4e9498fb9546c99
1 #include "stree.h"
2 #include "scanner.h"
3 #include "cc.h"
4 #include "errors.h"
5 #include "stdlib.h"
6 #include "stdio.h"
7 #include "string.h"
8 #include "assert.h"
9 #include "bstr.h"
11 static const char *form_strtab[] = {
12 "NONE",
13 "BINOP",
14 "UNOP",
15 "FACTOR",
16 "TAG",
17 "ATOM",
18 "TYPE",
19 "FUNCTION",
20 "VARIABLE",
21 "PARAMETERS",
22 "BLOCK",
23 "STAT",
26 static int next_id = 1;
28 const char *stree_form_str(int form)
30 return form_strtab[form - STF_NONE];
33 struct stree *stree_create(void)
35 struct stree *st;
36 st = emalloc(sizeof(struct stree));
37 memset(st, 0, sizeof (struct stree));
38 st->id = next_id++;
39 return st;
42 void stree_append_child(struct stree *st_parent, struct stree *st_child)
44 struct stree *st_child_prev = st_parent->child;
45 if (!st_parent || !st_child)
46 return;
47 st_child->parent = st_parent;
48 if (st_child_prev){
49 // insert at end of child list
50 while (st_child_prev->next){
51 st_child_prev = st_child_prev->next;
53 st_child_prev->next = st_child;
54 st_child->prev = st_child_prev;
55 st_child->next = NULL;
56 } else {
57 // first child
58 st_parent->child = st_child;
59 st_child->prev = NULL;
60 st_child->next = NULL;
64 void stree_remove_child(struct stree *st_child)
66 struct stree *st_parent = st_child->parent;
67 if (st_child->prev){
68 st_child->prev->next = st_child->next;
69 } else {
70 st_parent->child = st_child->next;
72 if (st_child->next){
73 st_child->next->prev = st_child->prev;
75 st_child->prev = NULL;
76 st_child->next = NULL;
77 st_child->parent = NULL;
80 void stree_destroy(struct stree *st)
82 if (st){
83 // destroy children
84 struct stree *st_child = st->child,
85 *st_child_next;
87 while (st_child){
88 st_child_next = st_child->next;
89 stree_destroy(st_child);
90 st_child = st_child_next;
93 if (st->cv.type == CBT_STRING){
94 free(st->cv.v.string);
96 free(st);
100 void stree_next_child(struct stree *st, struct stree **pchild)
102 if (*pchild == NULL){
103 *pchild = st->child;
104 } else {
105 *pchild = (*pchild)->next;
109 // form a string representing 'node', for debug output
110 static char *make_type_str(struct stree *node)
112 char *s = NULL;
113 // is the type info valid?
114 switch (node->form){
115 case STF_VARIABLE:
116 case STF_FUNCTION:
117 case STF_TYPE:
118 // XXX: erm, use arrays perhaps?
119 if (node->btype.qualifiers & TQ_RESTRICT)
120 strdcat(&s, "restrict ");
121 if (node->btype.qualifiers & TQ_VOLATILE)
122 strdcat(&s, "volatile ");
123 if (node->btype.qualifiers & TQ_CONST)
124 strdcat(&s, "const ");
125 if (node->btype.qualifiers & TQ_SIGNED)
126 strdcat(&s, "signed ");
127 if (node->btype.qualifiers & TQ_UNSIGNED)
128 strdcat(&s, "unsigned ");
129 if (node->btype.qualifiers & TQ_LONG_LONG)
130 strdcat(&s, "long long ");
131 if (node->btype.qualifiers & TQ_LONG)
132 strdcat(&s, "long ");
133 if (node->btype.qualifiers & TQ_SHORT)
134 strdcat(&s, "short ");
135 switch (node->btype.base_type){
136 case BT_VOID:
137 strdcat(&s, "void");
138 break;
139 case BT_CHAR:
140 strdcat(&s, "char");
141 break;
142 case BT_INT:
143 strdcat(&s, "int");
144 break;
145 case BT_FLOAT:
146 strdcat(&s, "float");
147 break;
148 case BT_DOUBLE:
149 strdcat(&s, "double");
150 break;
151 case BT_POINTER:
152 strdcat(&s, "pointer");
153 // TODO: pointing to what?
154 break;
155 case BT_STRUCT:
156 strdcat(&s, "struct");
157 // TODO: more informations!
158 break;
160 break;
161 default:
162 break;
164 return s;
167 static void stree_dump_internal(struct cc *cc, struct stree_stack *stack, FILE *output)
169 struct stree_stack stack_item;
171 // dump this node
172 struct stree_stack *p = stack;
173 assert(p);
174 // locate bottom of stack
175 while (p->prev){
176 p = p->prev;
178 while (p && p->next){
179 if (p->st_node->next){
180 fprintf(output, " | ");
181 } else {
182 fprintf(output, " ");
184 p = p->next;
186 if (stack->st_node->next){
187 fprintf(output, " +--");
188 } else {
189 fprintf(output, " L--");
192 char *type_str = make_type_str(stack->st_node);
193 fprintf(output, "%d:%s [%s]%s%s\n", stack->st_node->id,
194 stree_form_str(stack->st_node->form),
195 lex_get_tok_str(&cc->lex, stack->st_node->tok, NULL),
196 type_str ? " : " : "",
197 type_str ? type_str : "");
198 free(type_str);
201 // and the children
202 stack_item.prev = stack;
203 stack_item.next = NULL;
204 stack->next = &stack_item;
205 stack_item.st_node = stack->st_node->child;
206 while (stack_item.st_node){
207 stree_dump_internal(cc, &stack_item, output);
208 stack_item.st_node = stack_item.st_node->next;
210 stack->next = NULL; // pop stack
214 void stree_dump(struct cc *cc, struct stree *st_root, FILE *output)
216 struct stree_stack stack_item;
217 if (!st_root){
218 fprintf(output, "[TREE:NULL]\n");
219 return;
221 stack_item.st_node = st_root;
222 stack_item.prev = NULL;
223 stack_item.next = NULL;
224 stree_dump_internal(cc, &stack_item, output);
227 struct stree *stree_right(struct stree *st)
229 struct stree *p = st->child;
230 while (p && p->next){
231 p = p->next;
233 return p;
236 int stree_child_count(struct stree *st)
238 int n = 0;
239 struct stree *child_st;
240 if (!st){
241 return 0;
243 child_st = st->child;
244 while (child_st){
245 n++;
246 child_st = child_st->next;
248 return n;
251 struct stree *stree_find_local(struct stree *scope, enum stree_form form, tok_t tok)
253 if (!scope)
254 return NULL;
255 struct stree *p = scope->child;
256 while (p && !(p->form == form && p->tok == tok)){
257 p = p->next;
259 return p;
262 struct stree *stree_get_child_by_form(struct stree *st, enum stree_form form)
264 struct stree *child_st;
265 child_st = st->child;
266 while (child_st && child_st->form != form){
267 child_st = child_st->next;
269 return child_st;