warning.c \
parser.c \
ast2firm.c \
- write_fluffy.c \
- write_caml.c \
+ wrappergen/write_fluffy.c \
+ wrappergen/write_caml.c \
+ wrappergen/write_jna.c \
driver/firm_cmdline.c \
driver/firm_timing.c \
driver/firm_codegen.c \
@echo "===> DEPEND"
@rm -f $@ && touch $@ && makedepend -p "$@ build/" -Y -f $@ -- $(CPPFLAGS) -- $(SOURCES) 2> /dev/null && rm $@.bak
-DIRS = build build/adt build/driver build/cpb build/cpb/adt build/cpb/driver build/cpb2 build/cpb2/adt build/cpb2/driver build/cpbe build/cpbe/adt build/cpbe/driver
+DIRS = build build/adt build/driver build/wrappergen build/cpb build/cpb/adt build/cpb/driver build/cpb2 build/cpb2/adt build/cpb2/driver build/cpbe build/cpbe/adt build/cpbe/driver
UNUSED := $(shell mkdir -p $(DIRS))
$(GOAL): $(OBJECTS) $(LIBFIRM_FILE)
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * @file
- * @date 17.03.2007
- * @brief A hashset that contains pointers
- * @author Matthias Braun
- * @version $Id$
- */
-#ifndef _FIRM_PSET_H_
-#define _FIRM_PSET_H_
-
-/* collides with libfirm... */
-#if 0
-
-#define HashSet pset_t
-#define HashSetIterator pset_iterator_t
-#define ValueType void*
-#define DO_REHASH
-#include "hashset.h"
-#undef DO_REHASH
-#undef HashSet
-#undef HashSetIterator
-#undef ValueType
-
-/**
- * Initializes a pset
- *
- * @param pset Pointer to allocated space for the pset
- */
-void pset_init(pset_t *pset);
-
-/**
- * Initializes a pset
- *
- * @param pset Pointer to allocated space for the pset
- * @param expected_elements Number of elements expected in the pset (rougly)
- */
-void pset_init_size(pset_t *pset, size_t expected_elements);
-
-/**
- * Destroys a pset and frees the memory allocated for hashtable. The memory of
- * the pset itself is not freed.
- *
- * @param pset Pointer to the pset
- */
-void pset_destroy(pset_t *pset);
-
-/**
- * Inserts an element into a pset.
- *
- * @param pset Pointer to the pset
- * @param ptr Pointer to insert into the pset
- * @returns 1 if the pointer was inserted, 0 if it was already there
- */
-int pset_insert(pset_t *pset, void *ptr);
-
-/**
- * Removes an element from a pset. Does nothing if the pset doesn't contain the
- * element.
- *
- * @param pset Pointer to the pset
- * @param ptr Pointer to remove from the pset
- */
-void pset_remove(pset_t *pset, const void *ptr);
-
-/**
- * Tests whether a pset contains a pointer
- *
- * @param pset Pointer to the pset
- * @param ptr The pointer to test
- * @returns 1 @p pset contains the @p ptr, 0 otherwise
- */
-int pset_contains(const pset_t *pset, const void *ptr);
-
-/**
- * Returns the number of pointers contained in the pset
- *
- * @param pset Pointer to the pset
- * @returns Number of pointers contained in the pset
- */
-size_t pset_size(const pset_t *pset);
-
-/**
- * Initializes a pset iterator. Sets the iterator before the first element in
- * the pset.
- *
- * @param iterator Pointer to already allocated iterator memory
- * @param pset Pointer to the pset
- */
-void pset_iterator_init(pset_iterator_t *iterator, const pset_t *pset);
-
-/**
- * Advances the iterator and returns the current element or NULL if all elements
- * in the pset have been processed.
- * @attention It is not allowed to use pset_insert or pset_remove while
- * iterating over a pset; pset_remove_iter is allowed.
- *
- * @param iterator Pointer to the pset iterator.
- * @returns Next element in the pset or NULL
- */
-void* pset_iterator_next(pset_iterator_t *iterator);
-
-/**
- * Removes the element that the iterator currently points to from the hashset.
- *
- * @param pset Pointer to the pset
- * @param iterator Pointer to the iterator
- */
-void pset_remove_iterator(pset_t *pset, const pset_iterator_t *iterator);
-#endif
-
-#endif
#include "driver/firm_opt.h"
#include "driver/firm_cmdline.h"
#include "adt/error.h"
-#include "write_fluffy.h"
-#include "write_caml.h"
+#include "wrappergen/write_fluffy.h"
+#include "wrappergen/write_caml.h"
+#include "wrappergen/write_jna.h"
#include "revision.h"
#include "warning.h"
#include "mangle.h"
LexTest,
PrintAst,
PrintFluffy,
- PrintCaml
+ PrintCaml,
+ PrintJna
} compile_mode_t;
static void usage(const char *argv0)
mode = PrintFluffy;
} else if (streq(option, "print-caml")) {
mode = PrintCaml;
+ } else if (streq(option, "print-jna")) {
+ mode = PrintJna;
} else if (streq(option, "version")) {
print_cparser_version();
exit(EXIT_SUCCESS);
case PrintAst:
case PrintFluffy:
case PrintCaml:
+ case PrintJna:
case LexTest:
case PreprocessOnly:
case ParseOnly:
} else if (mode == PrintCaml) {
write_caml_decls(out, unit);
continue;
+ } else if (mode == PrintJna) {
+ write_jna_decls(out, unit);
+ continue;
}
translation_unit_to_firm(unit);
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "write_caml.h"
+#include "symbol_t.h"
+#include "ast_t.h"
+#include "type_t.h"
+#include "entity_t.h"
+#include "type.h"
+#include "adt/error.h"
+
+static const scope_t *global_scope;
+static FILE *out;
+
+static void write_type(const type_t *type);
+
+static const char *get_atomic_type_string(const atomic_type_kind_t type)
+{
+ switch(type) {
+ case ATOMIC_TYPE_VOID: return "unit";
+ case ATOMIC_TYPE_CHAR: return "byte";
+ case ATOMIC_TYPE_SCHAR: return "byte";
+ case ATOMIC_TYPE_UCHAR: return "unsigned byte";
+ case ATOMIC_TYPE_SHORT: return "short";
+ case ATOMIC_TYPE_USHORT: return "unsigned short";
+ case ATOMIC_TYPE_INT: return "int";
+ case ATOMIC_TYPE_UINT: return "unsigned int";
+ case ATOMIC_TYPE_LONG: return "int";
+ case ATOMIC_TYPE_ULONG: return "unsigned int";
+ case ATOMIC_TYPE_LONGLONG: return "long";
+ case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
+ case ATOMIC_TYPE_FLOAT: return "float";
+ case ATOMIC_TYPE_DOUBLE: return "double";
+ case ATOMIC_TYPE_LONG_DOUBLE: return "double";
+ case ATOMIC_TYPE_BOOL: return "bool";
+ default: panic("unsupported atomic type");
+ }
+}
+
+static void write_atomic_type(const atomic_type_t *type)
+{
+ fprintf(out, "%s", get_atomic_type_string(type->akind));
+}
+
+static void write_pointer_type(const pointer_type_t *type)
+{
+ type_t *points_to = type->points_to;
+ if (points_to->kind == TYPE_ATOMIC &&
+ is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) {
+ fputs("string", out);
+ return;
+ }
+
+ write_type(type->points_to);
+ fputc('*', out);
+}
+
+static entity_t *find_typedef(const type_t *type)
+{
+ /* first: search for a matching typedef in the global type... */
+ entity_t *entity = global_scope->entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_TYPEDEF)
+ continue;
+ if (entity->typedefe.type == type)
+ break;
+ }
+
+ return entity;
+}
+
+static void write_compound_type(const compound_type_t *type)
+{
+ const entity_t *entity = find_typedef((const type_t*) type);
+ if (entity != NULL) {
+ fprintf(out, "%s", entity->base.symbol->string);
+ return;
+ }
+
+ /* does the struct have a name? */
+ symbol_t *symbol = type->compound->base.symbol;
+ if (symbol != NULL) {
+ /* TODO: make sure we create a struct for it... */
+ fprintf(out, "%s", symbol->string);
+ return;
+ }
+ /* TODO: create a struct and use its name here... */
+ fprintf(out, "/* TODO anonymous struct */byte");
+}
+
+static void write_enum_type(const enum_type_t *type)
+{
+ const entity_t *entity = find_typedef((const type_t*) type);
+ if (entity != NULL) {
+ fprintf(out, "%s", entity->base.symbol->string);
+ return;
+ }
+
+ /* does the enum have a name? */
+ symbol_t *symbol = type->enume->base.symbol;
+ if (symbol != NULL) {
+ /* TODO: make sure we create an enum for it... */
+ fprintf(out, "%s", symbol->string);
+ return;
+ }
+ /* TODO: create a struct and use its name here... */
+ fprintf(out, "/* TODO anonymous enum */byte");
+}
+
+static void write_function_type(const function_type_t *type)
+{
+ fprintf(out, "(func(");
+
+ function_parameter_t *parameter = type->parameters;
+ int first = 1;
+ while(parameter != NULL) {
+ if (!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+
+#if 0
+ if (parameter->symbol != NULL) {
+ fprintf(out, "%s : ", parameter->symbol->string);
+ } else {
+ /* TODO make up some unused names (or allow _ in fluffy?) */
+ fprintf(out, "_ : ");
+ }
+#endif
+ fputs("_ : ", out);
+ write_type(parameter->type);
+
+ parameter = parameter->next;
+ }
+
+ fprintf(out, ") : ");
+ write_type(type->return_type);
+ fprintf(out, ")");
+}
+
+static void write_type(const type_t *type)
+{
+ switch(type->kind) {
+ case TYPE_ATOMIC:
+ write_atomic_type(&type->atomic);
+ return;
+ case TYPE_POINTER:
+ write_pointer_type(&type->pointer);
+ return;
+ case TYPE_COMPOUND_UNION:
+ case TYPE_COMPOUND_STRUCT:
+ write_compound_type(&type->compound);
+ return;
+ case TYPE_ENUM:
+ write_enum_type(&type->enumt);
+ return;
+ case TYPE_FUNCTION:
+ write_function_type(&type->function);
+ return;
+ case TYPE_INVALID:
+ panic("invalid type found");
+ case TYPE_COMPLEX:
+ case TYPE_IMAGINARY:
+ default:
+ fprintf(out, "/* TODO type */");
+ break;
+ }
+}
+
+static void write_function(const entity_t *entity)
+{
+ if (entity->function.statement != NULL) {
+ fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
+ entity->base.symbol->string);
+ }
+
+ fprintf(out, "external %s: ", entity->base.symbol->string);
+
+ const function_type_t *function_type
+ = (const function_type_t*) entity->declaration.type;
+
+ entity_t *parameter = entity->function.parameters.entities;
+ for( ; parameter != NULL; parameter = parameter->base.next) {
+ assert(parameter->kind == ENTITY_PARAMETER);
+ write_type(parameter->declaration.type);
+ fputs(" -> ", out);
+ }
+ if (function_type->variadic) {
+ fprintf(stderr, "WARNING: Variadic function not supported yet\n");
+ }
+ if (function_type->unspecified_parameters) {
+ fprintf(stderr, "WARNING: unspecified params not supported\n");
+ }
+ const type_t *return_type = function_type->return_type;
+ write_type(return_type);
+
+ fputs(" = \"", out);
+ fputs(entity->base.symbol->string, out);
+ fputs("\"", out);
+
+ fputc('\n', out);
+}
+
+void write_caml_decls(FILE *output, const translation_unit_t *unit)
+{
+ out = output;
+ global_scope = &unit->scope;
+
+ ast_set_output(out);
+ fprintf(out, "(* WARNING: Automatically generated file - chaning is useless *)\n");
+
+ /* write functions */
+ entity_t *entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_FUNCTION)
+ continue;
+
+ write_function(entity);
+ }
+}
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef WRITE_CAML_H
+#define WRITE_CAML_H
+
+#include "ast.h"
+
+void write_caml_decls(FILE *out, const translation_unit_t *unit);
+
+#endif
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "write_fluffy.h"
+#include "symbol_t.h"
+#include "ast_t.h"
+#include "type_t.h"
+#include "entity_t.h"
+#include "type.h"
+#include "adt/error.h"
+
+static const scope_t *global_scope;
+static FILE *out;
+
+static void write_type(const type_t *type);
+
+static const char *get_atomic_type_string(const atomic_type_kind_t type)
+{
+ switch(type) {
+ case ATOMIC_TYPE_VOID: return "void";
+ case ATOMIC_TYPE_CHAR: return "byte";
+ case ATOMIC_TYPE_SCHAR: return "byte";
+ case ATOMIC_TYPE_UCHAR: return "unsigned byte";
+ case ATOMIC_TYPE_SHORT: return "short";
+ case ATOMIC_TYPE_USHORT: return "unsigned short";
+ case ATOMIC_TYPE_INT: return "int";
+ case ATOMIC_TYPE_UINT: return "unsigned int";
+ case ATOMIC_TYPE_LONG: return "int";
+ case ATOMIC_TYPE_ULONG: return "unsigned int";
+ case ATOMIC_TYPE_LONGLONG: return "long";
+ case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
+ case ATOMIC_TYPE_FLOAT: return "float";
+ case ATOMIC_TYPE_DOUBLE: return "double";
+ case ATOMIC_TYPE_LONG_DOUBLE: return "double";
+ case ATOMIC_TYPE_BOOL: return "bool";
+ default: panic("unsupported atomic type");
+ }
+}
+
+static void write_atomic_type(const atomic_type_t *type)
+{
+ fprintf(out, "%s", get_atomic_type_string(type->akind));
+}
+
+static void write_pointer_type(const pointer_type_t *type)
+{
+ write_type(type->points_to);
+ fputc('*', out);
+}
+
+static entity_t *find_typedef(const type_t *type)
+{
+ /* first: search for a matching typedef in the global type... */
+ entity_t *entity = global_scope->entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_TYPEDEF)
+ continue;
+ if (entity->typedefe.type == type)
+ break;
+ }
+
+ return entity;
+}
+
+static void write_compound_type(const compound_type_t *type)
+{
+ entity_t *entity = find_typedef((const type_t*) type);
+ if(entity != NULL) {
+ fprintf(out, "%s", entity->base.symbol->string);
+ return;
+ }
+
+ /* does the struct have a name? */
+ symbol_t *symbol = type->compound->base.symbol;
+ if(symbol != NULL) {
+ /* TODO: make sure we create a struct for it... */
+ fprintf(out, "%s", symbol->string);
+ return;
+ }
+ /* TODO: create a struct and use its name here... */
+ fprintf(out, "/* TODO anonymous struct */byte");
+}
+
+static void write_enum_type(const enum_type_t *type)
+{
+ entity_t *entity = find_typedef((const type_t*) type);
+ if (entity != NULL) {
+ fprintf(out, "%s", entity->base.symbol->string);
+ return;
+ }
+
+ /* does the enum have a name? */
+ symbol_t *symbol = type->enume->base.symbol;
+ if (symbol != NULL) {
+ /* TODO: make sure we create an enum for it... */
+ fprintf(out, "%s", symbol->string);
+ return;
+ }
+ /* TODO: create a struct and use its name here... */
+ fprintf(out, "/* TODO anonymous enum */byte");
+}
+
+static void write_function_type(const function_type_t *type)
+{
+ fprintf(out, "(func(");
+
+ function_parameter_t *parameter = type->parameters;
+ int first = 1;
+ while(parameter != NULL) {
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+
+#if 0
+ if(parameter->symbol != NULL) {
+ fprintf(out, "%s : ", parameter->symbol->string);
+ } else {
+ /* TODO make up some unused names (or allow _ in fluffy?) */
+ fprintf(out, "_ : ");
+ }
+#endif
+ fputs("_ : ", out);
+ write_type(parameter->type);
+
+ parameter = parameter->next;
+ }
+
+ fprintf(out, ") : ");
+ write_type(type->return_type);
+ fprintf(out, ")");
+}
+
+static void write_type(const type_t *type)
+{
+ switch(type->kind) {
+ case TYPE_ATOMIC:
+ write_atomic_type(&type->atomic);
+ return;
+ case TYPE_POINTER:
+ write_pointer_type(&type->pointer);
+ return;
+ case TYPE_COMPOUND_UNION:
+ case TYPE_COMPOUND_STRUCT:
+ write_compound_type(&type->compound);
+ return;
+ case TYPE_ENUM:
+ write_enum_type(&type->enumt);
+ return;
+ case TYPE_FUNCTION:
+ write_function_type(&type->function);
+ return;
+ case TYPE_INVALID:
+ panic("invalid type found");
+ case TYPE_COMPLEX:
+ case TYPE_IMAGINARY:
+ default:
+ fprintf(out, "/* TODO type */");
+ break;
+ }
+}
+
+static void write_compound_entry(const entity_t *entity)
+{
+ fprintf(out, "\t%s : ", entity->base.symbol->string);
+ write_type(entity->declaration.type);
+ fprintf(out, "\n");
+}
+
+static void write_compound(const symbol_t *symbol, const compound_type_t *type)
+{
+ fprintf(out, "%s %s:\n",
+ type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
+ symbol->string);
+
+ const entity_t *entity = type->compound->members.entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ write_compound_entry(entity);
+ }
+
+ fprintf(out, "\n");
+}
+
+static void write_expression(const expression_t *expression);
+
+static void write_unary_expression(const unary_expression_t *expression)
+{
+ switch(expression->base.kind) {
+ case EXPR_UNARY_NEGATE:
+ fputc('-', out);
+ break;
+ case EXPR_UNARY_NOT:
+ fputc('!', out);
+ break;
+ default:
+ panic("unimeplemented unary expression found");
+ }
+ write_expression(expression->value);
+}
+
+static void write_expression(const expression_t *expression)
+{
+ const const_expression_t *constant;
+ /* TODO */
+ switch(expression->kind) {
+ case EXPR_CONST:
+ constant = &expression->conste;
+ if(is_type_integer(expression->base.type)) {
+ fprintf(out, "%lld", constant->v.int_value);
+ } else {
+ fprintf(out, "%Lf", constant->v.float_value);
+ }
+ break;
+ EXPR_UNARY_CASES
+ write_unary_expression((const unary_expression_t*) expression);
+ break;
+ default:
+ panic("not implemented expression");
+ }
+}
+
+static void write_enum(const symbol_t *symbol, const enum_type_t *type)
+{
+ fprintf(out, "enum %s:\n", symbol->string);
+
+ entity_t *entry = type->enume->base.next;
+ for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
+ entry = entry->base.next) {
+ fprintf(out, "\t%s", entry->base.symbol->string);
+ if(entry->enum_value.value != NULL) {
+ fprintf(out, " <- ");
+ write_expression(entry->enum_value.value);
+ }
+ fputc('\n', out);
+ }
+ fprintf(out, "typealias %s <- int\n", symbol->string);
+ fprintf(out, "\n");
+}
+
+static void write_variable(const entity_t *entity)
+{
+ fprintf(out, "var %s : ", entity->base.symbol->string);
+ write_type(entity->declaration.type);
+ fprintf(out, "\n");
+}
+
+static void write_function(const entity_t *entity)
+{
+ if (entity->function.statement != NULL) {
+ fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
+ entity->base.symbol->string);
+ }
+
+ fprintf(out, "func extern %s(", entity->base.symbol->string);
+
+ const function_type_t *function_type
+ = (const function_type_t*) entity->declaration.type;
+
+ entity_t *parameter = entity->function.parameters.entities;
+ int first = 1;
+ for( ; parameter != NULL; parameter = parameter->base.next) {
+ assert(parameter->kind == ENTITY_PARAMETER);
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+ if(parameter->base.symbol != NULL) {
+ fprintf(out, "%s : ", parameter->base.symbol->string);
+ } else {
+ fputs("_ : ", out);
+ }
+ write_type(parameter->declaration.type);
+ }
+ if(function_type->variadic) {
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+ fputs("...", out);
+ }
+ fprintf(out, ")");
+
+ const type_t *return_type = skip_typeref(function_type->return_type);
+ if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+ fprintf(out, " : ");
+ write_type(return_type);
+ }
+ fputc('\n', out);
+}
+
+void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
+{
+ out = output;
+ global_scope = &unit->scope;
+
+ ast_set_output(out);
+ type_set_output(out);
+ fprintf(out, "/* WARNING: Automatically generated file */\n");
+
+ /* write structs,unions + enums */
+ entity_t *entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_TYPEDEF)
+ continue;
+
+ type_t *type = entity->typedefe.type;
+ if(type->kind == TYPE_COMPOUND_STRUCT
+ || type->kind == TYPE_COMPOUND_UNION) {
+ write_compound(entity->base.symbol, &type->compound);
+ } else if(type->kind == TYPE_ENUM) {
+ write_enum(entity->base.symbol, &type->enumt);
+ }
+ }
+
+ /* write global variables */
+ entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_VARIABLE)
+ continue;
+
+ write_variable(entity);
+ }
+
+ /* write functions */
+ entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_FUNCTION)
+ continue;
+
+ write_function(entity);
+ }
+}
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef WRITE_FLUFFY_H
+#define WRITE_FLUFFY_H
+
+#include "ast.h"
+
+void write_fluffy_decls(FILE *out, const translation_unit_t *unit);
+
+#endif
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "write_jna.h"
+#include "symbol_t.h"
+#include "ast_t.h"
+#include "type_t.h"
+#include "entity_t.h"
+#include "type.h"
+#include "adt/error.h"
+#include <libfirm/adt/pset_new.h>
+
+static const scope_t *global_scope;
+static FILE *out;
+static pset_new_t avoid_symbols;
+
+static void write_type(type_t *type);
+
+static bool is_system_header(const char *fname)
+{
+ return strncmp(fname, "/usr/include", 12) == 0;
+}
+
+static const char *fix_builtin_names(const char *name)
+{
+ if (strcmp(name, "class") == 0) {
+ return "_class";
+ } else if(strcmp(name, "this") == 0) {
+ return "_this";
+ } else if(strcmp(name, "public") == 0) {
+ return "_public";
+ } else if(strcmp(name, "protected") == 0) {
+ return "_protected";
+ } else if(strcmp(name, "private") == 0) {
+ return "_private";
+ } else if(strcmp(name, "final") == 0) {
+ return "_final";
+ }
+ /* TODO put all reserved names here */
+ return name;
+}
+
+static const char *get_atomic_type_string(const atomic_type_kind_t type)
+{
+ switch(type) {
+ case ATOMIC_TYPE_VOID: return "void";
+ case ATOMIC_TYPE_CHAR: return "byte";
+ case ATOMIC_TYPE_SCHAR: return "byte";
+ case ATOMIC_TYPE_UCHAR: return "byte";
+ case ATOMIC_TYPE_SHORT: return "short";
+ case ATOMIC_TYPE_USHORT: return "short";
+ case ATOMIC_TYPE_INT: return "int";
+ case ATOMIC_TYPE_UINT: return "int";
+ case ATOMIC_TYPE_LONG: return "NativeLong";
+ case ATOMIC_TYPE_ULONG: return "NativeLong";
+ case ATOMIC_TYPE_LONGLONG: return "long";
+ case ATOMIC_TYPE_ULONGLONG: return "long";
+ case ATOMIC_TYPE_FLOAT: return "float";
+ case ATOMIC_TYPE_DOUBLE: return "double";
+ case ATOMIC_TYPE_LONG_DOUBLE: return "double";
+ case ATOMIC_TYPE_BOOL: return "boolean";
+ default: panic("unsupported atomic type");
+ }
+}
+
+static void write_atomic_type(const atomic_type_t *type)
+{
+ fputs(get_atomic_type_string(type->akind), out);
+}
+
+static void write_pointer_type(const pointer_type_t *type)
+{
+ type_t *points_to = skip_typeref(type->points_to);
+ if (is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) {
+ fputs("String", out);
+ return;
+ }
+ fputs("Pointer", out);
+}
+
+static entity_t *find_typedef(const type_t *type)
+{
+ /* first: search for a matching typedef in the global type... */
+ entity_t *entity = global_scope->entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_TYPEDEF)
+ continue;
+ if (entity->typedefe.type == type)
+ break;
+ }
+
+ return entity;
+}
+
+static entity_t *find_enum_typedef(const enum_t *enume)
+{
+ /* first: search for a matching typedef in the global type... */
+ entity_t *entity = global_scope->entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_TYPEDEF)
+ continue;
+ type_t *type = entity->typedefe.type;
+ if (type->kind != TYPE_ENUM)
+ continue;
+
+ enum_t *e_entity = type->enumt.enume;
+ if (e_entity == enume)
+ break;
+ }
+
+ return entity;
+}
+
+static void write_compound_type(const compound_type_t *type)
+{
+ entity_t *entity = find_typedef((const type_t*) type);
+ if(entity != NULL) {
+ fputs(entity->base.symbol->string, out);
+ return;
+ }
+
+ /* does the struct have a name? */
+ symbol_t *symbol = type->compound->base.symbol;
+ if(symbol != NULL) {
+ /* TODO: make sure we create a struct for it... */
+ fputs(symbol->string, out);
+ return;
+ }
+ /* TODO: create a struct and use its name here... */
+ fputs("/* TODO anonymous struct */byte", out);
+}
+
+static void write_enum_name(const enum_type_t *type)
+{
+ entity_t *entity = find_typedef((const type_t*) type);
+ if (entity != NULL) {
+ fputs(entity->base.symbol->string, out);
+ return;
+ }
+
+ /* does the enum have a name? */
+ symbol_t *symbol = type->enume->base.symbol;
+ if (symbol != NULL) {
+ /* TODO: make sure we create an enum for it... */
+ fputs(symbol->string, out);
+ return;
+ }
+
+ /* now we have a problem as we don't know how we'll call the anonymous
+ * enum */
+ panic("can't reference entries from anonymous enums yet");
+}
+
+static void write_enum_type(const enum_type_t *type)
+{
+ entity_t *entity = find_typedef((const type_t*) type);
+ if (entity != NULL) {
+ fprintf(out, "/* %s */int", entity->base.symbol->string);
+ return;
+ }
+
+ /* does the enum have a name? */
+ symbol_t *symbol = type->enume->base.symbol;
+ if (symbol != NULL) {
+ /* TODO: make sure we create an enum for it... */
+ fprintf(out, "/* %s */int", symbol->string);
+ return;
+ }
+ fprintf(out, "/* anonymous enum */int");
+}
+
+static void write_type(type_t *type)
+{
+ type = skip_typeref(type);
+ switch(type->kind) {
+ case TYPE_ATOMIC:
+ write_atomic_type(&type->atomic);
+ return;
+ case TYPE_POINTER:
+ write_pointer_type(&type->pointer);
+ return;
+ case TYPE_COMPOUND_UNION:
+ case TYPE_COMPOUND_STRUCT:
+ write_compound_type(&type->compound);
+ return;
+ case TYPE_ENUM:
+ write_enum_type(&type->enumt);
+ return;
+ case TYPE_BUILTIN:
+ write_type(type->builtin.real_type);
+ return;
+ case TYPE_ERROR:
+ case TYPE_INVALID:
+ case TYPE_TYPEOF:
+ case TYPE_TYPEDEF:
+ panic("invalid type found");
+ case TYPE_ARRAY:
+ case TYPE_BITFIELD:
+ case TYPE_REFERENCE:
+ case TYPE_FUNCTION:
+ case TYPE_COMPLEX:
+ case TYPE_IMAGINARY:
+ fprintf(out, "/* TODO type */Pointer");
+ break;
+ }
+}
+
+#if 0
+static void write_compound_entry(const entity_t *entity)
+{
+ fprintf(out, "\t%s : ", entity->base.symbol->string);
+ write_type(entity->declaration.type);
+ fprintf(out, "\n");
+}
+
+static void write_compound(const symbol_t *symbol, const compound_type_t *type)
+{
+ fprintf(out, "%s %s:\n",
+ type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
+ symbol->string);
+
+ const entity_t *entity = type->compound->members.entities;
+ for ( ; entity != NULL; entity = entity->base.next) {
+ write_compound_entry(entity);
+ }
+
+ fprintf(out, "\n");
+}
+#endif
+
+static void write_expression(const expression_t *expression);
+
+static void write_unary_expression(const unary_expression_t *expression)
+{
+ switch(expression->base.kind) {
+ case EXPR_UNARY_NEGATE:
+ fputc('-', out);
+ break;
+ case EXPR_UNARY_NOT:
+ fputc('!', out);
+ break;
+ case EXPR_UNARY_CAST_IMPLICIT:
+ write_expression(expression->value);
+ return;
+ default:
+ panic("unimeplemented unary expression found");
+ }
+ write_expression(expression->value);
+}
+
+static void write_binary_expression(const binary_expression_t *expression)
+{
+ fputs("(", out);
+ write_expression(expression->left);
+ switch(expression->base.kind) {
+ case EXPR_BINARY_BITWISE_OR: fputs("|", out); break;
+ case EXPR_BINARY_BITWISE_AND: fputs("&", out); break;
+ case EXPR_BINARY_BITWISE_XOR: fputs("^", out); break;
+ case EXPR_BINARY_SHIFTLEFT: fputs("<<", out); break;
+ case EXPR_BINARY_SHIFTRIGHT: fputs(">>", out); break;
+ case EXPR_BINARY_ADD: fputs("+", out); break;
+ case EXPR_BINARY_SUB: fputs("-", out); break;
+ case EXPR_BINARY_MUL: fputs("*", out); break;
+ case EXPR_BINARY_DIV: fputs("/", out); break;
+ default:
+ panic("unimplemented binexpr");
+ }
+ write_expression(expression->right);
+ fputs(")", out);
+}
+
+static void write_expression(const expression_t *expression)
+{
+ const const_expression_t *constant;
+ /* TODO */
+ switch(expression->kind) {
+ case EXPR_CONST:
+ constant = &expression->conste;
+ if(is_type_integer(expression->base.type)) {
+ fprintf(out, "%lld", constant->v.int_value);
+ } else {
+ fprintf(out, "%Lf", constant->v.float_value);
+ }
+ break;
+ case EXPR_REFERENCE_ENUM_VALUE: {
+ /* UHOH... hacking */
+ entity_t *entity = expression->reference.entity;
+ write_enum_name(& entity->enum_value.enum_type->enumt);
+ fprintf(out, ".%s.val", entity->base.symbol->string);
+ break;
+ }
+ EXPR_UNARY_CASES
+ write_unary_expression(&expression->unary);
+ break;
+ EXPR_BINARY_CASES
+ write_binary_expression(&expression->binary);
+ break;
+ default:
+ panic("not implemented expression");
+ }
+}
+
+static void write_enum(const symbol_t *symbol, const enum_t *entity)
+{
+ char buf[128];
+ const char *name;
+
+ if (symbol == NULL) {
+ static int lastenum = 0;
+ snprintf(buf, sizeof(buf), "AnonEnum%d", lastenum++);
+ name = buf;
+ } else {
+ name = symbol->string;
+ }
+
+ fprintf(out, "\tpublic static enum %s {\n", name);
+
+ entity_t *entry = entity->base.next;
+ for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
+ entry = entry->base.next) {
+ fprintf(out, "\t\t%s", entry->base.symbol->string);
+ fprintf(out, "(");
+ if(entry->enum_value.value != NULL) {
+ write_expression(entry->enum_value.value);
+ }
+ fprintf(out, ")");
+ if (entry->base.next != NULL
+ && entry->base.next->kind == ENTITY_ENUM_VALUE) {
+ fputs(",\n", out);
+ } else {
+ fputs(";\n", out);
+ }
+ }
+ fprintf(out, "\t\tpublic final int val;\n");
+ fprintf(out, "\t\tprivate static class C { static int next_val; }\n\n");
+ fprintf(out, "\t\t%s(int val) {\n", name);
+ fprintf(out, "\t\t\tthis.val = val;\n");
+ fprintf(out, "\t\t\tC.next_val = val + 1;\n");
+ fprintf(out, "\t\t}\n");
+ fprintf(out, "\t\t%s() {\n", name);
+ fprintf(out, "\t\t\tthis.val = C.next_val++;\n");
+ fprintf(out, "\t\t}\n");
+ fprintf(out, "\t\t\n");
+ fprintf(out, "\t\tpublic static %s getEnum(int val) {\n", name);
+ fprintf(out, "\t\t\tfor(%s entry : values()) {\n", name);
+ fprintf(out, "\t\t\t\tif (val == entry.val)\n");
+ fprintf(out, "\t\t\t\t\treturn entry;\n");
+ fprintf(out, "\t\t\t}\n");
+ fprintf(out, "\t\t\treturn null;\n");
+ fprintf(out, "\t\t}\n");
+ fprintf(out, "\t}\n");
+}
+
+#if 0
+static void write_variable(const entity_t *entity)
+{
+ fprintf(out, "var %s : ", entity->base.symbol->string);
+ write_type(entity->declaration.type);
+ fprintf(out, "\n");
+}
+#endif
+
+static void write_function(const entity_t *entity)
+{
+ if (entity->function.statement != NULL) {
+ fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
+ entity->base.symbol->string);
+ return;
+ }
+
+
+ const function_type_t *function_type
+ = (const function_type_t*) entity->declaration.type;
+
+ fputc('\t', out);
+ type_t *return_type = skip_typeref(function_type->return_type);
+ write_type(return_type);
+ fprintf(out, " %s(", entity->base.symbol->string);
+
+ entity_t *parameter = entity->function.parameters.entities;
+ int first = 1;
+ int n = 0;
+ for( ; parameter != NULL; parameter = parameter->base.next) {
+ assert(parameter->kind == ENTITY_PARAMETER);
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+ write_type(parameter->declaration.type);
+ if(parameter->base.symbol != NULL) {
+ fprintf(out, " %s", fix_builtin_names(parameter->base.symbol->string));
+ } else {
+ fprintf(out, " _%d", n++);
+ }
+ }
+ if(function_type->variadic) {
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+ fputs("Object ... args", out);
+ }
+ fprintf(out, ");\n");
+}
+
+
+void write_jna_decls(FILE *output, const translation_unit_t *unit)
+{
+ out = output;
+ global_scope = &unit->scope;
+
+ pset_new_init(&avoid_symbols);
+
+ ast_set_output(out);
+ type_set_output(out);
+ fprintf(out, "/* WARNING: Automatically generated file */\n");
+ fputs("import com.sun.jna.Library;\n", out);
+ fputs("import com.sun.jna.Native;\n", out);
+ fputs("import com.sun.jna.Platform;\n", out);
+ fputs("import com.sun.jna.Pointer;\n", out);
+ fputs("import com.sun.jna.NativeLong;\n", out);
+ fputs("\n\n", out);
+
+ /* TODO: where to get the name from? */
+ fputs("public interface binding extends Library {\n", out);
+
+ /* read the avoid list */
+ FILE *avoid = fopen("avoid.config", "r");
+ if (avoid != NULL) {
+ while (!feof(avoid)) {
+ char buf[1024];
+ fgets(buf, sizeof(buf), avoid);
+ size_t len = strlen(buf);
+ if (buf[len-1] == '\n')
+ buf[len-1] = 0;
+ if (buf[0] == 0)
+ continue;
+
+ symbol_t *symbol = symbol_table_insert(buf);
+ pset_new_insert(&avoid_symbols, symbol);
+ }
+ fclose(avoid);
+ }
+
+ /* write structs,unions + enums */
+ entity_t *entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind == ENTITY_ENUM) {
+ if (find_enum_typedef(&entity->enume) != NULL)
+ continue;
+ write_enum(entity->base.symbol, &entity->enume);
+ } else if (entity->kind == ENTITY_TYPEDEF) {
+ type_t *type = entity->typedefe.type;
+ if (type->kind == TYPE_ENUM) {
+ write_enum(entity->base.symbol, type->enumt.enume);
+ }
+ }
+
+#if 0
+ if(type->kind == TYPE_COMPOUND_STRUCT
+ || type->kind == TYPE_COMPOUND_UNION) {
+ write_compound(entity->base.symbol, &type->compound);
+ }
+#endif
+ }
+
+ /* write functions */
+ entity = unit->scope.entities;
+ for( ; entity != NULL; entity = entity->base.next) {
+ if (entity->kind != ENTITY_FUNCTION)
+ continue;
+ if (is_system_header(entity->base.source_position.input_name))
+ continue;
+
+ if (pset_new_contains(&avoid_symbols, entity->base.symbol))
+ continue;
+ write_function(entity);
+ }
+
+ fputs("}\n", out);
+
+ pset_new_destroy(&avoid_symbols);
+}
--- /dev/null
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef WRITE_JNA_H
+#define WRITE_JNA_H
+
+#include "ast.h"
+
+void write_jna_decls(FILE *out, const translation_unit_t *unit);
+
+#endif
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-#include <config.h>
-
-#include <errno.h>
-#include <string.h>
-
-#include "write_caml.h"
-#include "symbol_t.h"
-#include "ast_t.h"
-#include "type_t.h"
-#include "entity_t.h"
-#include "type.h"
-#include "adt/error.h"
-
-static const scope_t *global_scope;
-static FILE *out;
-
-static void write_type(const type_t *type);
-
-static const char *get_atomic_type_string(const atomic_type_kind_t type)
-{
- switch(type) {
- case ATOMIC_TYPE_VOID: return "unit";
- case ATOMIC_TYPE_CHAR: return "byte";
- case ATOMIC_TYPE_SCHAR: return "byte";
- case ATOMIC_TYPE_UCHAR: return "unsigned byte";
- case ATOMIC_TYPE_SHORT: return "short";
- case ATOMIC_TYPE_USHORT: return "unsigned short";
- case ATOMIC_TYPE_INT: return "int";
- case ATOMIC_TYPE_UINT: return "unsigned int";
- case ATOMIC_TYPE_LONG: return "int";
- case ATOMIC_TYPE_ULONG: return "unsigned int";
- case ATOMIC_TYPE_LONGLONG: return "long";
- case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
- case ATOMIC_TYPE_FLOAT: return "float";
- case ATOMIC_TYPE_DOUBLE: return "double";
- case ATOMIC_TYPE_LONG_DOUBLE: return "double";
- case ATOMIC_TYPE_BOOL: return "bool";
- default: panic("unsupported atomic type");
- }
-}
-
-static void write_atomic_type(const atomic_type_t *type)
-{
- fprintf(out, "%s", get_atomic_type_string(type->akind));
-}
-
-static void write_pointer_type(const pointer_type_t *type)
-{
- type_t *points_to = type->points_to;
- if (points_to->kind == TYPE_ATOMIC &&
- is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) {
- fputs("string", out);
- return;
- }
-
- write_type(type->points_to);
- fputc('*', out);
-}
-
-static entity_t *find_typedef(const type_t *type)
-{
- /* first: search for a matching typedef in the global type... */
- entity_t *entity = global_scope->entities;
- for ( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_TYPEDEF)
- continue;
- if (entity->typedefe.type == type)
- break;
- }
-
- return entity;
-}
-
-static void write_compound_type(const compound_type_t *type)
-{
- const entity_t *entity = find_typedef((const type_t*) type);
- if (entity != NULL) {
- fprintf(out, "%s", entity->base.symbol->string);
- return;
- }
-
- /* does the struct have a name? */
- symbol_t *symbol = type->compound->base.symbol;
- if (symbol != NULL) {
- /* TODO: make sure we create a struct for it... */
- fprintf(out, "%s", symbol->string);
- return;
- }
- /* TODO: create a struct and use its name here... */
- fprintf(out, "/* TODO anonymous struct */byte");
-}
-
-static void write_enum_type(const enum_type_t *type)
-{
- const entity_t *entity = find_typedef((const type_t*) type);
- if (entity != NULL) {
- fprintf(out, "%s", entity->base.symbol->string);
- return;
- }
-
- /* does the enum have a name? */
- symbol_t *symbol = type->enume->base.symbol;
- if (symbol != NULL) {
- /* TODO: make sure we create an enum for it... */
- fprintf(out, "%s", symbol->string);
- return;
- }
- /* TODO: create a struct and use its name here... */
- fprintf(out, "/* TODO anonymous enum */byte");
-}
-
-static void write_function_type(const function_type_t *type)
-{
- fprintf(out, "(func(");
-
- function_parameter_t *parameter = type->parameters;
- int first = 1;
- while(parameter != NULL) {
- if (!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
-
-#if 0
- if (parameter->symbol != NULL) {
- fprintf(out, "%s : ", parameter->symbol->string);
- } else {
- /* TODO make up some unused names (or allow _ in fluffy?) */
- fprintf(out, "_ : ");
- }
-#endif
- fputs("_ : ", out);
- write_type(parameter->type);
-
- parameter = parameter->next;
- }
-
- fprintf(out, ") : ");
- write_type(type->return_type);
- fprintf(out, ")");
-}
-
-static void write_type(const type_t *type)
-{
- switch(type->kind) {
- case TYPE_ATOMIC:
- write_atomic_type(&type->atomic);
- return;
- case TYPE_POINTER:
- write_pointer_type(&type->pointer);
- return;
- case TYPE_COMPOUND_UNION:
- case TYPE_COMPOUND_STRUCT:
- write_compound_type(&type->compound);
- return;
- case TYPE_ENUM:
- write_enum_type(&type->enumt);
- return;
- case TYPE_FUNCTION:
- write_function_type(&type->function);
- return;
- case TYPE_INVALID:
- panic("invalid type found");
- case TYPE_COMPLEX:
- case TYPE_IMAGINARY:
- default:
- fprintf(out, "/* TODO type */");
- break;
- }
-}
-
-static void write_function(const entity_t *entity)
-{
- if (entity->function.statement != NULL) {
- fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
- entity->base.symbol->string);
- }
-
- fprintf(out, "external %s: ", entity->base.symbol->string);
-
- const function_type_t *function_type
- = (const function_type_t*) entity->declaration.type;
-
- entity_t *parameter = entity->function.parameters.entities;
- for( ; parameter != NULL; parameter = parameter->base.next) {
- assert(parameter->kind == ENTITY_PARAMETER);
- write_type(parameter->declaration.type);
- fputs(" -> ", out);
- }
- if (function_type->variadic) {
- fprintf(stderr, "WARNING: Variadic function not supported yet\n");
- }
- if (function_type->unspecified_parameters) {
- fprintf(stderr, "WARNING: unspecified params not supported\n");
- }
- const type_t *return_type = function_type->return_type;
- write_type(return_type);
-
- fputs(" = \"", out);
- fputs(entity->base.symbol->string, out);
- fputs("\"", out);
-
- fputc('\n', out);
-}
-
-void write_caml_decls(FILE *output, const translation_unit_t *unit)
-{
- out = output;
- global_scope = &unit->scope;
-
- ast_set_output(out);
- fprintf(out, "(* WARNING: Automatically generated file - chaning is useless *)\n");
-
- /* write functions */
- entity_t *entity = unit->scope.entities;
- for( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_FUNCTION)
- continue;
-
- write_function(entity);
- }
-}
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-#ifndef WRITE_CAML_H
-#define WRITE_CAML_H
-
-#include "ast.h"
-
-void write_caml_decls(FILE *out, const translation_unit_t *unit);
-
-#endif
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-#include <config.h>
-
-#include <errno.h>
-#include <string.h>
-
-#include "write_fluffy.h"
-#include "symbol_t.h"
-#include "ast_t.h"
-#include "type_t.h"
-#include "entity_t.h"
-#include "type.h"
-#include "adt/error.h"
-
-static const scope_t *global_scope;
-static FILE *out;
-
-static void write_type(const type_t *type);
-
-static const char *get_atomic_type_string(const atomic_type_kind_t type)
-{
- switch(type) {
- case ATOMIC_TYPE_VOID: return "void";
- case ATOMIC_TYPE_CHAR: return "byte";
- case ATOMIC_TYPE_SCHAR: return "byte";
- case ATOMIC_TYPE_UCHAR: return "unsigned byte";
- case ATOMIC_TYPE_SHORT: return "short";
- case ATOMIC_TYPE_USHORT: return "unsigned short";
- case ATOMIC_TYPE_INT: return "int";
- case ATOMIC_TYPE_UINT: return "unsigned int";
- case ATOMIC_TYPE_LONG: return "int";
- case ATOMIC_TYPE_ULONG: return "unsigned int";
- case ATOMIC_TYPE_LONGLONG: return "long";
- case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
- case ATOMIC_TYPE_FLOAT: return "float";
- case ATOMIC_TYPE_DOUBLE: return "double";
- case ATOMIC_TYPE_LONG_DOUBLE: return "double";
- case ATOMIC_TYPE_BOOL: return "bool";
- default: panic("unsupported atomic type");
- }
-}
-
-static void write_atomic_type(const atomic_type_t *type)
-{
- fprintf(out, "%s", get_atomic_type_string(type->akind));
-}
-
-static void write_pointer_type(const pointer_type_t *type)
-{
- write_type(type->points_to);
- fputc('*', out);
-}
-
-static entity_t *find_typedef(const type_t *type)
-{
- /* first: search for a matching typedef in the global type... */
- entity_t *entity = global_scope->entities;
- for ( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_TYPEDEF)
- continue;
- if (entity->typedefe.type == type)
- break;
- }
-
- return entity;
-}
-
-static void write_compound_type(const compound_type_t *type)
-{
- entity_t *entity = find_typedef((const type_t*) type);
- if(entity != NULL) {
- fprintf(out, "%s", entity->base.symbol->string);
- return;
- }
-
- /* does the struct have a name? */
- symbol_t *symbol = type->compound->base.symbol;
- if(symbol != NULL) {
- /* TODO: make sure we create a struct for it... */
- fprintf(out, "%s", symbol->string);
- return;
- }
- /* TODO: create a struct and use its name here... */
- fprintf(out, "/* TODO anonymous struct */byte");
-}
-
-static void write_enum_type(const enum_type_t *type)
-{
- entity_t *entity = find_typedef((const type_t*) type);
- if (entity != NULL) {
- fprintf(out, "%s", entity->base.symbol->string);
- return;
- }
-
- /* does the enum have a name? */
- symbol_t *symbol = type->enume->base.symbol;
- if (symbol != NULL) {
- /* TODO: make sure we create an enum for it... */
- fprintf(out, "%s", symbol->string);
- return;
- }
- /* TODO: create a struct and use its name here... */
- fprintf(out, "/* TODO anonymous enum */byte");
-}
-
-static void write_function_type(const function_type_t *type)
-{
- fprintf(out, "(func(");
-
- function_parameter_t *parameter = type->parameters;
- int first = 1;
- while(parameter != NULL) {
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
-
-#if 0
- if(parameter->symbol != NULL) {
- fprintf(out, "%s : ", parameter->symbol->string);
- } else {
- /* TODO make up some unused names (or allow _ in fluffy?) */
- fprintf(out, "_ : ");
- }
-#endif
- fputs("_ : ", out);
- write_type(parameter->type);
-
- parameter = parameter->next;
- }
-
- fprintf(out, ") : ");
- write_type(type->return_type);
- fprintf(out, ")");
-}
-
-static void write_type(const type_t *type)
-{
- switch(type->kind) {
- case TYPE_ATOMIC:
- write_atomic_type(&type->atomic);
- return;
- case TYPE_POINTER:
- write_pointer_type(&type->pointer);
- return;
- case TYPE_COMPOUND_UNION:
- case TYPE_COMPOUND_STRUCT:
- write_compound_type(&type->compound);
- return;
- case TYPE_ENUM:
- write_enum_type(&type->enumt);
- return;
- case TYPE_FUNCTION:
- write_function_type(&type->function);
- return;
- case TYPE_INVALID:
- panic("invalid type found");
- case TYPE_COMPLEX:
- case TYPE_IMAGINARY:
- default:
- fprintf(out, "/* TODO type */");
- break;
- }
-}
-
-static void write_compound_entry(const entity_t *entity)
-{
- fprintf(out, "\t%s : ", entity->base.symbol->string);
- write_type(entity->declaration.type);
- fprintf(out, "\n");
-}
-
-static void write_compound(const symbol_t *symbol, const compound_type_t *type)
-{
- fprintf(out, "%s %s:\n",
- type->base.kind == TYPE_COMPOUND_STRUCT ? "struct" : "union",
- symbol->string);
-
- const entity_t *entity = type->compound->members.entities;
- for ( ; entity != NULL; entity = entity->base.next) {
- write_compound_entry(entity);
- }
-
- fprintf(out, "\n");
-}
-
-static void write_expression(const expression_t *expression);
-
-static void write_unary_expression(const unary_expression_t *expression)
-{
- switch(expression->base.kind) {
- case EXPR_UNARY_NEGATE:
- fputc('-', out);
- break;
- case EXPR_UNARY_NOT:
- fputc('!', out);
- break;
- default:
- panic("unimeplemented unary expression found");
- }
- write_expression(expression->value);
-}
-
-static void write_expression(const expression_t *expression)
-{
- const const_expression_t *constant;
- /* TODO */
- switch(expression->kind) {
- case EXPR_CONST:
- constant = &expression->conste;
- if(is_type_integer(expression->base.type)) {
- fprintf(out, "%lld", constant->v.int_value);
- } else {
- fprintf(out, "%Lf", constant->v.float_value);
- }
- break;
- EXPR_UNARY_CASES
- write_unary_expression((const unary_expression_t*) expression);
- break;
- default:
- panic("not implemented expression");
- }
-}
-
-static void write_enum(const symbol_t *symbol, const enum_type_t *type)
-{
- fprintf(out, "enum %s:\n", symbol->string);
-
- entity_t *entry = type->enume->base.next;
- for ( ; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
- entry = entry->base.next) {
- fprintf(out, "\t%s", entry->base.symbol->string);
- if(entry->enum_value.value != NULL) {
- fprintf(out, " <- ");
- write_expression(entry->enum_value.value);
- }
- fputc('\n', out);
- }
- fprintf(out, "typealias %s <- int\n", symbol->string);
- fprintf(out, "\n");
-}
-
-static void write_variable(const entity_t *entity)
-{
- fprintf(out, "var %s : ", entity->base.symbol->string);
- write_type(entity->declaration.type);
- fprintf(out, "\n");
-}
-
-static void write_function(const entity_t *entity)
-{
- if (entity->function.statement != NULL) {
- fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
- entity->base.symbol->string);
- }
-
- fprintf(out, "func extern %s(", entity->base.symbol->string);
-
- const function_type_t *function_type
- = (const function_type_t*) entity->declaration.type;
-
- entity_t *parameter = entity->function.parameters.entities;
- int first = 1;
- for( ; parameter != NULL; parameter = parameter->base.next) {
- assert(parameter->kind == ENTITY_PARAMETER);
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
- if(parameter->base.symbol != NULL) {
- fprintf(out, "%s : ", parameter->base.symbol->string);
- } else {
- fputs("_ : ", out);
- }
- write_type(parameter->declaration.type);
- }
- if(function_type->variadic) {
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
- fputs("...", out);
- }
- fprintf(out, ")");
-
- const type_t *return_type = skip_typeref(function_type->return_type);
- if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
- fprintf(out, " : ");
- write_type(return_type);
- }
- fputc('\n', out);
-}
-
-void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
-{
- out = output;
- global_scope = &unit->scope;
-
- ast_set_output(out);
- type_set_output(out);
- fprintf(out, "/* WARNING: Automatically generated file */\n");
-
- /* write structs,unions + enums */
- entity_t *entity = unit->scope.entities;
- for( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_TYPEDEF)
- continue;
-
- type_t *type = entity->typedefe.type;
- if(type->kind == TYPE_COMPOUND_STRUCT
- || type->kind == TYPE_COMPOUND_UNION) {
- write_compound(entity->base.symbol, &type->compound);
- } else if(type->kind == TYPE_ENUM) {
- write_enum(entity->base.symbol, &type->enumt);
- }
- }
-
- /* write global variables */
- entity = unit->scope.entities;
- for( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_VARIABLE)
- continue;
-
- write_variable(entity);
- }
-
- /* write functions */
- entity = unit->scope.entities;
- for( ; entity != NULL; entity = entity->base.next) {
- if (entity->kind != ENTITY_FUNCTION)
- continue;
-
- write_function(entity);
- }
-}
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-#ifndef WRITE_FLUFFY_H
-#define WRITE_FLUFFY_H
-
-#include "ast.h"
-
-void write_fluffy_decls(FILE *out, const translation_unit_t *unit);
-
-#endif