improve type printing
[cparser] / ast.c
1 #include <config.h>
2
3 #include "ast_t.h"
4 #include "type_t.h"
5
6 #include <assert.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "adt/error.h"
11
12 struct obstack ast_obstack;
13
14 static
15 void print_const(FILE *out, const const_t *cnst)
16 {
17         fprintf(out, "%d", cnst->value);
18 }
19
20 static
21 void print_string_literal(FILE *out, const string_literal_t *string_literal)
22 {
23         /* TODO escape " and non-printable chars */
24         fprintf(out, "\"%s\"", string_literal->value);
25 }
26
27 static
28 void print_call_expression(FILE *out, const call_expression_t *call)
29 {
30         print_expression(out, call->method);
31         fprintf(out, "(");
32         call_argument_t *argument = call->arguments;
33         int              first    = 1;
34         while(argument != NULL) {
35                 if(!first) {
36                         fprintf(out, ", ");
37                 } else {
38                         first = 0;
39                 }
40                 print_expression(out, argument->expression);
41
42                 argument = argument->next;
43         }
44         fprintf(out, ")");
45 }
46
47 static
48 void print_binary_expression(FILE *out, const binary_expression_t *binexpr)
49 {
50         fprintf(out, "(");
51         print_expression(out, binexpr->left);
52         fprintf(out, " ");
53         switch(binexpr->type) {
54         case BINEXPR_INVALID:
55                 fprintf(out, "INVOP");
56                 break;
57         case BINEXPR_ASSIGN:
58                 fprintf(out, "<-");
59                 break;
60         case BINEXPR_ADD:
61                 fprintf(out, "+");
62                 break;
63         case BINEXPR_SUB:
64                 fprintf(out, "-");
65                 break;
66         case BINEXPR_NOTEQUAL:
67                 fprintf(out, "/=");
68                 break;
69         case BINEXPR_EQUAL:
70                 fprintf(out, "=");
71                 break;
72         case BINEXPR_LESS:
73                 fprintf(out, "<");
74                 break;
75         case BINEXPR_LESSEQUAL:
76                 fprintf(out, "<=");
77                 break;
78         case BINEXPR_GREATER:
79                 fprintf(out, ">");
80                 break;
81         case BINEXPR_GREATEREQUAL:
82                 fprintf(out, ">=");
83                 break;
84         default:
85                 /* TODO: add missing ops */
86                 fprintf(out, "op%d", binexpr->type);
87                 break;
88         }
89         fprintf(out, " ");
90         print_expression(out, binexpr->right);
91         fprintf(out, ")");
92 }
93
94 void print_expression(FILE *out, const expression_t *expression)
95 {
96         switch(expression->type) {
97         case EXPR_INVALID:
98                 fprintf(out, "*invalid expression*");
99                 break;
100         case EXPR_CONST:
101                 print_const(out, (const const_t*) expression);
102                 break;
103         case EXPR_STRING_LITERAL:
104                 print_string_literal(out, (const string_literal_t*) expression);
105                 break;
106         case EXPR_CALL:
107                 print_call_expression(out, (const call_expression_t*) expression);
108                 break;
109         case EXPR_BINARY:
110                 print_binary_expression(out, (const binary_expression_t*) expression);
111                 break;
112         case EXPR_REFERENCE:
113         case EXPR_UNARY:
114         case EXPR_SELECT:
115         case EXPR_ARRAY_ACCESS:
116         case EXPR_SIZEOF:
117                 /* TODO */
118                 fprintf(out, "some expression of type %d", expression->type);
119                 break;
120         }
121 }
122
123 static
124 void print_compound_statement(FILE *out, int indent,
125                               const compound_statement_t *block)
126 {
127         statement_t *statement = block->first_statement;
128         while(statement != NULL) {
129                 print_statement(out, indent + 1, statement);
130
131                 statement = statement->next;
132         }
133 }
134
135 static
136 void print_return_statement(FILE *out, const return_statement_t *statement)
137 {
138         fprintf(out, "return ");
139         if(statement->return_value != NULL)
140                 print_expression(out, statement->return_value);
141 }
142
143 static
144 void print_expression_statement(FILE *out,
145                                 const expression_statement_t *statement)
146 {
147         print_expression(out, statement->expression);
148 }
149
150 static
151 void print_goto_statement(FILE *out, const goto_statement_t *statement)
152 {
153         fprintf(out, "goto ");
154         if(statement->label != NULL) {
155                 fprintf(out, "%s", statement->label->symbol->string);
156         } else {
157                 fprintf(out, "?%s", statement->label_symbol->string);
158         }
159 }
160
161 static
162 void print_label_statement(FILE *out, const label_statement_t *statement)
163 {
164         fprintf(out, ":%s", statement->symbol->string);
165 }
166
167 static
168 void print_if_statement(FILE *out, int indent, const if_statement_t *statement)
169 {
170         fprintf(out, "if ");
171         print_expression(out, statement->condition);
172         fprintf(out, ":\n");
173         if(statement->true_statement != NULL) {
174                 print_statement(out, indent, statement->true_statement);
175         }
176
177         if(statement->false_statement != NULL) {
178                 fprintf(out, "else:\n");
179                 print_statement(out, indent, statement->false_statement);
180         }
181 }
182
183 static
184 void print_declaration_statement(FILE *out,
185                                  const declaration_statement_t *statement)
186 {
187         (void) statement;
188         fprintf(out, "*declaration statement*");
189 }
190
191 void print_statement(FILE *out, int indent, const statement_t *statement)
192 {
193         for(int i = 0; i < indent; ++i)
194                 fprintf(out, "\t");
195
196         switch(statement->type) {
197         case STATEMENT_COMPOUND:
198                 print_compound_statement(out, indent,
199                                          (const compound_statement_t*) statement);
200                 break;
201         case STATEMENT_RETURN:
202                 print_return_statement(out, (const return_statement_t*) statement);
203                 break;
204         case STATEMENT_EXPRESSION:
205                 print_expression_statement(out,
206                                            (const expression_statement_t*) statement);
207                 break;
208         case STATEMENT_LABEL:
209                 print_label_statement(out, (const label_statement_t*) statement);
210                 break;
211         case STATEMENT_GOTO:
212                 print_goto_statement(out, (const goto_statement_t*) statement);
213                 break;
214         case STATEMENT_IF:
215                 print_if_statement(out, indent, (const if_statement_t*) statement);
216                 break;
217         case STATEMENT_DECLARATION:
218                 print_declaration_statement(out,
219                                             (const declaration_statement_t*) statement);
220                 break;
221         case STATEMENT_INVALID:
222         default:
223                 fprintf(out, "*invalid statement*");
224                 break;
225
226         }
227         fprintf(out, "\n");
228 }
229
230 #if 0
231 static
232 void print_method_parameters(FILE *out, const method_parameter_t *parameters,
233                              const method_type_t *method_type)
234 {
235         fprintf(out, "(");
236
237         int                            first          = 1;
238         const method_parameter_t      *parameter      = parameters;
239         const method_parameter_type_t *parameter_type
240                 = method_type->parameter_types;
241         while(parameter != NULL && parameter_type != NULL) {
242                 if(!first) {
243                         fprintf(out, ", ");
244                 } else {
245                         first = 0;
246                 }
247
248                 print_type(out, parameter_type->type);
249                 fprintf(out, " %s", parameter->symbol->string);
250
251                 parameter      = parameter->next;
252                 parameter_type = parameter_type->next;
253         }
254         assert(parameter == NULL && parameter_type == NULL);
255
256         fprintf(out, ")");
257 }
258 #endif
259
260 static
261 void print_declaration(FILE *out, const declaration_t *declaration)
262 {
263         /* TODO */
264         print_type(out, declaration->type);
265         fprintf(out, " %s", declaration->symbol->string);
266 }
267
268 void print_ast(FILE *out, const translation_unit_t *unit)
269 {
270         declaration_t *declaration = unit->context.declarations;
271
272         while(declaration != NULL) {
273                 print_declaration(out, declaration);
274
275                 declaration = declaration->next;
276         }
277 }
278
279 void init_ast(void)
280 {
281         obstack_init(&ast_obstack);
282 }
283
284 void exit_ast(void)
285 {
286         obstack_free(&ast_obstack, NULL);
287 }
288
289 void* (allocate_ast) (size_t size)
290 {
291         return _allocate_ast(size);
292 }