diff options
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 20 | ||||
-rw-r--r-- | types.c | 54 |
3 files changed, 47 insertions, 29 deletions
@@ -17,6 +17,8 @@ do we consistently handle x := &some_array_or_slice; x.len use - use with struct members (e.g. SuperPoint ::= struct { use p: Point; }) compile to a temp file, then move it if compilation succeeds +if you include something twice, it should #define one thing to the other -- it's okay because struct field can't contain __ + -> allow #force'd includes to namespaces &void simplify eval macros with val_to_u/i64 #if should not create a block @@ -1,14 +1,22 @@ -#include "std/io.toc"; +//#include "std/io.toc"; + +#include "std/io.toc", foo; +#include "std/io.toc", bar; c_add ::= fn(x:int, y:int) int { #C("x+y") } main ::= fn() { - xs : [5]int; - for x, i := &xs { - *x = c_add(i*i, i*i*i); + xs : [5]Point; + for use x, i := &xs { + z = c_add(i*i, i*i*i) as f32; + } + for use x := xs { + foo.puti(z as int); } - for x := xs { - puti(x); + Point ::= struct { + x: int; + y: int; + z: f32; } } @@ -757,6 +757,32 @@ static Status add_block_to_struct(Typer *tr, Block *b, StructDef *s, Statement * return true; } +static Status struct_resolve(Typer *tr, StructDef *s) { + if (!(s->flags & STRUCT_DEF_RESOLVED)) { + if (!types_block(tr, &s->body)) + return false; + s->fields = NULL; + Statement *new_stmts = NULL; + if (!add_block_to_struct(tr, &s->body, s, &new_stmts)) + return false; + s->body.stmts = new_stmts; + /* set the field of each declaration, so that we can lookup struct members quickly */ + Field *field = s->fields; + arr_foreach(new_stmts, Statement, stmt) { + assert(stmt->kind == STMT_DECL); + Declaration *decl = stmt->decl; + if (!(decl->flags & DECL_IS_CONST)) { + assert(!(decl->flags & DECL_HAS_EXPR)); + decl->field = field; + field += arr_len(decl->idents); + } + } + s->instance_id = 0; + s->flags |= STRUCT_DEF_RESOLVED; + } + return true; +} + /* fixes the type (replaces [5+3]int with [8]int, etc.) */ static Status type_resolve(Typer *tr, Type *t, Location where) { Evaluator *ev = tr->evalr; @@ -817,28 +843,8 @@ static Status type_resolve(Typer *tr, Type *t, Location where) { break; case TYPE_STRUCT: { StructDef *s = t->struc; - if (!(s->flags & STRUCT_DEF_RESOLVED)) { - if (!types_block(tr, &s->body)) - return false; - s->fields = NULL; - Statement *new_stmts = NULL; - if (!add_block_to_struct(tr, &s->body, s, &new_stmts)) - return false; - s->body.stmts = new_stmts; - /* set the field of each declaration, so that we can lookup struct members quickly */ - Field *field = s->fields; - arr_foreach(new_stmts, Statement, stmt) { - assert(stmt->kind == STMT_DECL); - Declaration *decl = stmt->decl; - if (!(decl->flags & DECL_IS_CONST)) { - assert(!(decl->flags & DECL_HAS_EXPR)); - decl->field = field; - field += arr_len(decl->idents); - } - } - s->instance_id = 0; - s->flags |= STRUCT_DEF_RESOLVED; - } + if (!struct_resolve(tr, s)) + return false; } break; case TYPE_EXPR: { Value typeval; @@ -3126,12 +3132,14 @@ static Status types_expr(Typer *tr, Expression *e) { free(s); return false; } + if (!struct_resolve(tr, struc->struc)) return false; if (!get_struct_constant(struc->struc, rhs->ident_str, e)) return false; break; } else if (struct_type->kind == TYPE_STRUCT) { StructDef *struc = struct_type->struc; - assert(struc->flags & STRUCT_DEF_RESOLVED); + if (!struct_resolve(tr, struc)) return false; + Identifier struct_ident = ident_get_with_len(&struc->body.idents, rhs->ident_str.str, rhs->ident_str.len); if (struct_ident && !(struct_ident->decl->flags & DECL_IS_CONST)) { Field *field = struct_ident->decl->field; |