symbol_table.c \
token.c \
type.c \
- type_hash.c
+ type_hash.c \
+ write_fluffy.c
OBJECTS = $(SOURCES:%.c=build/%.o)
fprintf(out, " %s", declaration->symbol->string);
}
-static
-void print_namespace_entry(FILE *out, const unit_entry_t *entry)
-{
- print_declaration(out, &entry->declaration);
-}
-
void print_ast(FILE *out, const translation_unit_t *unit)
{
- unit_entry_t *entry = unit->entries;
+ declaration_t *declaration = unit->context.declarations;
- while(entry != NULL) {
- print_namespace_entry(out, entry);
+ while(declaration != NULL) {
+ print_declaration(out, declaration);
- entry = entry->next;
+ declaration = declaration->next;
}
}
#include <stdio.h>
+typedef struct context_t context_t;
+
typedef struct expression_t expression_t;
typedef struct const_t const_t;
typedef struct string_literal_t string_literal_t;
typedef struct goto_statement_t goto_statement_t;
typedef struct label_statement_t label_statement_t;
-typedef struct unit_entry_t unit_entry_t;
typedef struct translation_unit_t translation_unit_t;
typedef struct method_parameter_t method_parameter_t;
typedef struct method_t method_t;
EXPR_SIZEOF,
} expresion_type_t;
+struct context_t {
+ declaration_t *declarations;
+};
+
struct expression_t {
expresion_type_t type;
type_t *datatype;
};
struct reference_expression_t {
- expression_t expression;
- symbol_t *symbol;
- declaration_t *declaration;
+ expression_t expression;
+ symbol_t *symbol;
+ declaration_t *declaration;
};
struct call_argument_t {
};
struct select_expression_t {
- expression_t expression;
- expression_t *compound;
- symbol_t *symbol;
+ expression_t expression;
+ expression_t *compound;
+ symbol_t *symbol;
- compound_entry_t *compound_entry;
+ declaration_t *compound_entry;
};
struct array_access_expression_t {
method_parameter_t *parameters;
statement_t *statement;
source_position_t source_position;
+ context_t context;
+
+ declaration_t *next;
};
typedef enum {
struct compound_statement_t {
statement_t statement;
statement_t *first_statement;
+ context_t context;
};
struct declaration_statement_t {
expression_t *expression;
};
-struct unit_entry_t {
- declaration_t declaration;
- unit_entry_t *next;
-};
-
struct translation_unit_t {
- unit_entry_t *entries;
+ context_t context;
};
static inline
#endif
static
-void compile(const char *fname)
+translation_unit_t *compile(const char *fname)
{
FILE *in = fopen(fname, "r");
if(in == NULL) {
lexer_open_stream(in, fname);
- parse();
+ translation_unit_t *unit = parse();
fclose(in);
+
+ return unit;
}
static
fclose(in);
}
+void write_fluffy_decls(translation_unit_t *unit);
+
int main(int argc, char **argv)
{
init_symbol_table();
}
for(int i = 1; i < argc; ++i) {
- compile(argv[i]);
+ translation_unit_t *unit = compile(argv[i]);
+ write_fluffy_decls(unit);
}
exit_parser();
#include "adt/error.h"
#include "adt/array.h"
-#define PRINT_TOKENS
+//#define PRINT_TOKENS
#define MAX_LOOKAHEAD 2
struct environment_entry_t {
static int lookahead_bufpos;
static struct obstack environment_obstack;
static environment_entry_t **environment_stack = NULL;
-static translation_unit_t *translation_unit = NULL;
-static const void *context = NULL;
+static context_t *context = NULL;
+static declaration_t *last_declaration = NULL;
static
statement_t *parse_compound_statement(void);
} \
next_token();
+static void set_context(context_t *new_context)
+{
+ context = new_context;
+
+ declaration_t *declaration = new_context->declarations;
+ if(declaration != NULL) {
+ while(1) {
+ if(declaration->next == NULL)
+ break;
+ declaration = declaration->next;
+ }
+ }
+
+ last_declaration = declaration;
+}
/**
* pushs an environment_entry on the environment stack and links the
}
}
- fprintf(stderr, "Set '%s' to %p\n", symbol->string, (void*) declaration);
-
entry->old_declaration = symbol->declaration;
entry->old_context = symbol->context;
entry->symbol = symbol;
return parse_expression();
}
-static compound_entry_t *parse_compound_type_entries(void);
+static void parse_compound_type_entries(void);
static void parse_declarator(declaration_t *declaration,
storage_class_t storage_class, type_t *type);
static void maybe_push_declaration(declaration_t *declaration);
+static void record_declaration(declaration_t *declaration);
typedef struct declaration_specifiers_t declaration_specifiers_t;
struct declaration_specifiers_t {
struct_type->type.type = TYPE_COMPOUND_STRUCT;
struct_type->source_position = token.source_position;
- fprintf(stderr, "New struct %p\n", (void*) struct_type);
-
int top = environment_top();
- const void *last_context = context;
- context = struct_type;
+ context_t *last_context = context;
+ set_context(&struct_type->context);
if(token.type == T_IDENTIFIER) {
next_token();
if(token.type == '{') {
parse_compound_type_entries();
}
- fprintf(stderr, "Finished struct %p\n",(void*) struct_type);
} else if(token.type == '{') {
parse_compound_type_entries();
- fprintf(stderr, "Finished struct %p\n", (void*) struct_type);
} else {
parse_error_expected("problem while parsing struct type specifiers",
T_IDENTIFIER, '{', 0);
struct_type = NULL;
}
- assert(context == struct_type);
- context = last_context;
+ assert(context == &struct_type->context);
+ set_context(last_context);
environment_pop_to(top);
return (type_t*) struct_type;
union_type->source_position = token.source_position;
int top = environment_top();
- const void *last_context = context;
- context = union_type;
+ context_t *last_context = context;
+ set_context(&union_type->context);
if(token.type == T_IDENTIFIER) {
union_type->symbol = token.v.symbol;
union_type = NULL;
}
- assert(context == union_type);
- context = last_context;
+ assert(context == &union_type->context);
+ set_context(last_context);
environment_pop_to(top);
return (type_t*) union_type;
}
specifiers->type = result;
-
- fprintf(stderr, "Specifiers type: ");
- print_type(stderr, result);
- fprintf(stderr, "\n");
}
static
parse_declarator(declaration, specifiers.storage_class,
specifiers.type);
maybe_push_declaration(declaration);
+ record_declaration(declaration);
}
}
{
while(token.type == T___attribute__) {
next_token();
- fprintf(stderr, "TODO: __attribute__ not handled yet\n");
expect_void('(');
int depth = 1;
next_token();
int top = environment_top();
- const void *last_context = context;
- context = NULL;
+ context_t *last_context = context;
+ set_context(&declaration->context);
parse_parameters();
- assert(context == NULL);
- context = last_context;
+ assert(context == &declaration->context);
+ set_context(last_context);
environment_pop_to(top);
expect_void(')');
parse_attributes();
}
+static void record_declaration(declaration_t *declaration)
+{
+ if(last_declaration != NULL) {
+ last_declaration->next = declaration;
+ } else {
+ if(context != NULL)
+ context->declarations = declaration;
+ }
+ last_declaration = declaration;
+}
+
static
void maybe_push_declaration(declaration_t *declaration)
{
- fprintf(stderr, "Declarator '%s' type: ",
- declaration->symbol ? declaration->symbol->string : "");
- print_type(stderr, declaration->type);
- fprintf(stderr, "\n");
-
symbol_t *symbol = declaration->symbol;
if(symbol != NULL) {
parse_declarator(declaration, specifiers->storage_class,
specifiers->type);
maybe_push_declaration(declaration);
+ record_declaration(declaration);
if(token.type == '=') {
next_token();
if(token.type == '{') {
void parse_struct_declarators(const declaration_specifiers_t *specifiers)
{
while(1) {
- declaration_t *declaration = allocate_ast_zero(sizeof(declaration[0]));
-
- compound_entry_t *entry = allocate_ast_zero(sizeof(entry[0]));
- entry->declaration = declaration;
-
if(token.type == ':') {
next_token();
parse_constant_expression();
- /* TODO */
+ /* TODO (bitfields) */
} else {
+ declaration_t *declaration
+ = allocate_ast_zero(sizeof(declaration[0]));
parse_declarator(declaration, specifiers->storage_class,
specifiers->type);
maybe_push_declaration(declaration);
+ record_declaration(declaration);
if(token.type == ':') {
next_token();
parse_constant_expression();
- /* TODO */
+ /* TODO (bitfields) */
}
}
expect_void(';');
}
-static compound_entry_t *parse_compound_type_entries(void)
+static void parse_compound_type_entries(void)
{
eat('{');
- compound_entry_t *entries = NULL;
-
while(token.type != '}' && token.type != T_EOF) {
declaration_specifiers_t specifiers;
memset(&specifiers, 0, sizeof(specifiers));
parse_struct_declarators(&specifiers);
}
+ if(token.type == T_EOF) {
+ parse_error("unexpected error while parsing struct");
+ }
next_token();
-
- return entries;
}
void parse_declaration(void)
= allocate_ast_zero(sizeof(compound_statement[0]));
compound_statement->statement.type = STATEMENT_COMPOUND;
- int top = environment_top();
- const void *last_context = context;
- context = compound_statement;
+ int top = environment_top();
+ context_t *last_context = context;
+ set_context(&compound_statement->context);
while(token.type != '}') {
parse_statement();
}
- assert(context == compound_statement);
- context = last_context;
+ assert(context == &compound_statement->context);
+ set_context(last_context);
environment_pop_to(top);
next_token();
{
translation_unit_t *unit = allocate_ast_zero(sizeof(unit[0]));
- assert(translation_unit == NULL);
assert(context == NULL);
- translation_unit = unit;
+ set_context(&unit->context);
while(token.type != T_EOF) {
parse_declaration();
}
- translation_unit = NULL;
+ assert(context == &unit->context);
+ context = NULL;
+ last_declaration = NULL;
+
return unit;
}
typedef struct pointer_type_t pointer_type_t;
typedef struct method_parameter_type_t method_parameter_type_t;
typedef struct method_type_t method_type_t;
-typedef struct compound_entry_t compound_entry_t;
typedef struct compound_type_t compound_type_t;
typedef struct enum_type_t enum_type_t;
typedef struct builtin_type_t builtin_type_t;
if(type1->symbol != type2->symbol)
return 0;
-#if 0
- struct_entry_t *entry1 = type1->entries;
- struct_entry_t *entry2 = type2->entries;
+ declaration_t *entry1 = type1->context.declarations;
+ declaration_t *entry2 = type2->context.declarations;
while(entry1 != NULL && entry2 != NULL) {
if(entry1->type != entry2->type)
return 0;
+ if(entry1->symbol != entry2->symbol)
+ return 0;
entry1 = entry1->next;
entry2 = entry2->next;
}
if(entry1 != NULL || entry2 != NULL)
return 0;
-#endif
return 1;
}
#include "type.h"
#include "symbol.h"
#include "token_t.h"
+#include "ast_t.h"
#include "adt/obst.h"
struct obstack *type_obst;
const char *abi_style;
};
-struct compound_entry_t {
- declaration_t *declaration;
- compound_entry_t *next;
- source_position_t source_position;
-};
-
struct compound_type_t {
type_t type;
- compound_entry_t *entries;
symbol_t *symbol;
+ context_t context;
source_position_t source_position;
};
--- /dev/null
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "ast_t.h"
+#include "type_t.h"
+#include "adt/error.h"
+
+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");
+ }
+}
+
+static void write_atomic_type(const atomic_type_t *type)
+{
+ fprintf(out, "%s", get_atomic_type_string(type->atype));
+}
+
+static void write_pointer_type(const pointer_type_t *type)
+{
+ write_type(type->points_to);
+ fputc('*', out);
+}
+
+static void write_type(const type_t *type)
+{
+ switch(type->type) {
+ case TYPE_ATOMIC:
+ write_atomic_type((const atomic_type_t*) type);
+ return;
+ case TYPE_POINTER:
+ write_pointer_type((const pointer_type_t*) type);
+ return;
+ case TYPE_INVALID:
+ panic("invalid type found");
+ break;
+ default:
+ fprintf(out, "/* TODO type */");
+ break;
+ }
+}
+
+static void write_struct_entry(const declaration_t *declaration)
+{
+ fprintf(out, "\t%s : ", declaration->symbol->string);
+ write_type(declaration->type);
+ fprintf(out, "\n");
+}
+
+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;
+ while(declaration != NULL) {
+ write_struct_entry(declaration);
+ declaration = declaration->next;
+ }
+
+ fprintf(out, "\n");
+}
+
+static void write_variable(const declaration_t *declaration)
+{
+ fprintf(out, "var %s : ", declaration->symbol->string);
+ write_type(declaration->type);
+ /* TODO: initializers */
+ fprintf(out, "\n");
+}
+
+void write_fluffy_decls(const translation_unit_t *unit)
+{
+#if 0
+ out = fopen("out.fluffy", "w");
+ if(out == NULL) {
+ fprintf(stderr, "Couldn't open out.fluffy: %s\n", strerror(errno));
+ exit(1);
+ }
+#endif
+ out = stdout;
+
+ fprintf(out, "/* WARNING: Automatically generated file */\n");
+
+ /* write structs + enums */
+ declaration_t *declaration = unit->context.declarations;
+ while(declaration != NULL) {
+ //fprintf(out, "// Decl: %s\n", declaration->symbol->string);
+ if(! (declaration->storage_class & STORAGE_CLASS_TYPEDEF)) {
+ declaration = declaration->next;
+ 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 */
+ }
+
+ declaration = declaration->next;
+ }
+
+ /* write global variables */
+ declaration = unit->context.declarations;
+ while(declaration != NULL) {
+ if(declaration->storage_class & STORAGE_CLASS_TYPEDEF) {
+ declaration = declaration->next;
+ continue;
+ }
+
+ type_t *type = declaration->type;
+ if(type->type != TYPE_METHOD) {
+ write_variable(declaration);
+ }
+ declaration = declaration->next;
+ }
+
+ //fclose(out);
+}