#include <errno.h>
#include <string.h>
+#include "write_fluffy.h"
#include "ast_t.h"
#include "type_t.h"
+#include "type.h"
#include "adt/error.h"
static const context_t *global_context;
fputc('*', out);
}
-static void write_compound_type(const compound_type_t *type)
+static declaration_t *find_typedef(const 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)) {
+ if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
declaration = declaration->next;
continue;
}
- if(declaration->type == (type_t*) type)
+ if(declaration->type == type)
break;
declaration = declaration->next;
}
+ return declaration;
+}
+
+static void write_compound_type(const compound_type_t *type)
+{
+ declaration_t *declaration = find_typedef((const type_t*) type);
if(declaration != NULL) {
fprintf(out, "%s", declaration->symbol->string);
return;
}
/* does the struct have a name? */
- if(type->symbol != NULL) {
+ symbol_t *symbol = type->declaration->symbol;
+ if(symbol != NULL) {
/* TODO: make sure we create a struct for it... */
- fprintf(out, "%s", type->symbol->string);
+ fprintf(out, "%s", 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)
+static void write_enum_type(const enum_type_t *type)
+{
+ declaration_t *declaration = find_typedef((const type_t*) type);
+ if(declaration != NULL) {
+ fprintf(out, "%s", declaration->symbol->string);
+ return;
+ }
+
+ /* does the enum have a name? */
+ symbol_t *symbol = type->declaration->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(");
- method_parameter_type_t *parameter_type = type->parameter_types;
- int first = 1;
- while(parameter_type != NULL) {
+ function_parameter_t *parameter = type->parameters;
+ int first = 1;
+ while(parameter != NULL) {
if(!first) {
fprintf(out, ", ");
} else {
first = 0;
}
- if(parameter_type->symbol != NULL) {
- fprintf(out, "%s : ", parameter_type->symbol->string);
+#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, "_ : ");
}
- write_type(parameter_type->type);
+#endif
+ fputs("_ : ", out);
+ write_type(parameter->type);
- parameter_type = parameter_type->next;
+ parameter = parameter->next;
}
fprintf(out, ") : ");
- write_type(type->result_type);
+ write_type(type->return_type);
fprintf(out, ")");
}
case TYPE_COMPOUND_STRUCT:
write_compound_type((const compound_type_t*) type);
return;
- case TYPE_METHOD:
- write_method_type((const method_type_t*) type);
+ case TYPE_ENUM:
+ write_enum_type((const enum_type_t*) type);
+ return;
+ case TYPE_FUNCTION:
+ write_function_type((const function_type_t*) type);
return;
case TYPE_INVALID:
panic("invalid type found");
static void write_struct(const symbol_t *symbol, const compound_type_t *type)
{
- (void) type;
fprintf(out, "struct %s:\n", symbol->string);
- const declaration_t *declaration = type->context.declarations;
+ const declaration_t *declaration = type->declaration->context.declarations;
while(declaration != NULL) {
write_struct_entry(declaration);
declaration = declaration->next;
fprintf(out, "\n");
}
+static void write_union(const symbol_t *symbol, const compound_type_t *type)
+{
+ fprintf(out, "union %s:\n", symbol->string);
+
+ const declaration_t *declaration = type->declaration->context.declarations;
+ while(declaration != NULL) {
+ write_struct_entry(declaration);
+ declaration = declaration->next;
+ }
+
+ fprintf(out, "\n");
+}
+
+static void write_expression(const expression_t *expression);
+
+static void write_unary_expression(const unary_expression_t *expression)
+{
+ switch(expression->type) {
+ case UNEXPR_NEGATE:
+ fputc('-', out);
+ break;
+ case UNEXPR_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->type) {
+ case EXPR_CONST:
+ constant = &expression->conste;
+ if(is_type_integer(expression->base.datatype)) {
+ fprintf(out, "%lld", constant->v.int_value);
+ } else {
+ fprintf(out, "%Lf", constant->v.float_value);
+ }
+ break;
+ case EXPR_UNARY:
+ 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);
+
+ declaration_t *entry = type->declaration->next;
+ for ( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
+ entry = entry->next) {
+ fprintf(out, "\t%s", entry->symbol->string);
+ if(entry->init.initializer != NULL) {
+ fprintf(out, " <- ");
+ write_expression(entry->init.enum_value);
+ }
+ fputc('\n', out);
+ }
+ fprintf(out, "typealias %s <- int\n", symbol->string);
+ fprintf(out, "\n");
+}
+
static void write_variable(const declaration_t *declaration)
{
fprintf(out, "var %s : ", declaration->symbol->string);
static void write_function(const declaration_t *declaration)
{
- if(declaration->statement != NULL) {
+ if(declaration->init.statement != NULL) {
fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
declaration->symbol->string);
}
fprintf(out, "func extern %s(",
declaration->symbol->string);
+ const function_type_t *function_type
+ = (const function_type_t*) declaration->type;
+
declaration_t *parameter = declaration->context.declarations;
int first = 1;
for( ; parameter != NULL; parameter = parameter->next) {
}
write_type(parameter->type);
}
+ if(function_type->variadic) {
+ if(!first) {
+ fprintf(out, ", ");
+ } else {
+ first = 0;
+ }
+ fputs("...", out);
+ }
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) {
+ const type_t *return_type = function_type->return_type;
+ if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
fprintf(out, " : ");
- write_type(result_type);
+ write_type(return_type);
}
fputc('\n', out);
}
fprintf(out, "/* WARNING: Automatically generated file */\n");
- /* write structs + enums */
+ /* write structs,unions + enums */
declaration_t *declaration = unit->context.declarations;
- while(declaration != NULL) {
+ for( ; declaration != NULL; declaration = declaration->next) {
//fprintf(out, "// Decl: %s\n", declaration->symbol->string);
- if(! (declaration->storage_class & STORAGE_CLASS_TYPEDEF)) {
- declaration = declaration->next;
+ if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
continue;
}
type_t *type = declaration->type;
if(type->type == TYPE_COMPOUND_STRUCT) {
write_struct(declaration->symbol, (compound_type_t*) type);
} else if(type->type == TYPE_COMPOUND_UNION) {
- /* TODO */
+ write_union(declaration->symbol, (compound_type_t*) type);
+ } else if(type->type == TYPE_ENUM) {
+ write_enum(declaration->symbol, (enum_type_t*) type);
}
-
- declaration = declaration->next;
}
/* write global variables */
declaration = unit->context.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
- if(declaration->storage_class & STORAGE_CLASS_TYPEDEF)
+ if(declaration->namespc != NAMESPACE_NORMAL)
+ continue;
+ if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
+ || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
continue;
type_t *type = declaration->type;
- if(type->type == TYPE_METHOD)
+ if(type->type == TYPE_FUNCTION)
continue;
write_variable(declaration);
/* write functions */
declaration = unit->context.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
- if(declaration->storage_class & STORAGE_CLASS_TYPEDEF)
+ if(declaration->namespc != NAMESPACE_NORMAL)
+ continue;
+ if(declaration->storage_class == STORAGE_CLASS_TYPEDEF
+ || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)
continue;
type_t *type = declaration->type;
- if(type->type != TYPE_METHOD)
+ if(type->type != TYPE_FUNCTION)
continue;
write_function(declaration);