summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c2
-rw-r--r--test.toc20
-rw-r--r--types.c54
3 files changed, 47 insertions, 29 deletions
diff --git a/main.c b/main.c
index 0c71a21..ac039e9 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index 011b5a3..c6deab2 100644
--- a/test.toc
+++ b/test.toc
@@ -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;
}
}
diff --git a/types.c b/types.c
index 1567c59..b58e040 100644
--- a/types.c
+++ b/types.c
@@ -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;