summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c58
-rw-r--r--main.c2
-rw-r--r--parse.c5
-rw-r--r--test.toc11
-rw-r--r--typedefs_cgen.c6
-rw-r--r--types.c5
6 files changed, 50 insertions, 37 deletions
diff --git a/eval.c b/eval.c
index bccc7c2..e4b6676 100644
--- a/eval.c
+++ b/eval.c
@@ -731,7 +731,6 @@ static bool eval_address_of(Evaluator *ev, Expression *e, void **ptr) {
return true;
}
-
static bool eval_set(Evaluator *ev, Expression *set, Value *to) {
switch (set->kind) {
case EXPR_IDENT: {
@@ -953,7 +952,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
if (!eval_expr(ev, lhs_expr, &lhs)) return false;
if (e->binary.op != BINARY_DOT)
if (!eval_expr(ev, rhs_expr, &rhs)) return false;
-
BuiltinType builtin = e->binary.lhs->type.builtin;
switch (e->binary.op) {
case BINARY_DOT: {
@@ -1038,7 +1036,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
while (1) {
if (w->cond) {
if (!eval_expr(ev, w->cond, &cond)) return false;
- if (!val_truthiness(&cond, &w->cond->type))
+ Type *cond_type = &w->cond->type;
+ if (!val_truthiness(&cond, cond_type))
break;
}
if (!eval_block(ev, &w->body, &e->type, v)) return false;
@@ -1069,6 +1068,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
IdentDecl *idecl = ident_decl(e->ident);
Declaration *d = idecl->decl;
if (!types_decl(ev->typer, d)) return false;
+ assert(d->type.flags & TYPE_FLAG_RESOLVED);
if (idecl->flags & IDECL_FLAG_HAS_VAL) {
*v = idecl->val;
} else if (d->flags & DECL_FLAG_CONST) {
@@ -1087,7 +1087,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
v->type->user.decl = d;
v->type->user.index = index;
} else {
- *v = d->type.kind == TYPE_TUPLE ? d->val.tuple[index] : d->val;
+ *v = *decl_val_at_index(d, index);
}
} else {
char *s = ident_to_str(e->ident);
@@ -1232,42 +1232,46 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
static bool eval_decl(Evaluator *ev, Declaration *d) {
- Value val = {0};
int has_expr = d->flags & DECL_FLAG_HAS_EXPR;
+ int is_const = d->flags & DECL_FLAG_CONST;
+ Value val = {0};
+
if (has_expr) {
- if (d->flags & DECL_FLAG_CONST) {
+ if (is_const) {
if (!(d->flags & DECL_FLAG_FOUND_VAL)) {
if (!eval_expr(ev, &d->expr, &d->val))
return false;
d->flags |= DECL_FLAG_FOUND_VAL;
}
- val = d->val;
} else {
+ /* TODO: tuples allocated here will never be freed! */
if (!eval_expr(ev, &d->expr, &val))
return false;
}
}
- long index = 0;
- arr_foreach(d->idents, Identifier, i) {
- IdentDecl *id = ident_decl(*i);
- Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[index] : &d->type;
- Value *thisval = NULL;
- if (has_expr)
- thisval = d->type.kind == TYPE_TUPLE ? &val.tuple[index] : &val;
- Type *inner = type_inner(type);
- if (inner->kind == TYPE_STRUCT) {
- id->val.struc = err_calloc(1, compiler_sizeof(inner));
- } else if (inner->kind == TYPE_ARR) {
- id->val.arr = err_calloc(inner->arr.n, compiler_sizeof(inner->arr.of));
+
+ if (!is_const) {
+ int index = 0;
+ arr_foreach(d->idents, Identifier, i) {
+ IdentDecl *id = ident_decl(*i);
+ Type *type = decl_type_at_index(d, index);
+ Type *inner = type_inner(type);
+ if (!is_const) {
+ if (has_expr) {
+ val_copy(NULL, &id->val, &val, type);
+ } else {
+ if (inner->kind == TYPE_STRUCT) {
+ id->val.struc = err_calloc(1, compiler_sizeof(inner));
+ } else if (inner->kind == TYPE_ARR) {
+ id->val.arr = err_calloc(inner->arr.n, compiler_sizeof(inner->arr.of));
+ } else {
+ id->val = val; /* = (Value)({0}) */
+ }
+ }
+ }
+ index++;
+ id->flags |= IDECL_FLAG_HAS_VAL;
}
-
- if (has_expr)
- val_copy(d->flags & DECL_FLAG_CONST ? ev : NULL, &id->val, thisval, type);
- index++;
- id->flags |= IDECL_FLAG_HAS_VAL;
- }
- if (has_expr && d->expr.kind == EXPR_TUPLE) {
- val_free(&val, &d->type); /* free the tuple */
}
return true;
}
diff --git a/main.c b/main.c
index cbd93b8..b16ca4a 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
/*
TODO:
-pointers to futurely-declared types
+pointers to futurely-declared types (or to this type)
for
+=, -=, *=, /=
compile-time arguments
diff --git a/parse.c b/parse.c
index 5dc9601..ce01ba6 100644
--- a/parse.c
+++ b/parse.c
@@ -893,7 +893,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
if (parser_is_definitely_type(p, NULL)) {
/* it's a type! */
e->kind = EXPR_TYPE;
- return parse_type(p, &e->typeval);
+ if (!parse_type(p, &e->typeval))
+ return false;
+ if (t->token == end) return true;
+ /* there's more stuff after. maybe it's, e.g. int, float */
}
t->token = before;
diff --git a/test.toc b/test.toc
index c54be5f..e7808fe 100644
--- a/test.toc
+++ b/test.toc
@@ -21,12 +21,21 @@ total @= fn() int {
t
};
+// Foo @= struct {
+// x: &Bar;
+// };
+
+// Bar @= struct {
+// y : &Foo;
+// };
+
main @= fn() {
+ // f: Foo;
+
puti(total());
X @= total();
puti(X);
puti(#sizeof(int));
puti(#alignof(int));
- puti(#sizeof({ Foo, Bar @= int, struct { x: i64; y: char; } ; f: Foo; f }));
};
diff --git a/typedefs_cgen.c b/typedefs_cgen.c
index 58b9767..8228a24 100644
--- a/typedefs_cgen.c
+++ b/typedefs_cgen.c
@@ -90,10 +90,10 @@ static bool typedefs_expr(CGenerator *g, Expression *e) {
}
static bool typedefs_decl(CGenerator *g, Declaration *d) {
- for (size_t idx = 0; idx < arr_len(d->idents); idx++) {
+ for (int idx = 0; idx < (int)arr_len(d->idents); idx++) {
Identifier i = d->idents[idx];
- Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type;
- Value *val = d->type.kind == TYPE_TUPLE ? &d->val.tuple[idx] : &d->val;
+ Type *type = decl_type_at_index(d, idx);
+ Value *val = decl_val_at_index(d, idx);
if (type->kind == TYPE_TYPE) {
/* generate typedef */
cgen_write(g, "typedef ");
diff --git a/types.c b/types.c
index b831f05..4b86e34 100644
--- a/types.c
+++ b/types.c
@@ -379,6 +379,7 @@ static bool type_resolve(Typer *tr, Type *t, Location where) {
return false;
break;
case TYPE_USER: {
+ t->flags |= TYPE_FLAG_RESOLVED; /* pre-resolve type to avoid infinite recursion */
/* find declaration */
Identifier ident = t->user.ident;
IdentDecl *idecl = ident_decl(ident);
@@ -1333,10 +1334,6 @@ static bool types_decl(Typer *tr, Declaration *d) {
success = false;
goto ret;
}
- if (!type_resolve(tr, val->type, d->where)) {
- success = false;
- goto ret;
- }
if (val->type->kind == TYPE_TUPLE) {
err_print(d->where, "You can't declare a new type to be a tuple.");
success = false;