2 * This file is part of cparser.
3 * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
10 #include "write_fluffy.h"
11 #include "separator_t.h"
17 #include "adt/error.h"
20 static const scope_t *global_scope;
23 static void write_type(const type_t *type);
25 static const char *get_atomic_type_string(const atomic_type_kind_t type)
28 case ATOMIC_TYPE_VOID: return "void";
29 case ATOMIC_TYPE_CHAR: return "byte";
30 case ATOMIC_TYPE_SCHAR: return "byte";
31 case ATOMIC_TYPE_UCHAR: return "unsigned byte";
32 case ATOMIC_TYPE_SHORT: return "short";
33 case ATOMIC_TYPE_USHORT: return "unsigned short";
34 case ATOMIC_TYPE_INT: return "int";
35 case ATOMIC_TYPE_UINT: return "unsigned int";
36 case ATOMIC_TYPE_LONG: return "int";
37 case ATOMIC_TYPE_ULONG: return "unsigned int";
38 case ATOMIC_TYPE_LONGLONG: return "long";
39 case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
40 case ATOMIC_TYPE_FLOAT: return "float";
41 case ATOMIC_TYPE_DOUBLE: return "double";
42 case ATOMIC_TYPE_LONG_DOUBLE: return "double";
43 case ATOMIC_TYPE_BOOL: return "bool";
44 default: panic("unsupported atomic type");
48 static void write_atomic_type(const atomic_type_t *type)
50 fprintf(out, "%s", get_atomic_type_string(type->akind));
53 static void write_pointer_type(const pointer_type_t *type)
55 write_type(type->points_to);
59 static entity_t *find_typedef(const type_t *type)
61 /* first: search for a matching typedef in the global type... */
62 entity_t *entity = global_scope->entities;
63 for ( ; entity != NULL; entity = entity->base.next) {
64 if (entity->kind != ENTITY_TYPEDEF)
66 if (entity->typedefe.type == type)
73 static void write_compound_type(const compound_type_t *type)
75 entity_t *entity = find_typedef((const type_t*) type);
77 fprintf(out, "%s", entity->base.symbol->string);
81 /* does the struct have a name? */
82 symbol_t *symbol = type->compound->base.symbol;
84 /* TODO: make sure we create a struct for it... */
85 fprintf(out, "%s", symbol->string);
88 /* TODO: create a struct and use its name here... */
89 fprintf(out, "/* TODO anonymous struct */byte");
92 static void write_enum_type(const enum_type_t *type)
94 entity_t *entity = find_typedef((const type_t*) type);
96 fprintf(out, "%s", entity->base.symbol->string);
100 /* does the enum have a name? */
101 symbol_t *symbol = type->enume->base.symbol;
102 if (symbol != NULL) {
103 /* TODO: make sure we create an enum for it... */
104 fprintf(out, "%s", symbol->string);
107 /* TODO: create a struct and use its name here... */
108 fprintf(out, "/* TODO anonymous enum */byte");
111 static void write_function_type(const function_type_t *type)
113 fprintf(out, "(func(");
115 function_parameter_t *parameter = type->parameters;
116 separator_t sep = { "", ", " };
117 while(parameter != NULL) {
118 fputs(sep_next(&sep), out);
121 if(parameter->symbol != NULL) {
122 fprintf(out, "%s : ", parameter->symbol->string);
124 /* TODO make up some unused names (or allow _ in fluffy?) */
125 fprintf(out, "_ : ");
129 write_type(parameter->type);
131 parameter = parameter->next;
134 fprintf(out, ") : ");
135 write_type(type->return_type);
139 static void write_type(const type_t *type)
143 write_atomic_type(&type->atomic);
146 write_pointer_type(&type->pointer);
148 case TYPE_COMPOUND_UNION:
149 case TYPE_COMPOUND_STRUCT:
150 write_compound_type(&type->compound);
153 write_enum_type(&type->enumt);
156 write_function_type(&type->function);
161 fprintf(out, "/* TODO type */");
166 static void write_compound_entry(const entity_t *entity)
168 fprintf(out, "\t%s : ", entity->base.symbol->string);
169 write_type(entity->declaration.type);
173 static void write_compound(const symbol_t *symbol, const compound_type_t *type)
175 fprintf(out, "%s %s:\n",
176 type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
179 const entity_t *entity = type->compound->members.entities;
180 for ( ; entity != NULL; entity = entity->base.next) {
181 write_compound_entry(entity);
187 static void write_expression(const expression_t *expression);
189 static void write_unary_expression(const unary_expression_t *expression)
191 switch(expression->base.kind) {
192 case EXPR_UNARY_NEGATE:
199 panic("unimplemented unary expression");
201 write_expression(expression->value);
204 static void write_expression(const expression_t *expression)
206 switch(expression->kind) {
207 case EXPR_LITERAL_INTEGER:
208 fprintf(out, "%s", expression->literal.value.begin);
210 case EXPR_UNARY_CASES:
211 write_unary_expression((const unary_expression_t*) expression);
214 panic("not implemented expression");
218 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
220 fprintf(out, "enum %s:\n", symbol->string);
222 entity_t *entry = type->enume->base.next;
223 for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
224 entry = entry->base.next) {
225 fprintf(out, "\t%s", entry->base.symbol->string);
226 if(entry->enum_value.value != NULL) {
227 fprintf(out, " <- ");
228 write_expression(entry->enum_value.value);
232 fprintf(out, "typealias %s <- int\n", symbol->string);
236 static void write_variable(const entity_t *entity)
238 fprintf(out, "var %s : ", entity->base.symbol->string);
239 write_type(entity->declaration.type);
243 static void write_function(const entity_t *entity)
245 if (entity->function.body != NULL) {
246 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
247 entity->base.symbol->string);
250 fprintf(out, "func extern %s(", entity->base.symbol->string);
252 const function_type_t *function_type
253 = (const function_type_t*) entity->declaration.type;
255 entity_t *parameter = entity->function.parameters.entities;
256 separator_t sep = { "", ", " };
257 for( ; parameter != NULL; parameter = parameter->base.next) {
258 assert(parameter->kind == ENTITY_PARAMETER);
259 fputs(sep_next(&sep), out);
260 if(parameter->base.symbol != NULL) {
261 fprintf(out, "%s : ", parameter->base.symbol->string);
265 write_type(parameter->declaration.type);
267 if(function_type->variadic) {
268 fputs(sep_next(&sep), out);
273 const type_t *return_type = skip_typeref(function_type->return_type);
274 if (!is_type_void(return_type)) {
276 write_type(return_type);
281 void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
284 global_scope = &unit->scope;
287 fprintf(out, "/* WARNING: Automatically generated file */\n");
289 /* write structs,unions + enums */
290 entity_t *entity = unit->scope.entities;
291 for( ; entity != NULL; entity = entity->base.next) {
292 if (entity->kind != ENTITY_TYPEDEF)
295 type_t *type = entity->typedefe.type;
296 if (is_type_compound(type)) {
297 write_compound(entity->base.symbol, &type->compound);
298 } else if(type->kind == TYPE_ENUM) {
299 write_enum(entity->base.symbol, &type->enumt);
303 /* write global variables */
304 entity = unit->scope.entities;
305 for( ; entity != NULL; entity = entity->base.next) {
306 if (entity->kind != ENTITY_VARIABLE)
309 write_variable(entity);
312 /* write functions */
313 entity = unit->scope.entities;
314 for( ; entity != NULL; entity = entity->base.next) {
315 if (entity->kind != ENTITY_FUNCTION)
318 write_function(entity);