diff options
-rw-r--r-- | cgen.c | 4 | ||||
-rw-r--r-- | eval.c | 12 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 16 | ||||
-rw-r--r-- | test.toc | 10 | ||||
-rw-r--r-- | types.c | 6 |
6 files changed, 37 insertions, 13 deletions
@@ -158,9 +158,7 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); #define cgen_recurse_subtypes(f, g, type, extra) \ switch (type->kind) { \ case TYPE_STRUCT: \ - arr_foreach(type->struc->fields, Field, fl) \ - if (!f(g, fl->type, extra)) \ - return false; \ + /* don't descend into fields */ \ break; \ case TYPE_FN: \ arr_foreach(type->fn.types, Type, sub) { \ @@ -1320,8 +1320,16 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Declaration *d = NULL; if (is_decl) { d = idecl->decl; - if (!types_decl(ev->typer, d)) return false; - assert(d->type.flags & TYPE_IS_RESOLVED); + if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval.kind == TYPE_STRUCT) { + v->type = allocr_malloc(ev->allocr, sizeof *v->type); + v->type->flags = TYPE_IS_RESOLVED; + v->type->kind = TYPE_STRUCT; + v->type->struc = d->expr.typeval.struc; + break; + } else { + if (!types_decl(ev->typer, d)) return false; + assert(d->type.flags & TYPE_IS_RESOLVED); + } } if (idecl->flags & IDECL_HAS_VAL) { *v = idecl->val; @@ -18,6 +18,8 @@ /* TODO: +check for problematic circular dependencies +test really long type names packages --- X ::= newtype(int); or something @@ -228,13 +228,15 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { return written; } case TYPE_STRUCT: { - size_t written = str_copy(buffer, bufsize, "struct { "); - arr_foreach(t->struc->fields, Field, f) { - written += type_to_str_(f->type, buffer + written, bufsize - written); - written += str_copy(buffer + written, bufsize - written, "; "); - } - written += str_copy(buffer + written, bufsize - written, " }"); - return written; + /* size_t written = str_copy(buffer, bufsize, "struct { "); */ + /* arr_foreach(t->struc->fields, Field, f) { */ + /* written += type_to_str_(f->type, buffer + written, bufsize - written); */ + /* written += str_copy(buffer + written, bufsize - written, "; "); */ + /* } */ + /* written += str_copy(buffer + written, bufsize - written, " }"); */ + /* TODO: show name or something (to allow circular dependencies)? */ + return str_copy(buffer, bufsize, "struct { ... }"); + } case TYPE_ARR: { size_t written = str_copy(buffer, bufsize, "["); @@ -6,7 +6,15 @@ putf ::= fn(x: float) { #C("printf(\"%f\\n\", (double)x); "); }; -point ::= pkg "point"; +// point ::= pkg "point"; + +Foo ::= struct { + b: &Bar; +}; + +Bar ::= struct { + f: &Foo; +}; main ::= fn() { f::=fn(t::Type)Type {t}; @@ -441,6 +441,12 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { /* allow using a function before declaring it */ if (!type_of_fn(tr, d->expr.fn, t, 0)) return false; return true; + } else if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_TYPE)) { + /* allow using a type before declaring it */ + t->kind = TYPE_BUILTIN; + t->builtin = BUILTIN_TYPE; + t->flags = TYPE_IS_RESOLVED; + return true; } else { if (where.start <= d->where.end) { char *s = ident_to_str(i); |