11 static const context_t *global_context;
14 static void write_type(const type_t *type);
16 static const char *get_atomic_type_string(const atomic_type_type_t 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");
39 static void write_atomic_type(const atomic_type_t *type)
41 fprintf(out, "%s", get_atomic_type_string(type->atype));
44 static void write_pointer_type(const pointer_type_t *type)
46 write_type(type->points_to);
50 static declaration_t *find_typedef(const type_t *type)
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;
59 if(declaration->type == type)
61 declaration = declaration->next;
67 static void write_compound_type(const compound_type_t *type)
69 declaration_t *declaration = find_typedef((const type_t*) type);
70 if(declaration != NULL) {
71 fprintf(out, "%s", declaration->symbol->string);
75 /* does the struct have a name? */
76 symbol_t *symbol = type->declaration->symbol;
78 /* TODO: make sure we create a struct for it... */
79 fprintf(out, "%s", symbol->string);
82 /* TODO: create a struct and use its name here... */
83 fprintf(out, "/* TODO anonymous struct */byte");
86 static void write_enum_type(const enum_type_t *type)
88 declaration_t *declaration = find_typedef((const type_t*) type);
89 if(declaration != NULL) {
90 fprintf(out, "%s", declaration->symbol->string);
94 /* does the enum have a name? */
95 symbol_t *symbol = type->declaration->symbol;
97 /* TODO: make sure we create an enum for it... */
98 fprintf(out, "%s", symbol->string);
101 /* TODO: create a struct and use its name here... */
102 fprintf(out, "/* TODO anonymous enum */byte");
105 static void write_method_type(const method_type_t *type)
107 fprintf(out, "(func(");
109 method_parameter_t *parameter = type->parameters;
111 while(parameter != NULL) {
119 if(parameter->symbol != NULL) {
120 fprintf(out, "%s : ", parameter->symbol->string);
122 /* TODO make up some unused names (or allow _ in fluffy?) */
123 fprintf(out, "_ : ");
127 write_type(parameter->type);
129 parameter = parameter->next;
132 fprintf(out, ") : ");
133 write_type(type->result_type);
137 static void write_type(const type_t *type)
141 write_atomic_type((const atomic_type_t*) type);
144 write_pointer_type((const pointer_type_t*) type);
146 case TYPE_COMPOUND_UNION:
147 case TYPE_COMPOUND_STRUCT:
148 write_compound_type((const compound_type_t*) type);
151 write_enum_type((const enum_type_t*) type);
154 write_method_type((const method_type_t*) type);
157 panic("invalid type found");
160 fprintf(out, "/* TODO type */");
165 static void write_struct_entry(const declaration_t *declaration)
167 fprintf(out, "\t%s : ", declaration->symbol->string);
168 write_type(declaration->type);
172 static void write_struct(const symbol_t *symbol, const compound_type_t *type)
174 fprintf(out, "struct %s:\n", symbol->string);
176 const declaration_t *declaration = type->declaration->context.declarations;
177 while(declaration != NULL) {
178 write_struct_entry(declaration);
179 declaration = declaration->next;
185 static void write_union(const symbol_t *symbol, const compound_type_t *type)
187 fprintf(out, "union %s:\n", symbol->string);
189 const declaration_t *declaration = type->declaration->context.declarations;
190 while(declaration != NULL) {
191 write_struct_entry(declaration);
192 declaration = declaration->next;
198 static void write_expression(const expression_t *expression);
200 static void write_unary_expression(const unary_expression_t *expression)
202 switch(expression->type) {
210 panic("unimeplemented unary expression found");
212 write_expression(expression->value);
215 static void write_expression(const expression_t *expression)
217 const const_t *constant;
219 switch(expression->type) {
221 constant = (const const_t*) expression;
222 if(is_type_integer(expression->datatype)) {
223 fprintf(out, "%d", constant->v.int_value);
225 fprintf(out, "%Lf", constant->v.float_value);
229 write_unary_expression((const unary_expression_t*) expression);
232 panic("not implemented expression");
236 static void write_initializer(const initializer_t *initializer)
238 if(initializer->type != INITIALIZER_VALUE) {
239 panic("list initializers not supported yet");
242 write_expression(initializer->v.value);
245 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
247 fprintf(out, "enum %s:\n", symbol->string);
249 declaration_t *entry = type->declaration->context_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);
259 fprintf(out, "typealias %s <- int\n", symbol->string);
263 static void write_variable(const declaration_t *declaration)
265 fprintf(out, "var %s : ", declaration->symbol->string);
266 write_type(declaration->type);
267 /* TODO: initializers */
271 static void write_function(const declaration_t *declaration)
273 if(declaration->init.statement != NULL) {
274 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
275 declaration->symbol->string);
278 fprintf(out, "func extern %s(",
279 declaration->symbol->string);
281 const method_type_t *method_type = (const method_type_t*) declaration->type;
283 declaration_t *parameter = declaration->context.declarations;
285 for( ; parameter != NULL; parameter = parameter->next) {
291 if(parameter->symbol != NULL) {
292 fprintf(out, "%s : ", parameter->symbol->string);
296 write_type(parameter->type);
298 if(method_type->variadic) {
308 const type_t *result_type = method_type->result_type;
309 if(result_type->type != TYPE_ATOMIC ||
310 ((const atomic_type_t*) result_type)->atype != ATOMIC_TYPE_VOID) {
312 write_type(result_type);
317 void write_fluffy_decls(const translation_unit_t *unit)
320 out = fopen("out.fluffy", "w");
322 fprintf(stderr, "Couldn't open out.fluffy: %s\n", strerror(errno));
327 global_context = &unit->context;
329 fprintf(out, "/* WARNING: Automatically generated file */\n");
331 /* write structs,unions + enums */
332 declaration_t *declaration = unit->context.declarations;
333 for( ; declaration != NULL; declaration = declaration->next) {
334 //fprintf(out, "// Decl: %s\n", declaration->symbol->string);
335 if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
338 type_t *type = declaration->type;
339 if(type->type == TYPE_COMPOUND_STRUCT) {
340 write_struct(declaration->symbol, (compound_type_t*) type);
341 } else if(type->type == TYPE_COMPOUND_UNION) {
342 write_union(declaration->symbol, (compound_type_t*) type);
343 } else if(type->type == TYPE_ENUM) {
344 write_enum(declaration->symbol, (enum_type_t*) type);
348 /* write global variables */
349 declaration = unit->context.declarations;
350 for( ; declaration != NULL; declaration = declaration->next) {
351 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
352 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
355 type_t *type = declaration->type;
356 if(type->type == TYPE_METHOD)
359 write_variable(declaration);
362 /* write functions */
363 declaration = unit->context.declarations;
364 for( ; declaration != NULL; declaration = declaration->next) {
365 if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
366 || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
369 type_t *type = declaration->type;
370 if(type->type != TYPE_METHOD)
373 write_function(declaration);