2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 #include "write_fluffy.h"
31 #include "adt/error.h"
34 static const scope_t *global_scope;
37 static void write_type(const type_t *type);
39 static const char *get_atomic_type_string(const atomic_type_kind_t type)
42 case ATOMIC_TYPE_VOID: return "void";
43 case ATOMIC_TYPE_CHAR: return "byte";
44 case ATOMIC_TYPE_SCHAR: return "byte";
45 case ATOMIC_TYPE_UCHAR: return "unsigned byte";
46 case ATOMIC_TYPE_SHORT: return "short";
47 case ATOMIC_TYPE_USHORT: return "unsigned short";
48 case ATOMIC_TYPE_INT: return "int";
49 case ATOMIC_TYPE_UINT: return "unsigned int";
50 case ATOMIC_TYPE_LONG: return "int";
51 case ATOMIC_TYPE_ULONG: return "unsigned int";
52 case ATOMIC_TYPE_LONGLONG: return "long";
53 case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
54 case ATOMIC_TYPE_FLOAT: return "float";
55 case ATOMIC_TYPE_DOUBLE: return "double";
56 case ATOMIC_TYPE_LONG_DOUBLE: return "double";
57 case ATOMIC_TYPE_BOOL: return "bool";
58 default: panic("unsupported atomic type");
62 static void write_atomic_type(const atomic_type_t *type)
64 fprintf(out, "%s", get_atomic_type_string(type->akind));
67 static void write_pointer_type(const pointer_type_t *type)
69 write_type(type->points_to);
73 static entity_t *find_typedef(const type_t *type)
75 /* first: search for a matching typedef in the global type... */
76 entity_t *entity = global_scope->entities;
77 for ( ; entity != NULL; entity = entity->base.next) {
78 if (entity->kind != ENTITY_TYPEDEF)
80 if (entity->typedefe.type == type)
87 static void write_compound_type(const compound_type_t *type)
89 entity_t *entity = find_typedef((const type_t*) type);
91 fprintf(out, "%s", entity->base.symbol->string);
95 /* does the struct have a name? */
96 symbol_t *symbol = type->compound->base.symbol;
98 /* TODO: make sure we create a struct for it... */
99 fprintf(out, "%s", symbol->string);
102 /* TODO: create a struct and use its name here... */
103 fprintf(out, "/* TODO anonymous struct */byte");
106 static void write_enum_type(const enum_type_t *type)
108 entity_t *entity = find_typedef((const type_t*) type);
109 if (entity != NULL) {
110 fprintf(out, "%s", entity->base.symbol->string);
114 /* does the enum have a name? */
115 symbol_t *symbol = type->enume->base.symbol;
116 if (symbol != NULL) {
117 /* TODO: make sure we create an enum for it... */
118 fprintf(out, "%s", symbol->string);
121 /* TODO: create a struct and use its name here... */
122 fprintf(out, "/* TODO anonymous enum */byte");
125 static void write_function_type(const function_type_t *type)
127 fprintf(out, "(func(");
129 function_parameter_t *parameter = type->parameters;
131 while(parameter != NULL) {
139 if(parameter->symbol != NULL) {
140 fprintf(out, "%s : ", parameter->symbol->string);
142 /* TODO make up some unused names (or allow _ in fluffy?) */
143 fprintf(out, "_ : ");
147 write_type(parameter->type);
149 parameter = parameter->next;
152 fprintf(out, ") : ");
153 write_type(type->return_type);
157 static void write_type(const type_t *type)
161 write_atomic_type(&type->atomic);
164 write_pointer_type(&type->pointer);
166 case TYPE_COMPOUND_UNION:
167 case TYPE_COMPOUND_STRUCT:
168 write_compound_type(&type->compound);
171 write_enum_type(&type->enumt);
174 write_function_type(&type->function);
177 panic("invalid type found");
181 fprintf(out, "/* TODO type */");
186 static void write_compound_entry(const entity_t *entity)
188 fprintf(out, "\t%s : ", entity->base.symbol->string);
189 write_type(entity->declaration.type);
193 static void write_compound(const symbol_t *symbol, const compound_type_t *type)
195 fprintf(out, "%s %s:\n",
196 type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
199 const entity_t *entity = type->compound->members.entities;
200 for ( ; entity != NULL; entity = entity->base.next) {
201 write_compound_entry(entity);
207 static void write_expression(const expression_t *expression);
209 static void write_unary_expression(const unary_expression_t *expression)
211 switch(expression->base.kind) {
212 case EXPR_UNARY_NEGATE:
219 panic("unimeplemented unary expression found");
221 write_expression(expression->value);
224 static void write_expression(const expression_t *expression)
226 const const_expression_t *constant;
228 switch(expression->kind) {
230 constant = &expression->conste;
231 if(is_type_integer(expression->base.type)) {
232 fprintf(out, "%lld", constant->v.int_value);
234 fprintf(out, "%Lf", constant->v.float_value);
238 write_unary_expression((const unary_expression_t*) expression);
241 panic("not implemented expression");
245 static void write_enum(const symbol_t *symbol, const enum_type_t *type)
247 fprintf(out, "enum %s:\n", symbol->string);
249 entity_t *entry = type->enume->base.next;
250 for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
251 entry = entry->base.next) {
252 fprintf(out, "\t%s", entry->base.symbol->string);
253 if(entry->enum_value.value != NULL) {
254 fprintf(out, " <- ");
255 write_expression(entry->enum_value.value);
259 fprintf(out, "typealias %s <- int\n", symbol->string);
263 static void write_variable(const entity_t *entity)
265 fprintf(out, "var %s : ", entity->base.symbol->string);
266 write_type(entity->declaration.type);
270 static void write_function(const entity_t *entity)
272 if (entity->function.statement != NULL) {
273 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
274 entity->base.symbol->string);
277 fprintf(out, "func extern %s(", entity->base.symbol->string);
279 const function_type_t *function_type
280 = (const function_type_t*) entity->declaration.type;
282 entity_t *parameter = entity->function.parameters.entities;
284 for( ; parameter != NULL; parameter = parameter->base.next) {
285 assert(parameter->kind == ENTITY_PARAMETER);
291 if(parameter->base.symbol != NULL) {
292 fprintf(out, "%s : ", parameter->base.symbol->string);
296 write_type(parameter->declaration.type);
298 if(function_type->variadic) {
308 const type_t *return_type = skip_typeref(function_type->return_type);
309 if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
311 write_type(return_type);
316 void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
319 global_scope = &unit->scope;
322 fprintf(out, "/* WARNING: Automatically generated file */\n");
324 /* write structs,unions + enums */
325 entity_t *entity = unit->scope.entities;
326 for( ; entity != NULL; entity = entity->base.next) {
327 if (entity->kind != ENTITY_TYPEDEF)
330 type_t *type = entity->typedefe.type;
331 if(type->kind == TYPE_COMPOUND_STRUCT
332 || type->kind == TYPE_COMPOUND_UNION) {
333 write_compound(entity->base.symbol, &type->compound);
334 } else if(type->kind == TYPE_ENUM) {
335 write_enum(entity->base.symbol, &type->enumt);
339 /* write global variables */
340 entity = unit->scope.entities;
341 for( ; entity != NULL; entity = entity->base.next) {
342 if (entity->kind != ENTITY_VARIABLE)
345 write_variable(entity);
348 /* write functions */
349 entity = unit->scope.entities;
350 for( ; entity != NULL; entity = entity->base.next) {
351 if (entity->kind != ENTITY_FUNCTION)
354 write_function(entity);