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_caml.h"
31 #include "adt/error.h"
33 static const scope_t *global_scope;
36 static void write_type(const type_t *type);
38 static const char *get_atomic_type_string(const atomic_type_kind_t type)
41 case ATOMIC_TYPE_VOID: return "unit";
42 case ATOMIC_TYPE_CHAR: return "byte";
43 case ATOMIC_TYPE_SCHAR: return "byte";
44 case ATOMIC_TYPE_UCHAR: return "unsigned byte";
45 case ATOMIC_TYPE_SHORT: return "short";
46 case ATOMIC_TYPE_USHORT: return "unsigned short";
47 case ATOMIC_TYPE_INT: return "int";
48 case ATOMIC_TYPE_UINT: return "unsigned int";
49 case ATOMIC_TYPE_LONG: return "int";
50 case ATOMIC_TYPE_ULONG: return "unsigned int";
51 case ATOMIC_TYPE_LONGLONG: return "long";
52 case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
53 case ATOMIC_TYPE_FLOAT: return "float";
54 case ATOMIC_TYPE_DOUBLE: return "double";
55 case ATOMIC_TYPE_LONG_DOUBLE: return "double";
56 case ATOMIC_TYPE_BOOL: return "bool";
57 default: panic("unsupported atomic type");
61 static void write_atomic_type(const atomic_type_t *type)
63 fprintf(out, "%s", get_atomic_type_string(type->akind));
66 static void write_pointer_type(const pointer_type_t *type)
68 type_t *points_to = type->points_to;
69 if (points_to->kind == TYPE_ATOMIC &&
70 is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) {
75 write_type(type->points_to);
79 static entity_t *find_typedef(const type_t *type)
81 /* first: search for a matching typedef in the global type... */
82 entity_t *entity = global_scope->entities;
83 for ( ; entity != NULL; entity = entity->base.next) {
84 if (entity->kind != ENTITY_TYPEDEF)
86 if (entity->typedefe.type == type)
93 static void write_compound_type(const compound_type_t *type)
95 const entity_t *entity = find_typedef((const type_t*) type);
97 fprintf(out, "%s", entity->base.symbol->string);
101 /* does the struct have a name? */
102 symbol_t *symbol = type->compound->base.symbol;
103 if (symbol != NULL) {
104 /* TODO: make sure we create a struct for it... */
105 fprintf(out, "%s", symbol->string);
108 /* TODO: create a struct and use its name here... */
109 fprintf(out, "/* TODO anonymous struct */byte");
112 static void write_enum_type(const enum_type_t *type)
114 const entity_t *entity = find_typedef((const type_t*) type);
115 if (entity != NULL) {
116 fprintf(out, "%s", entity->base.symbol->string);
120 /* does the enum have a name? */
121 symbol_t *symbol = type->enume->base.symbol;
122 if (symbol != NULL) {
123 /* TODO: make sure we create an enum for it... */
124 fprintf(out, "%s", symbol->string);
127 /* TODO: create a struct and use its name here... */
128 fprintf(out, "/* TODO anonymous enum */byte");
131 static void write_function_type(const function_type_t *type)
133 fprintf(out, "(func(");
135 function_parameter_t *parameter = type->parameters;
137 while(parameter != NULL) {
145 if (parameter->symbol != NULL) {
146 fprintf(out, "%s : ", parameter->symbol->string);
148 /* TODO make up some unused names (or allow _ in fluffy?) */
149 fprintf(out, "_ : ");
153 write_type(parameter->type);
155 parameter = parameter->next;
158 fprintf(out, ") : ");
159 write_type(type->return_type);
163 static void write_type(const type_t *type)
167 write_atomic_type(&type->atomic);
170 write_pointer_type(&type->pointer);
172 case TYPE_COMPOUND_UNION:
173 case TYPE_COMPOUND_STRUCT:
174 write_compound_type(&type->compound);
177 write_enum_type(&type->enumt);
180 write_function_type(&type->function);
183 panic("invalid type found");
187 fprintf(out, "/* TODO type */");
192 static void write_function(const entity_t *entity)
194 if (entity->function.statement != NULL) {
195 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
196 entity->base.symbol->string);
199 fprintf(out, "external %s: ", entity->base.symbol->string);
201 const function_type_t *function_type
202 = (const function_type_t*) entity->declaration.type;
204 entity_t *parameter = entity->function.parameters.entities;
205 for( ; parameter != NULL; parameter = parameter->base.next) {
206 assert(parameter->kind == ENTITY_PARAMETER);
207 write_type(parameter->declaration.type);
210 if (function_type->variadic) {
211 fprintf(stderr, "WARNING: Variadic function not supported yet\n");
213 if (function_type->unspecified_parameters) {
214 fprintf(stderr, "WARNING: unspecified params not supported\n");
216 const type_t *return_type = function_type->return_type;
217 write_type(return_type);
220 fputs(entity->base.symbol->string, out);
226 void write_caml_decls(FILE *output, const translation_unit_t *unit)
229 global_scope = &unit->scope;
232 fprintf(out, "(* WARNING: Automatically generated file - chaning is useless *)\n");
234 /* write functions */
235 entity_t *entity = unit->scope.entities;
236 for( ; entity != NULL; entity = entity->base.next) {
237 if (entity->kind != ENTITY_FUNCTION)
240 write_function(entity);