diff options
-rw-r--r-- | cgen.c | 22 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | typedefs_cgen.c | 35 | ||||
-rw-r--r-- | types.c | 1 | ||||
-rw-r--r-- | types.h | 3 |
6 files changed, 62 insertions, 14 deletions
@@ -131,8 +131,8 @@ static inline void cgen_ident_id_to_str(char *buffer, IdentID id) { snprintf(buffer, 32, "a%lu_", (unsigned long)id); } -static bool cgen_type_post(CGenerator *g, Type *t, Location where); static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { + assert(t->flags & TYPE_FLAG_RESOLVED); switch (t->kind) { case TYPE_BUILTIN: switch (t->builtin) { @@ -196,8 +196,24 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { assert(0); return false; case TYPE_USER: { - Identifier i = t->user.decl->idents[t->user.index]; - cgen_ident(g, i); + Type *this = t; + do { + Type *next = type_user_underlying(this); + if (next->kind == TYPE_STRUCT) { + /* use struct tag */ + cgen_write(g, "struct "); + t = this; + break; + } + this = next; + } while (this->kind == TYPE_USER); + + Declaration *d = t->user.decl; + int idx = t->user.index; + if (d->c.ids[idx]) + cgen_ident_id(g, d->c.ids[idx]); + else + cgen_ident(g, d->idents[idx]); } break; } return true; @@ -1,6 +1,7 @@ /* TODO: pointers to futurely-declared types (or to this type) +make sure futurely/currently-declared types are *only* used by pointer for +=, -=, *=, /= compile-time arguments @@ -21,17 +21,17 @@ total @= fn() int { t }; -// Foo @= struct { -// x: &Bar; -// }; +Foo @= struct { + x: &Bar; +}; -// Bar @= struct { -// y : &Foo; -// }; +Bar @= struct { + y : &Foo; +}; main @= fn() { - // f: Foo; + f: Foo; puti(total()); X @= total(); diff --git a/typedefs_cgen.c b/typedefs_cgen.c index 8228a24..f652ca1 100644 --- a/typedefs_cgen.c +++ b/typedefs_cgen.c @@ -72,11 +72,14 @@ static bool typedefs_expr(CGenerator *g, Expression *e) { return false; fn_exit(&e->fn); break; + case EXPR_NEW: + if (e->new.n && !typedefs_expr(g, e->new.n)) + return false; + break; case EXPR_TYPE: case EXPR_C: case EXPR_DSIZEOF: case EXPR_DALIGNOF: - case EXPR_NEW: case EXPR_IDENT: case EXPR_LITERAL_BOOL: case EXPR_LITERAL_INT: @@ -90,17 +93,41 @@ static bool typedefs_expr(CGenerator *g, Expression *e) { } static bool typedefs_decl(CGenerator *g, Declaration *d) { + d->c.ids = NULL; for (int idx = 0; idx < (int)arr_len(d->idents); idx++) { Identifier i = d->idents[idx]; Type *type = decl_type_at_index(d, idx); Value *val = decl_val_at_index(d, idx); if (type->kind == TYPE_TYPE) { + if (d->c.ids == NULL) + d->c.ids = calloc(arr_len(d->idents), sizeof *d->c.ids); /* generate typedef */ + IdentID id; + if (g->block != NULL) id = d->c.ids[idx] = g->ident_counter++; cgen_write(g, "typedef "); - if (!cgen_type_pre(g, val->type, d->where)) return false; + if (val->type->kind == TYPE_STRUCT) { + cgen_write(g, "struct "); + if (g->block == NULL) { + /* we can refer to this by its name */ + cgen_ident(g, i); + } else { + /* we need to use an ID ): */ + cgen_ident_id(g, id); + } + } else { + if (!cgen_type_pre(g, val->type, d->where)) return false; + } cgen_write(g, " "); - cgen_ident(g, i); - if (!cgen_type_post(g, val->type, d->where)) return false; + if (g->block == NULL) { + /* we can refer to this by its name */ + cgen_ident(g, i); + } else { + /* we need to use an ID ): */ + cgen_ident_id(g, id); + } + if (val->type->kind != TYPE_STRUCT) { + if (!cgen_type_post(g, val->type, d->where)) return false; + } cgen_write(g, ";"); cgen_nl(g); } @@ -1334,6 +1334,7 @@ static bool types_decl(Typer *tr, Declaration *d) { success = false; goto ret; } + if (!type_resolve(tr, val->type, d->where)) return false; if (val->type->kind == TYPE_TUPLE) { err_print(d->where, "You can't declare a new type to be a tuple."); success = false; @@ -513,6 +513,9 @@ typedef struct Declaration { Expression expr; Value val; /* only for constant decls. */ + struct { + IdentID *ids; /* array of IDs used in place of ident names. unfortunately needed for user defined types. this is NOT a dynamic array, but is of length arr_len(idents). */ + } c; } Declaration; typedef enum { |