summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-03 19:33:48 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-03 19:33:48 -0500
commitdb354b0994e4606d8f27e17dc24dbc81f0113c7a (patch)
treeebc727cf2298ecd13052f000ad0fb49cc0aa5cf1
parent7a135cb2d258fee49880d3dd9f5f43096bd73331 (diff)
started to get user-defined types to work with pointers to future types
-rw-r--r--cgen.c22
-rw-r--r--main.c1
-rw-r--r--test.toc14
-rw-r--r--typedefs_cgen.c35
-rw-r--r--types.c1
-rw-r--r--types.h3
6 files changed, 62 insertions, 14 deletions
diff --git a/cgen.c b/cgen.c
index 39a56c3..66ebdc9 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
diff --git a/main.c b/main.c
index b16ca4a..436bcd4 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index e7808fe..acffe96 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
}
diff --git a/types.c b/types.c
index 4b86e34..7756585 100644
--- a/types.c
+++ b/types.c
@@ -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;
diff --git a/types.h b/types.h
index 2ddd648..0313691 100644
--- a/types.h
+++ b/types.h
@@ -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 {