summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decls_cgen.c41
-rw-r--r--test.toc3
-rw-r--r--typedefs_cgen.c24
-rw-r--r--types.h7
4 files changed, 39 insertions, 36 deletions
diff --git a/decls_cgen.c b/decls_cgen.c
index 40087f5..7fcb106 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -79,31 +79,34 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) {
} else if (d->flags & DECL_HAS_EXPR) {
if (d->flags & DECL_IS_CONST) {
for (size_t idx = 0; idx < arr_len(d->idents); idx++) {
- Identifier i = d->idents[idx];
Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type;
if (type->kind == TYPE_TYPE) {
Value *val = d->type.kind == TYPE_TUPLE ? &d->val.tuple[idx] : &d->val;
if (val->type->kind == TYPE_STRUCT) {
- /* generate struct definition */
- cgen_write(g, "struct ");
- if (g->block == NULL)
- cgen_ident(g, i);
- else
- cgen_ident_id(g, d->c.ids[idx]);
- cgen_write(g, "{");
- cgen_nl(g);
- g->indent_lvl++;
- arr_foreach(val->type->struc->fields, Field, f) {
- if (!cgen_type_pre(g, f->type, d->where)) return false;
- cgen_write(g, " ");
- cgen_ident(g, f->name);
- if (!cgen_type_post(g, f->type, d->where)) return false;
- cgen_write(g, ";");
+ StructDef *sdef = val->type->struc;
+ if (!(sdef->flags & STRUCT_DEF_CGENERATED)) {
+ /* generate struct definition */
+ cgen_write(g, "struct ");
+ if (sdef->c.name)
+ cgen_ident(g, sdef->c.name);
+ else
+ cgen_ident_id(g, sdef->c.id);
+ cgen_write(g, "{");
cgen_nl(g);
+ g->indent_lvl++;
+ arr_foreach(sdef->fields, Field, f) {
+ if (!cgen_type_pre(g, f->type, d->where)) return false;
+ cgen_write(g, " ");
+ cgen_ident(g, f->name);
+ if (!cgen_type_post(g, f->type, d->where)) return false;
+ cgen_write(g, ";");
+ cgen_nl(g);
+ }
+ g->indent_lvl--;
+ cgen_write(g, "};");
+ cgen_nl(g);
+ sdef->flags |= STRUCT_DEF_CGENERATED;
}
- g->indent_lvl--;
- cgen_write(g, "};");
- cgen_nl(g);
}
}
}
diff --git a/test.toc b/test.toc
index 0ee769f..5fc72d4 100644
--- a/test.toc
+++ b/test.toc
@@ -21,7 +21,8 @@ t @= struct {
A: int;
b: int;
};
+u @= t;
x : t;
- y := x;
+ y : u = x;
}; \ No newline at end of file
diff --git a/typedefs_cgen.c b/typedefs_cgen.c
index 71b1c5f..0feee25 100644
--- a/typedefs_cgen.c
+++ b/typedefs_cgen.c
@@ -23,7 +23,6 @@ static bool typedefs_expr(CGenerator *g, Expression *e) {
}
static bool typedefs_decl(CGenerator *g, Declaration *d) {
- d->c.ids = NULL;
if (cgen_fn_is_direct(g, d)) {
d->expr.fn.c.name = d->idents[0];
}
@@ -32,23 +31,26 @@ static bool typedefs_decl(CGenerator *g, Declaration *d) {
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 = allocr_calloc(g->allocr, arr_len(d->idents), sizeof *d->c.ids);
/* generate typedef */
IdentID id = 0;
if (g->block != NULL || g->fn != NULL)
- id = d->c.ids[idx] = g->ident_counter++;
+ id = g->ident_counter++;
if (val->type->kind == TYPE_STRUCT) {
/* we'll actually define the struct later; here we can just declare it */
- cgen_write(g, "struct ");
- if (id) {
- cgen_ident_id(g, id);
- val->type->struc->c.id = id;
+ StructDef *sdef = val->type->struc;
+ if (sdef->c.id || sdef->c.name) {
+ /* we've already done this */
} else {
- cgen_ident(g, i);
- val->type->struc->c.name = i;
+ cgen_write(g, "struct ");
+ if (id) {
+ cgen_ident_id(g, id);
+ sdef->c.id = id;
+ } else {
+ cgen_ident(g, i);
+ sdef->c.name = i;
+ }
+ cgen_write(g, ";");
}
- cgen_write(g, ";");
} else {
cgen_write(g, "typedef ");
if (!cgen_type_pre(g, val->type, d->where)) return false;
diff --git a/types.h b/types.h
index 3d17f0a..c855702 100644
--- a/types.h
+++ b/types.h
@@ -336,7 +336,8 @@ typedef struct FnType {
} FnType;
enum {
- STRUCT_DEF_FOUND_OFFSETS = 0x00,
+ STRUCT_DEF_FOUND_OFFSETS = 0x01,
+ STRUCT_DEF_CGENERATED = 0x02,
};
typedef struct {
@@ -640,10 +641,6 @@ typedef struct Declaration {
DeclFlags flags;
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 {