6 #include "write_fluffy.h"
10 #include "adt/error.h"
12 static const context_t *global_context;
15 static void write_type(const type_t *type);
17 static const char *get_atomic_type_string(const atomic_type_type_t type)
20 case ATOMIC_TYPE_VOID: return "void";
21 case ATOMIC_TYPE_CHAR: return "byte";
22 case ATOMIC_TYPE_SCHAR: return "byte";
23 case ATOMIC_TYPE_UCHAR: return "unsigned byte";
24 case ATOMIC_TYPE_SHORT: return "short";
25 case ATOMIC_TYPE_USHORT: return "unsigned short";
26 case ATOMIC_TYPE_INT: return "int";
27 case ATOMIC_TYPE_UINT: return "unsigned int";
28 case ATOMIC_TYPE_LONG: return "int";
29 case ATOMIC_TYPE_ULONG: return "unsigned int";
30 case ATOMIC_TYPE_LONGLONG: return "long";
31 case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
32 case ATOMIC_TYPE_FLOAT: return "float";
33 case ATOMIC_TYPE_DOUBLE: return "double";
34 case ATOMIC_TYPE_LONG_DOUBLE: return "double";
35 case ATOMIC_TYPE_BOOL: return "bool";
36 default: panic("unsupported atomic type");
40 static void write_atomic_type(const atomic_type_t *type)
42 fprintf(out, "%s", get_atomic_type_string(type->atype));
45 static void write_pointer_type(const pointer_type_t *type)
47 write_type(type->points_to);
51 static declaration_t *find_typedef(const type_t *type)
53 /* first: search for a matching typedef in the global type... */
54 declaration_t *declaration = global_context->declarations;
55 while(declaration != NULL) {
56 if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
57 declaration = declaration->next;
60 if(declaration->type == type)
62 declaration = declaration->next;
68 static void write_compound_type(const compound_type_t *type)
70 declaration_t *declaration = find_typedef((const type_t*) type);
71 if(declaration != NULL) {
72 fprintf(out, "%s", declaration->symbol->string);
76 /* does the struct have a name? */
77 symbol_t *symbol = type->declaration->symbol;
79 /* TODO: make sure we create a struct for it... */
80 fprintf(out, "%s", symbol->string);
83 /* TODO: create a struct and use its name here... */
84 fprintf(out, "/* TODO anonymous struct */byte");
87 static void write_enum_type(const enum_type_t *type)
89 declaration_t *declaration = find_typedef((const type_t*) type);
90 if(declaration != NULL) {
91 fprintf(out, "%s", declaration->symbol->string);
95 /* does the enum have a name? */
96 symbol_t *symbol = type->declaration->symbol;
98 /* TODO: make sure we create an enum for it... */
99 fprintf(out, "%s", symbol->string);
102 /* TODO: create a struct and use its name here... */
103 fprintf(out, "/* TODO anonymous enum */byte");
106 static void write_function_type(const function_type_t *type)
108 fprintf(out, "(func(");
110 function_parameter_t *parameter = type->parameters;
112 while(parameter != NULL) {
120 if(parameter->symbol != NULL) {
121 fprintf(out, "%s : ", parameter->symbol->string);
123 /* TODO make up some unused names (or allow _ in fluffy?) */
124 fprintf(out, "_ : ");
128 write_type(parameter->type);
130 parameter = parameter->next;
133 fprintf(out, ") : ");
134 write_type(type->result_type);
138 static void write_type(const type_t *type)
142 write_atomic_type((const atomic_type_t*) type);
145 write_pointer_type((const pointer_type_t*) type);
147 case TYPE_COMPOUND_UNION:
148 case TYPE_COMPOUND_STRUCT:
149 write_compound_type((const compound_type_t*) type);
152 write_enum_type((const enum_type_t*) type);
155 write_function_type((const function_type_t*) type);
158 panic("invalid type found");
161 fprintf(out, "/* TODO type */");
166 static void write_struct_entry(const declaration_t *declaration)
168 fprintf(out, "\t%s : ", declaration->symbol->string);
169 write_type(declaration->type);
173 static void write_struct(const symbol_t *symbol, const compound_type_t *type)
175 fprintf(out, "struct %s:\n", symbol->string);
177 const declaration_t *declaration = type->declaration->context.declarations;
178 while(declaration != NULL) {
179 write_struct_entry(declaration);
180 declaration = declaration->next;
186 static void write_union(const symbol_t *symbol, const compound_type_t *type)
188 fprintf(out, "union %s:\n", symbol->string);
190 const declaration_t *declaration = type->declaration->context.declarations;
191 while(declaration != NULL) {
192 write_struct_entry(declaration);
193 declaration = declaration->next;
199 static void write_expression(const expression_t *expression);
201 static void write_unary_expression(const unary_expression_t *expression)
203 switch(expression->type) {
211 panic("unimeplemented unary expression found");
213 write_expression(expression->value);
216 static void write_expression(const expression_t *expression)
218 const const_t *constant;
220 switch(expression->type) {
222 constant = (const const_t*) expression;
223 if(is_type_integer(expression->datatype)) {
224 fprintf(out, "%lld", constant->v.int_value);
226 fprintf(out, "%Lf", constant->v.float_value);
230 write_unary_expression((const unary_expression_t*) expression);
233 panic("not implemented expression");
237 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
239 fprintf(out, "enum %s:\n", symbol->string);
241 declaration_t *entry = type->declaration->next;
242 for ( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
243 entry = entry->next) {
244 fprintf(out, "\t%s", entry->symbol->string);
245 if(entry->init.initializer != NULL) {
246 fprintf(out, " <- ");
247 write_expression(entry->init.enum_value);
251 fprintf(out, "typealias %s <- int\n", symbol->string);
255 static void write_variable(const declaration_t *declaration)
257 fprintf(out, "var %s : ", declaration->symbol->string);
258 write_type(declaration->type);
259 /* TODO: initializers */
263 static void write_function(const declaration_t *declaration)
265 if(declaration->init.statement != NULL) {
266 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
267 declaration->symbol->string);
270 fprintf(out, "func extern %s(",
271 declaration->symbol->string);
273 const function_type_t *function_type
274 = (const function_type_t*) declaration->type;
276 declaration_t *parameter = declaration->context.declarations;
278 for( ; parameter != NULL; parameter = parameter->next) {
284 if(parameter->symbol != NULL) {
285 fprintf(out, "%s : ", parameter->symbol->string);
289 write_type(parameter->type);
291 if(function_type->variadic) {
301 const type_t *result_type = function_type->result_type;
302 if(result_type->type != TYPE_ATOMIC ||
303 ((const atomic_type_t*) result_type)->atype != ATOMIC_TYPE_VOID) {
305 write_type(result_type);
310 void write_fluffy_decls(const translation_unit_t *unit)
313 out = fopen("out.fluffy", "w");
315 fprintf(stderr, "Couldn't open out.fluffy: %s\n", strerror(errno));
320 global_context = &unit->context;
322 fprintf(out, "/* WARNING: Automatically generated file */\n");
324 /* write structs,unions + enums */
325 declaration_t *declaration = unit->context.declarations;
326 for( ; declaration != NULL; declaration = declaration->next) {
327 //fprintf(out, "// Decl: %s\n", declaration->symbol->string);
328 if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
331 type_t *type = declaration->type;
332 if(type->type == TYPE_COMPOUND_STRUCT) {
333 write_struct(declaration->symbol, (compound_type_t*) type);
334 } else if(type->type == TYPE_COMPOUND_UNION) {
335 write_union(declaration->symbol, (compound_type_t*) type);
336 } else if(type->type == TYPE_ENUM) {
337 write_enum(declaration->symbol, (enum_type_t*) type);
341 /* write global variables */
342 declaration = unit->context.declarations;
343 for( ; declaration != NULL; declaration = declaration->next) {
344 if(declaration->namespc != NAMESPACE_NORMAL)
346 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
347 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
350 type_t *type = declaration->type;
351 if(type->type == TYPE_FUNCTION)
354 write_variable(declaration);
357 /* write functions */
358 declaration = unit->context.declarations;
359 for( ; declaration != NULL; declaration = declaration->next) {
360 if(declaration->namespc != NAMESPACE_NORMAL)
362 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
363 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
366 type_t *type = declaration->type;
367 if(type->type != TYPE_FUNCTION)
370 write_function(declaration);