Converted tabs to spaces, build into build/ dir
[mcc.git] / stree.c
blob343fa5fe19a89433a813090cd192927644a5425e
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 "TYPE",
18 "FUNCTION",
19 "VARIABLE",
20 "PARAMETERS",
23 static int next_id = 1;
25 const char *stree_form_str(int form)
27 return form_strtab[form - STF_NONE];
30 struct stree *stree_create(void)
32 struct stree *st;
33 st = emalloc(sizeof(struct stree));
34 memset(st, 0, sizeof (struct stree));
35 st->id = next_id++;
36 return st;
39 void stree_append_child(struct stree *st_parent, struct stree *st_child)
41 struct stree *st_child_prev = st_parent->child;
42 if (!st_parent || !st_child)
43 return;
44 st_child->parent = st_parent;
45 if (st_child_prev){
46 // insert at end of child list
47 while (st_child_prev->next){
48 st_child_prev = st_child_prev->next;
50 st_child_prev->next = st_child;
51 st_child->prev = st_child_prev;
52 st_child->next = NULL;
53 } else {
54 // first child
55 st_parent->child = st_child;
56 st_child->prev = NULL;
57 st_child->next = NULL;
61 void stree_remove_child(struct stree *st_child)
63 struct stree *st_parent = st_child->parent;
64 if (st_child->prev){
65 st_child->prev->next = st_child->next;
66 } else {
67 st_parent->child = st_child->next;
69 if (st_child->next){
70 st_child->next->prev = st_child->prev;
72 st_child->prev = NULL;
73 st_child->next = NULL;
74 st_child->parent = NULL;
77 void stree_destroy(struct stree *st)
79 if (st){
80 // destroy children
81 struct stree *st_child = st->child,
82 *st_child_next;
84 while (st_child){
85 st_child_next = st_child->next;
86 stree_destroy(st_child);
87 st_child = st_child_next;
90 free(st);
94 void stree_next_child(struct stree *st, struct stree **pchild)
96 if (*pchild == NULL){
97 *pchild = st->child;
98 } else {
99 *pchild = (*pchild)->next;
103 // form a string representing 'node', for debug output
104 static char *make_type_str(struct stree *node)
106 char *s = NULL;
107 // is the type info valid?
108 switch (node->form){
109 case STF_VARIABLE:
110 case STF_FUNCTION:
111 case STF_TYPE:
112 // XXX: erm, use arrays perhaps?
113 if (node->btype.qualifiers & TQ_RESTRICT)
114 strdcat(&s, "restrict ");
115 if (node->btype.qualifiers & TQ_VOLATILE)
116 strdcat(&s, "volatile ");
117 if (node->btype.qualifiers & TQ_CONST)
118 strdcat(&s, "const ");
119 if (node->btype.qualifiers & TQ_SIGNED)
120 strdcat(&s, "signed ");
121 if (node->btype.qualifiers & TQ_UNSIGNED)
122 strdcat(&s, "unsigned ");
123 if (node->btype.qualifiers & TQ_LONG_LONG)
124 strdcat(&s, "long long ");
125 if (node->btype.qualifiers & TQ_LONG)
126 strdcat(&s, "long ");
127 if (node->btype.qualifiers & TQ_SHORT)
128 strdcat(&s, "short ");
129 switch (node->btype.base_type){
130 case BT_VOID:
131 strdcat(&s, "void");
132 break;
133 case BT_CHAR:
134 strdcat(&s, "char");
135 break;
136 case BT_INT:
137 strdcat(&s, "int");
138 break;
139 case BT_FLOAT:
140 strdcat(&s, "float");
141 break;
142 case BT_DOUBLE:
143 strdcat(&s, "double");
144 break;
145 case BT_POINTER:
146 strdcat(&s, "pointer");
147 // TODO: pointing to what?
148 break;
149 case BT_STRUCT:
150 strdcat(&s, "struct");
151 // TODO: more informations!
152 break;
154 break;
155 default:
156 break;
158 return s;
161 static void stree_dump_internal(struct cc *cc, struct stree_stack *stack, FILE *output)
163 struct stree_stack stack_item;
165 // dump this node
166 struct stree_stack *p = stack;
167 assert(p);
168 // locate bottom of stack
169 while (p->prev){
170 p = p->prev;
172 while (p && p->next){
173 if (p->st_node->next){
174 fprintf(output, " | ");
175 } else {
176 fprintf(output, " ");
178 p = p->next;
180 if (stack->st_node->next){
181 fprintf(output, " +--");
182 } else {
183 fprintf(output, " L--");
186 char *type_str = make_type_str(stack->st_node);
187 fprintf(output, "%d:%s [%s]%s%s\n", stack->st_node->id,
188 stree_form_str(stack->st_node->form),
189 lex_get_tok_str(&cc->lex, stack->st_node->tok, NULL),
190 type_str ? " : " : "",
191 type_str ? type_str : "");
192 free(type_str);
195 // and the children
196 stack_item.prev = stack;
197 stack_item.next = NULL;
198 stack->next = &stack_item;
199 stack_item.st_node = stack->st_node->child;
200 while (stack_item.st_node){
201 stree_dump_internal(cc, &stack_item, output);
202 stack_item.st_node = stack_item.st_node->next;
204 stack->next = NULL; // pop stack
208 void stree_dump(struct cc *cc, struct stree *st_root, FILE *output)
210 struct stree_stack stack_item;
211 if (!st_root){
212 fprintf(output, "[TREE:NULL]\n");
213 return;
215 stack_item.st_node = st_root;
216 stack_item.prev = NULL;
217 stack_item.next = NULL;
218 stree_dump_internal(cc, &stack_item, output);
221 struct stree *stree_right(struct stree *st)
223 struct stree *p = st->child;
224 while (p && p->next){
225 p = p->next;
227 return p;
230 int stree_child_count(struct stree *st)
232 int n = 0;
233 struct stree *child_st;
234 if (!st){
235 return 0;
237 child_st = st->child;
238 while (child_st){
239 n++;
240 child_st = child_st->next;
242 return n;
245 struct stree *stree_find_local(struct stree *scope, enum stree_form form, tok_t tok)
247 if (!scope)
248 return NULL;
249 struct stree *p = scope->child;
250 while (p && !(p->form == form && p->tok == tok)){
251 p = p->next;
253 return p;
256 struct stree *stree_get_child_by_form(struct stree *st, enum stree_form form)
258 struct stree *child_st;
259 child_st = st->child;
260 while (child_st && child_st->form != form){
261 child_st = child_st->next;
263 return child_st;