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"
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 "unit";
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 type_t *points_to = type->points_to;
70 if (points_to->kind == TYPE_ATOMIC &&
71 is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) {
76 write_type(type->points_to);
80 static entity_t *find_typedef(const type_t *type)
82 /* first: search for a matching typedef in the global type... */
83 entity_t *entity = global_scope->entities;
84 for ( ; entity != NULL; entity = entity->base.next) {
85 if (entity->kind != ENTITY_TYPEDEF)
87 if (entity->typedefe.type == type)
94 static void write_compound_type(const compound_type_t *type)
96 const entity_t *entity = find_typedef((const type_t*) type);
98 fprintf(out, "%s", entity->base.symbol->string);
102 /* does the struct have a name? */
103 symbol_t *symbol = type->compound->base.symbol;
104 if (symbol != NULL) {
105 /* TODO: make sure we create a struct for it... */
106 fprintf(out, "%s", symbol->string);
109 /* TODO: create a struct and use its name here... */
110 fprintf(out, "/* TODO anonymous struct */byte");
113 static void write_enum_type(const enum_type_t *type)
115 const entity_t *entity = find_typedef((const type_t*) type);
116 if (entity != NULL) {
117 fprintf(out, "%s", entity->base.symbol->string);
121 /* does the enum have a name? */
122 symbol_t *symbol = type->enume->base.symbol;
123 if (symbol != NULL) {
124 /* TODO: make sure we create an enum for it... */
125 fprintf(out, "%s", symbol->string);
128 /* TODO: create a struct and use its name here... */
129 fprintf(out, "/* TODO anonymous enum */byte");
132 static void write_function_type(const function_type_t *type)
134 fprintf(out, "(func(");
136 function_parameter_t *parameter = type->parameters;
138 while(parameter != NULL) {
146 if (parameter->symbol != NULL) {
147 fprintf(out, "%s : ", parameter->symbol->string);
149 /* TODO make up some unused names (or allow _ in fluffy?) */
150 fprintf(out, "_ : ");
154 write_type(parameter->type);
156 parameter = parameter->next;
159 fprintf(out, ") : ");
160 write_type(type->return_type);
164 static void write_type(const type_t *type)
168 write_atomic_type(&type->atomic);
171 write_pointer_type(&type->pointer);
173 case TYPE_COMPOUND_UNION:
174 case TYPE_COMPOUND_STRUCT:
175 write_compound_type(&type->compound);
178 write_enum_type(&type->enumt);
181 write_function_type(&type->function);
184 panic("invalid type found");
188 fprintf(out, "/* TODO type */");
193 static void write_function(const entity_t *entity)
195 if (entity->function.statement != NULL) {
196 fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
197 entity->base.symbol->string);
200 fprintf(out, "external %s: ", entity->base.symbol->string);
202 const function_type_t *function_type
203 = (const function_type_t*) entity->declaration.type;
205 entity_t *parameter = entity->function.parameters.entities;
206 for( ; parameter != NULL; parameter = parameter->base.next) {
207 assert(parameter->kind == ENTITY_PARAMETER);
208 write_type(parameter->declaration.type);
211 if (function_type->variadic) {
212 fprintf(stderr, "WARNING: Variadic function not supported yet\n");
214 if (function_type->unspecified_parameters) {
215 fprintf(stderr, "WARNING: unspecified params not supported\n");
217 const type_t *return_type = function_type->return_type;
218 write_type(return_type);
221 fputs(entity->base.symbol->string, out);
227 void write_caml_decls(FILE *output, const translation_unit_t *unit)
230 global_scope = &unit->scope;
233 fprintf(out, "(* WARNING: Automatically generated file - chaning is useless *)\n");
235 /* write functions */
236 entity_t *entity = unit->scope.entities;
237 for( ; entity != NULL; entity = entity->base.next) {
238 if (entity->kind != ENTITY_FUNCTION)
241 write_function(entity);