2 * This file is part of cparser.
3 * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
7 #include "write_fluffy.h"
8 #include "separator_t.h"
14 #include "adt/error.h"
17 static const scope_t *global_scope;
20 static void write_type(const type_t *type);
22 static const char *get_atomic_type_string(const atomic_type_kind_t type)
25 case ATOMIC_TYPE_VOID: return "void";
26 case ATOMIC_TYPE_CHAR: return "byte";
27 case ATOMIC_TYPE_SCHAR: return "byte";
28 case ATOMIC_TYPE_UCHAR: return "unsigned byte";
29 case ATOMIC_TYPE_SHORT: return "short";
30 case ATOMIC_TYPE_USHORT: return "unsigned short";
31 case ATOMIC_TYPE_INT: return "int";
32 case ATOMIC_TYPE_UINT: return "unsigned int";
33 case ATOMIC_TYPE_LONG: return "int";
34 case ATOMIC_TYPE_ULONG: return "unsigned int";
35 case ATOMIC_TYPE_LONGLONG: return "long";
36 case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
37 case ATOMIC_TYPE_FLOAT: return "float";
38 case ATOMIC_TYPE_DOUBLE: return "double";
39 case ATOMIC_TYPE_LONG_DOUBLE: return "double";
40 case ATOMIC_TYPE_BOOL: return "bool";
41 default: panic("unsupported atomic type");
45 static void write_atomic_type(const atomic_type_t *type)
47 fprintf(out, "%s", get_atomic_type_string(type->akind));
50 static void write_pointer_type(const pointer_type_t *type)
52 write_type(type->points_to);
56 static entity_t *find_typedef(const type_t *type)
58 /* first: search for a matching typedef in the global type... */
59 entity_t *entity = global_scope->entities;
60 for ( ; entity != NULL; entity = entity->base.next) {
61 if (entity->kind != ENTITY_TYPEDEF)
63 if (entity->typedefe.type == type)
70 static void write_compound_type(const compound_type_t *type)
72 entity_t *entity = find_typedef((const type_t*) type);
74 fprintf(out, "%s", entity->base.symbol->string);
78 /* does the struct have a name? */
79 symbol_t *symbol = type->compound->base.symbol;
81 /* TODO: make sure we create a struct for it... */
82 fprintf(out, "%s", symbol->string);
85 /* TODO: create a struct and use its name here... */
86 fprintf(out, "/* TODO anonymous struct */byte");
89 static void write_enum_type(const enum_type_t *type)
91 entity_t *entity = find_typedef((const type_t*) type);
93 fprintf(out, "%s", entity->base.symbol->string);
97 /* does the enum have a name? */
98 symbol_t *symbol = type->enume->base.symbol;
100 /* TODO: make sure we create an enum for it... */
101 fprintf(out, "%s", symbol->string);
104 /* TODO: create a struct and use its name here... */
105 fprintf(out, "/* TODO anonymous enum */byte");
108 static void write_function_type(const function_type_t *type)
110 fprintf(out, "(func(");
112 function_parameter_t *parameter = type->parameters;
113 separator_t sep = { "", ", " };
114 while(parameter != NULL) {
115 fputs(sep_next(&sep), out);
118 if(parameter->symbol != NULL) {
119 fprintf(out, "%s : ", parameter->symbol->string);
121 /* TODO make up some unused names (or allow _ in fluffy?) */
122 fprintf(out, "_ : ");
126 write_type(parameter->type);
128 parameter = parameter->next;
131 fprintf(out, ") : ");
132 write_type(type->return_type);
136 static void write_type(const type_t *type)
140 write_atomic_type(&type->atomic);
143 write_pointer_type(&type->pointer);
145 case TYPE_COMPOUND_UNION:
146 case TYPE_COMPOUND_STRUCT:
147 write_compound_type(&type->compound);
150 write_enum_type(&type->enumt);
153 write_function_type(&type->function);
158 fprintf(out, "/* TODO type */");
163 static void write_compound_entry(const entity_t *entity)
165 fprintf(out, "\t%s : ", entity->base.symbol->string);
166 write_type(entity->declaration.type);
170 static void write_compound(const symbol_t *symbol, const compound_type_t *type)
172 fprintf(out, "%s %s:\n",
173 type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
176 const entity_t *entity = type->compound->members.entities;
177 for ( ; entity != NULL; entity = entity->base.next) {
178 write_compound_entry(entity);
184 static void write_expression(const expression_t *expression);
186 static void write_unary_expression(const unary_expression_t *expression)
188 switch(expression->base.kind) {
189 case EXPR_UNARY_NEGATE:
196 panic("unimplemented unary expression");
198 write_expression(expression->value);
201 static void write_expression(const expression_t *expression)
203 switch(expression->kind) {
204 case EXPR_LITERAL_INTEGER:
205 fprintf(out, "%s", expression->literal.value.begin);
207 case EXPR_UNARY_CASES:
208 write_unary_expression((const unary_expression_t*) expression);
211 panic("not implemented expression");
215 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
217 fprintf(out, "enum %s:\n", symbol->string);
219 entity_t *entry = type->enume->base.next;
220 for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
221 entry = entry->base.next) {
222 fprintf(out, "\t%s", entry->base.symbol->string);
223 if(entry->enum_value.value != NULL) {
224 fprintf(out, " <- ");
225 write_expression(entry->enum_value.value);
229 fprintf(out, "typealias %s <- int\n", symbol->string);
233 static void write_variable(const entity_t *entity)
235 fprintf(out, "var %s : ", entity->base.symbol->string);
236 write_type(entity->declaration.type);
240 static void write_function(const entity_t *entity)
242 if (entity->function.body != NULL) {
243 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
244 entity->base.symbol->string);
247 fprintf(out, "func extern %s(", entity->base.symbol->string);
249 const function_type_t *function_type
250 = (const function_type_t*) entity->declaration.type;
252 entity_t *parameter = entity->function.parameters.entities;
253 separator_t sep = { "", ", " };
254 for( ; parameter != NULL; parameter = parameter->base.next) {
255 assert(parameter->kind == ENTITY_PARAMETER);
256 fputs(sep_next(&sep), out);
257 if(parameter->base.symbol != NULL) {
258 fprintf(out, "%s : ", parameter->base.symbol->string);
262 write_type(parameter->declaration.type);
264 if(function_type->variadic) {
265 fputs(sep_next(&sep), out);
270 const type_t *return_type = skip_typeref(function_type->return_type);
271 if (!is_type_void(return_type)) {
273 write_type(return_type);
278 void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
281 global_scope = &unit->scope;
284 fprintf(out, "/* WARNING: Automatically generated file */\n");
286 /* write structs,unions + enums */
287 entity_t *entity = unit->scope.entities;
288 for( ; entity != NULL; entity = entity->base.next) {
289 if (entity->kind != ENTITY_TYPEDEF)
292 type_t *type = entity->typedefe.type;
293 if (is_type_compound(type)) {
294 write_compound(entity->base.symbol, &type->compound);
295 } else if(type->kind == TYPE_ENUM) {
296 write_enum(entity->base.symbol, &type->enumt);
300 /* write global variables */
301 entity = unit->scope.entities;
302 for( ; entity != NULL; entity = entity->base.next) {
303 if (entity->kind != ENTITY_VARIABLE)
306 write_variable(entity);
309 /* write functions */
310 entity = unit->scope.entities;
311 for( ; entity != NULL; entity = entity->base.next) {
312 if (entity->kind != ENTITY_FUNCTION)
315 write_function(entity);