first revision of jna writer
authorMatthias Braun <matze@braunis.de>
Wed, 10 Dec 2008 20:10:19 +0000 (20:10 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 10 Dec 2008 20:10:19 +0000 (20:10 +0000)
[r24503]

13 files changed:
Makefile
adt/pset.h [deleted file]
main.c
wrappergen/write_caml.c [new file with mode: 0644]
wrappergen/write_caml.h [new file with mode: 0644]
wrappergen/write_fluffy.c [new file with mode: 0644]
wrappergen/write_fluffy.h [new file with mode: 0644]
wrappergen/write_jna.c [new file with mode: 0644]
wrappergen/write_jna.h [new file with mode: 0644]
write_caml.c [deleted file]
write_caml.h [deleted file]
write_fluffy.c [deleted file]
write_fluffy.h [deleted file]

index 9ca0876..73c1bad 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,8 +45,9 @@ SOURCES := \
        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 \
@@ -91,7 +92,7 @@ REVISION ?= $(shell svnversion -n .)
        @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)
diff --git a/adt/pset.h b/adt/pset.h
deleted file mode 100644 (file)
index e56148a..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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
diff --git a/main.c b/main.c
index d9afcdb..e711e2b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -72,8 +72,9 @@
 #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"
@@ -508,7 +509,8 @@ typedef enum compile_mode_t {
        LexTest,
        PrintAst,
        PrintFluffy,
-       PrintCaml
+       PrintCaml,
+       PrintJna
 } compile_mode_t;
 
 static void usage(const char *argv0)
@@ -1038,6 +1040,8 @@ int main(int argc, char **argv)
                                        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);
@@ -1157,6 +1161,7 @@ int main(int argc, char **argv)
                case PrintAst:
                case PrintFluffy:
                case PrintCaml:
+               case PrintJna:
                case LexTest:
                case PreprocessOnly:
                case ParseOnly:
@@ -1348,6 +1353,9 @@ do_parsing:
                        } 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);
diff --git a/wrappergen/write_caml.c b/wrappergen/write_caml.c
new file mode 100644 (file)
index 0000000..c226c3d
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * 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);
+       }
+}
diff --git a/wrappergen/write_caml.h b/wrappergen/write_caml.h
new file mode 100644 (file)
index 0000000..9273e47
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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
diff --git a/wrappergen/write_fluffy.c b/wrappergen/write_fluffy.c
new file mode 100644 (file)
index 0000000..dadf943
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * 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);
+       }
+}
diff --git a/wrappergen/write_fluffy.h b/wrappergen/write_fluffy.h
new file mode 100644 (file)
index 0000000..4f997f0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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
diff --git a/wrappergen/write_jna.c b/wrappergen/write_jna.c
new file mode 100644 (file)
index 0000000..8f438ff
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * 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);
+}
diff --git a/wrappergen/write_jna.h b/wrappergen/write_jna.h
new file mode 100644 (file)
index 0000000..73d9e41
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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
diff --git a/write_caml.c b/write_caml.c
deleted file mode 100644 (file)
index c226c3d..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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);
-       }
-}
diff --git a/write_caml.h b/write_caml.h
deleted file mode 100644 (file)
index 9273e47..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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
diff --git a/write_fluffy.c b/write_fluffy.c
deleted file mode 100644 (file)
index dadf943..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * 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);
-       }
-}
diff --git a/write_fluffy.h b/write_fluffy.h
deleted file mode 100644 (file)
index 4f997f0..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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