From 619e8bbd734140dd6562c9f10c43c029eaa3f52d Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Fri, 7 Sep 2007 10:39:01 +0000 Subject: [PATCH] support for writing functions and function types in fluffy export [r18338] --- write_fluffy.c | 169 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 142 insertions(+), 27 deletions(-) diff --git a/write_fluffy.c b/write_fluffy.c index 51b058b..be6a71c 100644 --- a/write_fluffy.c +++ b/write_fluffy.c @@ -7,30 +7,31 @@ #include "type_t.h" #include "adt/error.h" -static FILE *out; +static const context_t *global_context; +static FILE *out; static void write_type(const type_t *type); static const char *get_atomic_type_string(const atomic_type_type_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_BOOL: return "bool"; - default: - panic("unsupported atomic 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"); } } @@ -45,6 +46,64 @@ static void write_pointer_type(const pointer_type_t *type) fputc('*', out); } +static void write_compound_type(const compound_type_t *type) +{ + /* first: search for a matching typedef in the global type... */ + declaration_t *declaration = global_context->declarations; + while(declaration != NULL) { + if(! (declaration->storage_class & STORAGE_CLASS_TYPEDEF)) { + declaration = declaration->next; + continue; + } + if(declaration->type == (type_t*) type) + break; + declaration = declaration->next; + } + + if(declaration != NULL) { + fprintf(out, "%s", declaration->symbol->string); + return; + } + + /* does the struct have a name? */ + if(type->symbol != NULL) { + /* TODO: make sure we create a struct for it... */ + fprintf(out, "%s", type->symbol->string); + return; + } + /* TODO: create a struct and use its name here... */ + fprintf(out, "/* TODO anonymous struct */byte"); +} + +static void write_method_type(const method_type_t *type) +{ + fprintf(out, "(func("); + + method_parameter_type_t *parameter_type = type->parameter_types; + int first = 1; + while(parameter_type != NULL) { + if(!first) { + fprintf(out, ", "); + } else { + first = 0; + } + + if(parameter_type->symbol != NULL) { + fprintf(out, "%s : ", parameter_type->symbol->string); + } else { + /* TODO make up some unused names (or allow _ in fluffy?) */ + fprintf(out, "_ : "); + } + write_type(parameter_type->type); + + parameter_type = parameter_type->next; + } + + fprintf(out, ") : "); + write_type(type->result_type); + fprintf(out, ")"); +} + static void write_type(const type_t *type) { switch(type->type) { @@ -54,6 +113,13 @@ static void write_type(const type_t *type) case TYPE_POINTER: write_pointer_type((const pointer_type_t*) type); return; + case TYPE_COMPOUND_UNION: + case TYPE_COMPOUND_STRUCT: + write_compound_type((const compound_type_t*) type); + return; + case TYPE_METHOD: + write_method_type((const method_type_t*) type); + return; case TYPE_INVALID: panic("invalid type found"); break; @@ -92,6 +158,43 @@ static void write_variable(const declaration_t *declaration) fprintf(out, "\n"); } +static void write_function(const declaration_t *declaration) +{ + if(declaration->statement != NULL) { + fprintf(stderr, "Warning: can't convert function bodies (at %s)\n", + declaration->symbol->string); + } + + fprintf(out, "func extern %s(", + declaration->symbol->string); + + declaration_t *parameter = declaration->context.declarations; + int first = 1; + for( ; parameter != NULL; parameter = parameter->next) { + if(!first) { + fprintf(out, ", "); + } else { + first = 0; + } + if(parameter->symbol != NULL) { + fprintf(out, "%s : ", parameter->symbol->string); + } else { + fputs("_ : ", out); + } + write_type(parameter->type); + } + fprintf(out, ")"); + + const method_type_t *method_type = (const method_type_t*) declaration->type; + const type_t *result_type = method_type->result_type; + if(result_type->type != TYPE_ATOMIC || + ((const atomic_type_t*) result_type)->atype != ATOMIC_TYPE_VOID) { + fprintf(out, " : "); + write_type(result_type); + } + fputc('\n', out); +} + void write_fluffy_decls(const translation_unit_t *unit) { #if 0 @@ -101,7 +204,8 @@ void write_fluffy_decls(const translation_unit_t *unit) exit(1); } #endif - out = stdout; + out = stdout; + global_context = &unit->context; fprintf(out, "/* WARNING: Automatically generated file */\n"); @@ -125,17 +229,28 @@ void write_fluffy_decls(const translation_unit_t *unit) /* write global variables */ declaration = unit->context.declarations; - while(declaration != NULL) { - if(declaration->storage_class & STORAGE_CLASS_TYPEDEF) { - declaration = declaration->next; + for( ; declaration != NULL; declaration = declaration->next) { + if(declaration->storage_class & STORAGE_CLASS_TYPEDEF) continue; - } type_t *type = declaration->type; - if(type->type != TYPE_METHOD) { - write_variable(declaration); - } - declaration = declaration->next; + if(type->type == TYPE_METHOD) + continue; + + write_variable(declaration); + } + + /* write functions */ + declaration = unit->context.declarations; + for( ; declaration != NULL; declaration = declaration->next) { + if(declaration->storage_class & STORAGE_CLASS_TYPEDEF) + continue; + + type_t *type = declaration->type; + if(type->type != TYPE_METHOD) + continue; + + write_function(declaration); } //fclose(out); -- 2.20.1