summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-03 20:01:48 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-03 20:01:48 -0500
commit376fe21bba246b0bdbd90b9a4101e15c5411b505 (patch)
tree975c6ff240cebc0431530af602bdefc6e92bf1c4
parentdb354b0994e4606d8f27e17dc24dbc81f0113c7a (diff)
got pointers to future types to work
-rw-r--r--cgen.c23
-rw-r--r--main.c1
-rw-r--r--test.toc16
-rw-r--r--typedefs_cgen.c14
4 files changed, 39 insertions, 15 deletions
diff --git a/cgen.c b/cgen.c
index 66ebdc9..cea6bfa 100644
--- a/cgen.c
+++ b/cgen.c
@@ -1268,7 +1268,28 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
Type *type = is_tuple ? &d->type.tuple[idx] : &d->type;
Value *val = is_tuple ? &d->val.tuple[idx] : &d->val;
if (type->kind == TYPE_TYPE) {
- /* handled in decls_cgen */
+ /* mostly handled in typedefs_cgen, except for struct declarations */
+ if (val->type->kind == TYPE_STRUCT) {
+ 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, ";");
+ cgen_nl(g);
+ }
+ g->indent_lvl--;
+ cgen_write(g, "};");
+ cgen_nl(g);
+ }
continue;
}
if (!cgen_val_pre(g, val, type, d->where))
diff --git a/main.c b/main.c
index 436bcd4..671a4e3 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,5 @@
/*
TODO:
-pointers to futurely-declared types (or to this type)
make sure futurely/currently-declared types are *only* used by pointer
for
+=, -=, *=, /=
diff --git a/test.toc b/test.toc
index acffe96..00cd372 100644
--- a/test.toc
+++ b/test.toc
@@ -32,7 +32,21 @@ Bar @= struct {
main @= fn() {
f: Foo;
-
+ b: Bar;
+ f.x = &b;
+ b.y = &f;
+
+ Baz @= struct { a : &Quux; };
+ Quux @= struct { b: &Baz; };
+ B : Baz;
+ q : Quux;
+ B.a = &q;
+ q.b = &B;
+
+ Wow @= struct { w: &Wow; };
+ w: Wow;
+ w.w = &w;
+
puti(total());
X @= total();
puti(X);
diff --git a/typedefs_cgen.c b/typedefs_cgen.c
index f652ca1..2051acb 100644
--- a/typedefs_cgen.c
+++ b/typedefs_cgen.c
@@ -104,19 +104,9 @@ static bool typedefs_decl(CGenerator *g, Declaration *d) {
/* generate typedef */
IdentID id;
if (g->block != NULL) id = d->c.ids[idx] = g->ident_counter++;
+ if (val->type->kind == TYPE_STRUCT) continue; /* we don't need to typedef this; we can just use its tag */
cgen_write(g, "typedef ");
- 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;
- }
+ if (!cgen_type_pre(g, val->type, d->where)) return false;
cgen_write(g, " ");
if (g->block == NULL) {
/* we can refer to this by its name */