partly implemented reference_expression_to_firm and unary expression_to_firm
[cparser] / write_fluffy.c
1 #include <config.h>
2
3 #include <errno.h>
4 #include <string.h>
5
6 #include "ast_t.h"
7 #include "type_t.h"
8 #include "type.h"
9 #include "adt/error.h"
10
11 static const context_t *global_context;
12 static FILE            *out;
13
14 static void write_type(const type_t *type);
15
16 static const char *get_atomic_type_string(const atomic_type_type_t type)
17 {
18         switch(type) {
19         case ATOMIC_TYPE_VOID:       return "void";
20         case ATOMIC_TYPE_CHAR:       return "byte";
21         case ATOMIC_TYPE_SCHAR:      return "byte";
22         case ATOMIC_TYPE_UCHAR:      return "unsigned byte";
23         case ATOMIC_TYPE_SHORT:      return "short";
24         case ATOMIC_TYPE_USHORT:     return "unsigned short";
25         case ATOMIC_TYPE_INT:        return "int";
26         case ATOMIC_TYPE_UINT:       return "unsigned int";
27         case ATOMIC_TYPE_LONG:       return "int";
28         case ATOMIC_TYPE_ULONG:      return "unsigned int";
29         case ATOMIC_TYPE_LONGLONG:   return "long";
30         case ATOMIC_TYPE_ULONGLONG:  return "unsigned long";
31         case ATOMIC_TYPE_FLOAT:      return "float";
32         case ATOMIC_TYPE_DOUBLE:     return "double";
33         case ATOMIC_TYPE_LONG_DOUBLE: return "double";
34         case ATOMIC_TYPE_BOOL:       return "bool";
35         default:                     panic("unsupported atomic type");
36         }
37 }
38
39 static void write_atomic_type(const atomic_type_t *type)
40 {
41         fprintf(out, "%s", get_atomic_type_string(type->atype));
42 }
43
44 static void write_pointer_type(const pointer_type_t *type)
45 {
46         write_type(type->points_to);
47         fputc('*', out);
48 }
49
50 static declaration_t *find_typedef(const type_t *type)
51 {
52         /* first: search for a matching typedef in the global type... */
53         declaration_t *declaration = global_context->declarations;
54         while(declaration != NULL) {
55                 if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
56                         declaration = declaration->next;
57                         continue;
58                 }
59                 if(declaration->type == type)
60                         break;
61                 declaration = declaration->next;
62         }
63
64         return declaration;
65 }
66
67 static void write_compound_type(const compound_type_t *type)
68 {
69         declaration_t *declaration = find_typedef((const type_t*) type);
70         if(declaration != NULL) {
71                 fprintf(out, "%s", declaration->symbol->string);
72                 return;
73         }
74
75         /* does the struct have a name? */
76         symbol_t *symbol = type->declaration->symbol;
77         if(symbol != NULL) {
78                 /* TODO: make sure we create a struct for it... */
79                 fprintf(out, "%s", symbol->string);
80                 return;
81         }
82         /* TODO: create a struct and use its name here... */
83         fprintf(out, "/* TODO anonymous struct */byte");
84 }
85
86 static void write_enum_type(const enum_type_t *type)
87 {
88         declaration_t *declaration = find_typedef((const type_t*) type);
89         if(declaration != NULL) {
90                 fprintf(out, "%s", declaration->symbol->string);
91                 return;
92         }
93
94         /* does the enum have a name? */
95         symbol_t *symbol = type->declaration->symbol;
96         if(symbol != NULL) {
97                 /* TODO: make sure we create an enum for it... */
98                 fprintf(out, "%s", symbol->string);
99                 return;
100         }
101         /* TODO: create a struct and use its name here... */
102         fprintf(out, "/* TODO anonymous enum */byte");
103 }
104
105 static void write_function_type(const function_type_t *type)
106 {
107         fprintf(out, "(func(");
108
109         function_parameter_t *parameter = type->parameters;
110         int                   first     = 1;
111         while(parameter != NULL) {
112                 if(!first) {
113                         fprintf(out, ", ");
114                 } else {
115                         first = 0;
116                 }
117
118 #if 0
119                 if(parameter->symbol != NULL) {
120                         fprintf(out, "%s : ", parameter->symbol->string);
121                 } else {
122                         /* TODO make up some unused names (or allow _ in fluffy?) */
123                         fprintf(out, "_ : ");
124                 }
125 #endif
126                 fputs("_ : ", out);
127                 write_type(parameter->type);
128
129                 parameter = parameter->next;
130         }
131
132         fprintf(out, ") : ");
133         write_type(type->result_type);
134         fprintf(out, ")");
135 }
136
137 static void write_type(const type_t *type)
138 {
139         switch(type->type) {
140         case TYPE_ATOMIC:
141                 write_atomic_type((const atomic_type_t*) type);
142                 return;
143         case TYPE_POINTER:
144                 write_pointer_type((const pointer_type_t*) type);
145                 return;
146         case TYPE_COMPOUND_UNION:
147         case TYPE_COMPOUND_STRUCT:
148                 write_compound_type((const compound_type_t*) type);
149                 return;
150         case TYPE_ENUM:
151                 write_enum_type((const enum_type_t*) type);
152                 return;
153         case TYPE_FUNCTION:
154                 write_function_type((const function_type_t*) type);
155                 return;
156         case TYPE_INVALID:
157                 panic("invalid type found");
158                 break;
159         default:
160                 fprintf(out, "/* TODO type */");
161                 break;
162         }
163 }
164
165 static void write_struct_entry(const declaration_t *declaration)
166 {
167         fprintf(out, "\t%s : ", declaration->symbol->string);
168         write_type(declaration->type);
169         fprintf(out, "\n");
170 }
171
172 static void write_struct(const symbol_t *symbol, const compound_type_t *type)
173 {
174         fprintf(out, "struct %s:\n", symbol->string);
175
176         const declaration_t *declaration = type->declaration->context.declarations;
177         while(declaration != NULL) {
178                 write_struct_entry(declaration);
179                 declaration = declaration->next;
180         }
181
182         fprintf(out, "\n");
183 }
184
185 static void write_union(const symbol_t *symbol, const compound_type_t *type)
186 {
187         fprintf(out, "union %s:\n", symbol->string);
188
189         const declaration_t *declaration = type->declaration->context.declarations;
190         while(declaration != NULL) {
191                 write_struct_entry(declaration);
192                 declaration = declaration->next;
193         }
194
195         fprintf(out, "\n");
196 }
197
198 static void write_expression(const expression_t *expression);
199
200 static void write_unary_expression(const unary_expression_t *expression)
201 {
202         switch(expression->type) {
203         case UNEXPR_NEGATE:
204                 fputc('-', out);
205                 break;
206         case UNEXPR_NOT:
207                 fputc('!', out);
208                 break;
209         default:
210                 panic("unimeplemented unary expression found");
211         }
212         write_expression(expression->value);
213 }
214
215 static void write_expression(const expression_t *expression)
216 {
217         const const_t *constant;
218         /* TODO */
219         switch(expression->type) {
220         case EXPR_CONST:
221                 constant = (const const_t*) expression;
222                 if(is_type_integer(expression->datatype)) {
223                         fprintf(out, "%d", constant->v.int_value);
224                 } else {
225                         fprintf(out, "%Lf", constant->v.float_value);
226                 }
227                 break;
228         case EXPR_UNARY:
229                 write_unary_expression((const unary_expression_t*) expression);
230                 break;
231         default:
232                 panic("not implemented expression");
233         }
234 }
235
236 static void write_initializer(const initializer_t *initializer)
237 {
238         if(initializer->type != INITIALIZER_VALUE) {
239                 panic("list initializers not supported yet");
240         }
241
242         write_expression(initializer->v.value);
243 }
244
245 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
246 {
247         fprintf(out, "enum %s:\n", symbol->string);
248
249         declaration_t *entry = type->declaration->next;
250         for ( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
251                         entry = entry->next) {
252                 fprintf(out, "\t%s", entry->symbol->string);
253                 if(entry->init.initializer != NULL) {
254                         fprintf(out, " <- ");
255                         write_initializer(entry->init.initializer);
256                 }
257                 fputc('\n', out);
258         }
259         fprintf(out, "typealias %s <- int\n", symbol->string);
260         fprintf(out, "\n");
261 }
262
263 static void write_variable(const declaration_t *declaration)
264 {
265         fprintf(out, "var %s : ", declaration->symbol->string);
266         write_type(declaration->type);
267         /* TODO: initializers */
268         fprintf(out, "\n");
269 }
270
271 static void write_function(const declaration_t *declaration)
272 {
273         if(declaration->init.statement != NULL) {
274                 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
275                         declaration->symbol->string);
276         }
277
278         fprintf(out, "func extern %s(",
279                 declaration->symbol->string);
280
281         const function_type_t *function_type
282                 = (const function_type_t*) declaration->type;
283
284         declaration_t *parameter = declaration->context.declarations;
285         int            first     = 1;
286         for( ; parameter != NULL; parameter = parameter->next) {
287                 if(!first) {
288                         fprintf(out, ", ");
289                 } else {
290                         first = 0;
291                 }
292                 if(parameter->symbol != NULL) {
293                         fprintf(out, "%s : ", parameter->symbol->string);
294                 } else {
295                         fputs("_ : ", out);
296                 }
297                 write_type(parameter->type);
298         }
299         if(function_type->variadic) {
300                 if(!first) {
301                         fprintf(out, ", ");
302                 } else {
303                         first = 0;
304                 }
305                 fputs("...", out);
306         }
307         fprintf(out, ")");
308
309         const type_t *result_type = function_type->result_type;
310         if(result_type->type != TYPE_ATOMIC ||
311                         ((const atomic_type_t*) result_type)->atype != ATOMIC_TYPE_VOID) {
312                 fprintf(out, " : ");
313                 write_type(result_type);
314         }
315         fputc('\n', out);
316 }
317
318 void write_fluffy_decls(const translation_unit_t *unit)
319 {
320 #if 0
321         out = fopen("out.fluffy", "w");
322         if(out == NULL) {
323                 fprintf(stderr, "Couldn't open out.fluffy: %s\n", strerror(errno));
324                 exit(1);
325         }
326 #endif
327         out            = stdout;
328         global_context = &unit->context;
329
330         fprintf(out, "/* WARNING: Automatically generated file */\n");
331
332         /* write structs,unions + enums */
333         declaration_t *declaration = unit->context.declarations;
334         for( ; declaration != NULL; declaration = declaration->next) {
335                 //fprintf(out, "// Decl: %s\n", declaration->symbol->string);
336                 if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
337                         continue;
338                 }
339                 type_t *type = declaration->type;
340                 if(type->type == TYPE_COMPOUND_STRUCT) {
341                         write_struct(declaration->symbol, (compound_type_t*) type);
342                 } else if(type->type == TYPE_COMPOUND_UNION) {
343                         write_union(declaration->symbol, (compound_type_t*) type);
344                 } else if(type->type == TYPE_ENUM) {
345                         write_enum(declaration->symbol, (enum_type_t*) type);
346                 }
347         }
348
349         /* write global variables */
350         declaration = unit->context.declarations;
351         for( ; declaration != NULL; declaration = declaration->next) {
352                 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
353                                 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
354                         continue;
355
356                 type_t *type = declaration->type;
357                 if(type->type == TYPE_FUNCTION)
358                         continue;
359
360                 write_variable(declaration);
361         }
362
363         /* write functions */
364         declaration = unit->context.declarations;
365         for( ; declaration != NULL; declaration = declaration->next) {
366                 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
367                                 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
368                         continue;
369
370                 type_t *type = declaration->type;
371                 if(type->type != TYPE_FUNCTION)
372                         continue;
373
374                 write_function(declaration);
375         }
376
377         //fclose(out);
378 }