summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-13 17:29:35 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-13 17:29:35 -0400
commit23c054dcfe3642753504bc5e51c10e31f51f722a (patch)
tree2dc7bb4948745790009732ede7f8d0dd0219e61d
parent1a512580a6e433341bbeb51ec2ee04a289112909 (diff)
cleaned up ident system; working except for for
-rw-r--r--cgen.c43
-rw-r--r--copy.c1
-rw-r--r--eval.c116
-rw-r--r--infer.c24
-rw-r--r--main.c10
-rw-r--r--parse.c34
-rw-r--r--test.toc18
-rw-r--r--types.c211
-rw-r--r--types.h14
9 files changed, 200 insertions, 271 deletions
diff --git a/cgen.c b/cgen.c
index 836c1a4..8551841 100644
--- a/cgen.c
+++ b/cgen.c
@@ -233,7 +233,7 @@ static void cgen_ident(CGenerator *g, Identifier i) {
if (i->nms) {
cgen_write(g, "%s", i->nms->c.prefix);
}
- if (i == g->main_ident && i->decl_kind == IDECL_DECL && ident_scope(i) == NULL) {
+ if (i == g->main_ident && ident_scope(i) == NULL) {
/* don't conflict with C's main! */
cgen_write(g, "main_");
} else {
@@ -1239,24 +1239,22 @@ static void cgen_expr(CGenerator *g, Expression *e) {
if (e->type.kind == TYPE_FN) {
/* generate the right function name, because it might be anonymous */
Identifier i = e->ident;
- if (i->decl_kind == IDECL_DECL) {
- Declaration *d = i->decl;
- if (d->flags & DECL_IS_CONST) {
- int index = decl_ident_index(d, i);
- Value fn_val = *decl_val_at_index(d, index);
- FnExpr *fn = fn_val.fn;
- Expression fn_expr;
- /* TODO: is this all really necessary? */
-
- fn_expr.kind = EXPR_FN;
- fn_expr.fn = allocr_malloc(g->allocr, sizeof *fn_expr.fn);
- *fn_expr.fn = *fn;
- fn_expr.flags = EXPR_FOUND_TYPE;
- fn_expr.type = *decl_type_at_index(d, index);
-
- cgen_expr(g, &fn_expr);
- handled = true;
- }
+ Declaration *d = i->decl;
+ if (d->flags & DECL_IS_CONST) {
+ int index = decl_ident_index(d, i);
+ Value fn_val = *decl_val_at_index(d, index);
+ FnExpr *fn = fn_val.fn;
+ Expression fn_expr;
+ /* TODO: is this all really necessary? */
+
+ fn_expr.kind = EXPR_FN;
+ fn_expr.fn = allocr_malloc(g->allocr, sizeof *fn_expr.fn);
+ *fn_expr.fn = *fn;
+ fn_expr.flags = EXPR_FOUND_TYPE;
+ fn_expr.type = *decl_type_at_index(d, index);
+
+ cgen_expr(g, &fn_expr);
+ handled = true;
}
}
if (!handled) {
@@ -1437,6 +1435,8 @@ static void cgen_expr(CGenerator *g, Expression *e) {
cgen_block(g, &w->body, NULL, 0);
} break;
case EXPR_FOR: {
+ /* TODO */
+#if 0
ForExpr *fo = e->for_;
int is_range = fo->flags & FOR_IS_RANGE;
if (is_range) {
@@ -1450,9 +1450,9 @@ static void cgen_expr(CGenerator *g, Expression *e) {
if (is_range) {
if (fo->range.to) {
/* pre generate to */
- cgen_type_pre(g, &fo->type);
+ cgen_type_pre(g, fo->type);
cgen_write(g, " to_");
- cgen_type_post(g, &fo->type);
+ cgen_type_post(g, fo->type);
cgen_write(g, " = ");
cgen_expr(g, fo->range.to);
cgen_write(g, "; ");
@@ -1612,6 +1612,7 @@ static void cgen_expr(CGenerator *g, Expression *e) {
cgen_lbl(g, fo->body.c.break_lbl);
cgen_writeln(g, ":;");
}
+#endif
} break;
case EXPR_BLOCK:
case EXPR_IF:
diff --git a/copy.c b/copy.c
index 1cbc088..7380c05 100644
--- a/copy.c
+++ b/copy.c
@@ -364,7 +364,6 @@ static void copy_decl(Copier *c, Declaration *out, Declaration *in) {
assert(c->block);
copier_ident_translate(c, &out->idents[i]);
- out->idents[i]->decl_kind = IDECL_DECL;
out->idents[i]->decl = out;
}
diff --git a/eval.c b/eval.c
index da173d8..806a024 100644
--- a/eval.c
+++ b/eval.c
@@ -663,67 +663,48 @@ static Status eval_expr_ptr_at_index(Evaluator *ev, Expression *e, void **ptr, T
}
static Value *ident_val(Evaluator *ev, Identifier i, Location where) {
- switch (i->decl_kind) {
- case IDECL_FOR: {
- ForExpr *fo = i->decl_for;
- Value *v = *(Value **)arr_last(fo->val_stack);
- if (i == fo->index) {
- if (fo->value)
- v = &v->tuple[0];
- } else {
- if (fo->index)
- v = &v->tuple[1];
- }
- return v;
- }
- case IDECL_DECL: {
- Declaration *decl = i->decl;
- int idx = decl_ident_index(decl, i);
- if (decl->type.kind == TYPE_UNKNOWN && ev->typer->err_ctx->have_errored)
- return NULL; /* silently fail (something went wrong when we typed this decl) */
- if (decl->flags & DECL_IS_PARAM) {
- if (decl->val_stack) {
- Value *valp = *(Value **)arr_last(decl->val_stack);
- if (arr_len(decl->idents) > 1)
- return &valp->tuple[idx];
- else
- return valp;
- } else {
- if (!(decl->flags & DECL_FOUND_VAL)) {
- /* trying to access parameter, e.g. fn(y: int) { x ::= y; } */
- char *s = ident_to_str(i);
- err_print(where, "You can't access non-constant parameter %s at compile time.", s);
- info_print(decl->where, "%s was declared here.", s);
- free(s);
- return NULL;
- }
- /* struct parameter */
- if (arr_len(decl->idents) > 1)
- return &decl->val.tuple[idx];
- else
- return &decl->val;
- }
- } else if (decl->flags & DECL_IS_CONST) {
- return decl_val_at_index(decl, idx);
- } else if (decl->val_stack) {
+ assert(ident_is_declared(i));
+ Declaration *decl = i->decl;
+ int idx = decl_ident_index(decl, i);
+ if (decl->type.kind == TYPE_UNKNOWN && ev->typer->err_ctx->have_errored)
+ return NULL; /* silently fail (something went wrong when we typed this decl) */
+ if (decl->flags & DECL_IS_PARAM) {
+ if (decl->val_stack) {
Value *valp = *(Value **)arr_last(decl->val_stack);
if (arr_len(decl->idents) > 1)
return &valp->tuple[idx];
else
return valp;
} else {
- char *s = ident_to_str(i);
- err_print(where, "You can't access non-constant variable %s at compile time.", s);
- info_print(decl->where, "%s was declared here.", s);
- free(s);
- return NULL; /* uh oh... this is a runtime-only variable */
+ if (!(decl->flags & DECL_FOUND_VAL)) {
+ /* trying to access parameter, e.g. fn(y: int) { x ::= y; } */
+ char *s = ident_to_str(i);
+ err_print(where, "You can't access non-constant parameter %s at compile time.", s);
+ info_print(decl->where, "%s was declared here.", s);
+ free(s);
+ return NULL;
+ }
+ /* struct parameter */
+ if (arr_len(decl->idents) > 1)
+ return &decl->val.tuple[idx];
+ else
+ return &decl->val;
}
+ } else if (decl->flags & DECL_IS_CONST) {
+ return decl_val_at_index(decl, idx);
+ } else if (decl->val_stack) {
+ Value *valp = *(Value **)arr_last(decl->val_stack);
+ if (arr_len(decl->idents) > 1)
+ return &valp->tuple[idx];
+ else
+ return valp;
+ } else {
+ char *s = ident_to_str(i);
+ err_print(where, "You can't access non-constant variable %s at compile time.", s);
+ info_print(decl->where, "%s was declared here.", s);
+ free(s);
+ return NULL; /* uh oh... this is a runtime-only variable */
}
- case IDECL_NONE: break;
- }
- assert(0);
- return NULL;
-
}
static inline bool eval_address_of_ident(Evaluator *ev, Identifier i, Location where, Type *type, void **ptr) {
@@ -1036,26 +1017,22 @@ static bool val_is_nonnegative(Value v, Type *t) {
}
static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location where) {
- if (ident->decl_kind == IDECL_NONE) {
+ if (!ident_is_declared(ident)) {
char *s = ident_to_str(ident);
err_print(where, "Undeclared identifier: %s.", s);
free(s);
return false;
}
- bool is_decl = ident->decl_kind == IDECL_DECL;
- Declaration *d = NULL;
- if (is_decl) {
- d = ident->decl;
- 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;
- return true;
- } else {
- if (!types_decl(ev->typer, d)) return false;
- assert(d->type.flags & TYPE_IS_RESOLVED);
- }
+ Declaration *d = ident->decl;
+ 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;
+ return true;
+ } else {
+ if (!types_decl(ev->typer, d)) return false;
+ assert(d->type.flags & TYPE_IS_RESOLVED);
}
Value *ival = ident_val(ev, ident, where);
if (!ival) return false;
@@ -1273,6 +1250,8 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
} break;
case EXPR_FOR: {
+ /* TODO */
+#if 0
ForExpr *fo = e->for_;
Value *index_val;
Value *value_val;
@@ -1394,6 +1373,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
free(for_valp->tuple);
}
free(for_valp);
+#endif
} break;
case EXPR_BLOCK:
if (!eval_block(ev, e->block, v)) return false;
diff --git a/infer.c b/infer.c
index 0a88c82..fceeaa4 100644
--- a/infer.c
+++ b/infer.c
@@ -75,19 +75,17 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
while (to->kind == EXPR_IDENT) {
Identifier i = to->ident;
- if (i->decl_kind == IDECL_DECL) {
- Declaration *decl = i->decl;
- int index = ident_index_in_decl(i, decl);
- Expression *expr = NULL;
- if (decl->type.kind == TYPE_TUPLE) {
- if (decl->expr.kind == EXPR_TUPLE) {
- expr = &decl->expr.tuple[index];
- }
- } else {
- expr = &decl->expr;
+ Declaration *decl = i->decl;
+ int index = ident_index_in_decl(i, decl);
+ Expression *expr = NULL;
+ if (decl->type.kind == TYPE_TUPLE) {
+ if (decl->expr.kind == EXPR_TUPLE) {
+ expr = &decl->expr.tuple[index];
}
- if (expr) to = expr;
- } else break;
+ } else {
+ expr = &decl->expr;
+ }
+ if (expr) to = expr;
}
if (to->kind != EXPR_CALL) {
if (to->kind == EXPR_TYPE) {
@@ -104,7 +102,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
I16 *order = NULL;
Expression *f = match->call.fn;
Identifier ident = f->ident;
- bool is_direct_fn = f->kind == EXPR_IDENT && ident->decl_kind == IDECL_DECL && (ident->decl->flags & DECL_HAS_EXPR) && ident->decl->expr.kind == EXPR_FN;
+ bool is_direct_fn = f->kind == EXPR_IDENT && (ident->decl->flags & DECL_HAS_EXPR) && ident->decl->expr.kind == EXPR_FN;
if (!types_expr(tr, f))
return false;
if (f->type.kind != TYPE_FN) {
diff --git a/main.c b/main.c
index 6934d08..7f64537 100644
--- a/main.c
+++ b/main.c
@@ -8,9 +8,15 @@
/*
TODO:
-replace weird EXPR_FOR system with just a declaration- would make "for use p := points" easier
- -> rewrite for copying
+replace weird EXPR_FOR system with just a declaration- would make "for use p := points" easier.
+ need to fix:
+ - types.c
+ - cgen.c
+ - eval.c
+ - copy.c
+do we need the possibility that IdentSlot.decl is NULL?
EXPR_IDENT should be a string before typing, also struct member accesses
+make sure we set Expression.where in stuff like the EXPR_FOR for varargs (i.e. places where we construct expressions)
use
- use with struct members (e.g. SuperPoint ::= struct { use p: Point; })
local structs should not be named in C
diff --git a/parse.c b/parse.c
index c9e34a8..ceb690e 100644
--- a/parse.c
+++ b/parse.c
@@ -1001,14 +1001,12 @@ static Identifier parser_ident_insert(Parser *p, char *str) {
static Status check_ident_redecl(Parser *p, Identifier i) {
Tokenizer *t = p->tokr;
- if (i->idents == (p->block ? &p->block->idents : p->globals)) { /* in the same scope */
- if (i->decl_kind != IDECL_NONE) { /* declared */
- char *s = ident_to_str(i);
- tokr_err(t, "Redeclaration of identifier %s.", s);
- info_print(ident_decl_location(i), "Previous declaration was here.");
- free(s);
- return false;
- }
+ if (ident_is_declared(i)) {
+ char *s = ident_to_str(i);
+ tokr_err(t, "Redeclaration of identifier %s.", s);
+ info_print(ident_decl_location(i), "Previous declaration was here.");
+ free(s);
+ return false;
}
return true;
}
@@ -2121,7 +2119,6 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) {
Identifier i = *ident;
if (!check_ident_redecl(p, i))
goto ret_false;
- i->decl_kind = IDECL_DECL;
i->decl = d;
}
++t->token;
@@ -2429,7 +2426,6 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
tokr_skip_semicolon(t);
return false;
}
- ident->decl_kind = IDECL_DECL;
ident->decl = d;
Expression *e = &d->expr;
@@ -2701,23 +2697,14 @@ static void fprint_expr(FILE *out, Expression *e) {
case EXPR_FOR: {
ForExpr *fo = e->for_;
fprintf(out, "for ");
- if (fo->index) {
- fprint_ident_debug(out, fo->index);
- } else fprintf(out, "_");
- fprintf(out, ", ");
- if (fo->value) {
- fprint_ident_debug(out, fo->value);
- } else fprintf(out, "_");
- fprintf(out, " :");
- if (fo->flags & FOR_ANNOTATED_TYPE)
- fprint_type(out, &fo->type);
+ fprint_decl(out, &fo->header);
fprintf(out, "= ");
if (fo->flags & FOR_IS_RANGE) {
fprint_expr(out, fo->range.from);
if (found_type) {
if (fo->range.stepval) {
fprintf(out, ",");
- fprint_val(out, *fo->range.stepval, &fo->type);
+ fprint_val(out, *fo->range.stepval, fo->type);
}
} else {
if (fo->range.step) {
@@ -2923,9 +2910,10 @@ static inline Type *decl_type_at_index(Declaration *d, int i) {
return ret;
}
-static bool ident_is_definitely_const(Identifier i) {
+static inline bool ident_is_definitely_const(Identifier i) {
+ assert(ident_is_declared(i));
Declaration *decl = i->decl;
- if (i->decl_kind != IDECL_DECL || !(decl->flags & DECL_IS_CONST))
+ if (!(decl->flags & DECL_IS_CONST))
return false;
return true;
diff --git a/test.toc b/test.toc
index a23df05..8c4d07f 100644
--- a/test.toc
+++ b/test.toc
@@ -1,17 +1,11 @@
-#include "std/io.toc";
-
-Point ::= struct {
+Point ::= struct {
x, y: int;
}
-foo ::= fn() []char {
- return "y";
-}
-
main ::= fn() {
- p: Point;
- p["x"] = 5;
- p[foo()] = 17;
- puti(p["x"]);
- puti(p.y);
+ use p: Point;
+ p.x = 15;
+ p.y = 18;
+ x += 5;
+ x := 18;
}
diff --git a/types.c b/types.c
index fb3f124..5966e8c 100644
--- a/types.c
+++ b/types.c
@@ -268,23 +268,20 @@ static Status expr_must_lval(Expression *e) {
switch (e->kind) {
case EXPR_IDENT: {
Identifier i = e->ident;
- if (i->decl_kind == IDECL_DECL) {
- Declaration *d = i->decl;
- if (d->flags & DECL_IS_CONST) {
- char *istr = ident_to_str(i);
- err_print(e->where, "Use of constant %s as a non-constant expression.", istr);
- info_print(d->where, "%s was declared here.", istr);
- free(istr);
- return false;
- }
- if (type_is_builtin(&d->type, BUILTIN_VARARGS)) {
- char *istr = ident_to_str(i);
- err_print(e->where, "varargs cannot be set or pointed to.");
- info_print(d->where, "%s was declared here.", istr);
- free(istr);
- return false;
- }
-
+ Declaration *d = i->decl;
+ if (d->flags & DECL_IS_CONST) {
+ char *istr = ident_to_str(i);
+ err_print(e->where, "Use of constant %s as a non-constant expression.", istr);
+ info_print(d->where, "%s was declared here.", istr);
+ free(istr);
+ return false;
+ }
+ if (type_is_builtin(&d->type, BUILTIN_VARARGS)) {
+ char *istr = ident_to_str(i);
+ err_print(e->where, "varargs cannot be set or pointed to.");
+ info_print(d->where, "%s was declared here.", istr);
+ free(istr);
+ return false;
}
return true;
}
@@ -587,114 +584,87 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
return success;
}
-/* doesn't do any translation on ident or anything, so make sure it's in the right scope */
+/* doesn't do any translation on ident or check if it's declared or anything, so make sure it's in the right scope */
static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
- switch (i->decl_kind) {
- case IDECL_DECL:
- top: {
- Declaration *d = i->decl;
- if (!(d->flags & DECL_IS_CONST)) {
- /* check for trying to capture a variable into a function */
- bool captured = false;
- if (ident_scope(i) != NULL && ident_scope(i)->kind != BLOCK_NMS) {
- Block *decl_scope = ident_scope(i);
- if (decl_scope->kind != BLOCK_NMS) {
- /* go back through scopes */
- for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) {
- if ((*block)->kind == BLOCK_FN) {
- captured = true;
- break;
- }
+top:;
+ Declaration *d = i->decl;
+ assert(d);
+ if (!(d->flags & DECL_IS_CONST)) {
+ /* check for trying to capture a variable into a function */
+ bool captured = false;
+ if (ident_scope(i) != NULL && ident_scope(i)->kind != BLOCK_NMS) {
+ Block *decl_scope = ident_scope(i);
+ if (decl_scope->kind != BLOCK_NMS) {
+ /* go back through scopes */
+ for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) {
+ if ((*block)->kind == BLOCK_FN) {
+ captured = true;
+ break;
}
}
}
- if (captured) {
- err_print(where, "Variables cannot be captured into inner functions (but constants can).");
- return false;
- }
}
- 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;
- }
-
- /* are we inside this declaration? */
- arr_foreach(tr->in_decls, DeclarationPtr, in_decl) {
- if (d == *in_decl) {
- /* d needn't have an expression, because it could be its type that refers to itself */
- if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN) {
- /* it's okay if a function references itself */
- } else {
- /* if we've complained about it before when we were figuring out the type, don't complain again */
- if (!(d->flags & DECL_ERRORED_ABOUT_SELF_REFERENCE)) {
- char *s = ident_to_str(i);
- err_print(where, "Use of identifier %s in its own declaration.", s);
- free(s);
- info_print(d->where, "Declaration was here.");
- d->flags |= DECL_ERRORED_ABOUT_SELF_REFERENCE;
- }
- return false;
- }
- }
+ if (captured) {
+ err_print(where, "Variables cannot be captured into inner functions (but constants can).");
+ return false;
}
-
- if (d->flags & DECL_FOUND_TYPE) {
- *t = *decl_type_at_index(d, decl_ident_index(d, i));
- assert(t->flags & TYPE_IS_RESOLVED);
- return true;
- } else {
- if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_FN)) {
- /* allow using a function before declaring it */
- if (!type_of_fn(tr, d->expr.fn, &d->expr.type, 0)) return false;
- *t = d->expr.type;
- t->flags |= TYPE_IS_RESOLVED; /* for function templates */
- return true;
+ }
+ 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;
+ }
+
+ /* are we inside this declaration? */
+ arr_foreach(tr->in_decls, DeclarationPtr, in_decl) {
+ if (d == *in_decl) {
+ /* d needn't have an expression, because it could be its type that refers to itself */
+ if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN) {
+ /* it's okay if a function references itself */
} else {
- if (where.start <= d->where.end) {
+ /* if we've complained about it before when we were figuring out the type, don't complain again */
+ if (!(d->flags & DECL_ERRORED_ABOUT_SELF_REFERENCE)) {
char *s = ident_to_str(i);
- err_print(where, "Use of identifier %s before its declaration.", s);
- info_print(d->where, "%s will be declared here.", s);
+ err_print(where, "Use of identifier %s in its own declaration.", s);
free(s);
- return false;
- } else {
- if (d->flags & DECL_INFER) {
- err_print(where, "Use of identifier before it has been inferred. You are trying to do stuff with inference which toc doesn't support.");
- return false;
- }
- /* let's type the declaration, and redo this (for evaling future functions) */
- if (!types_decl(tr, d)) return false;
- goto top;
+ info_print(d->where, "Declaration was here.");
+ d->flags |= DECL_ERRORED_ABOUT_SELF_REFERENCE;
}
+ return false;
}
}
- } break;
- case IDECL_FOR: {
- ForExpr *fo = i->decl_for;
- /* are we inside this for loop? */
- typedef ForExpr *ForExprPtr;
- arr_foreach(tr->in_fors, ForExprPtr, in_f) {
- if (*in_f == fo) {
+ }
+
+ if (d->flags & DECL_FOUND_TYPE) {
+ *t = *decl_type_at_index(d, decl_ident_index(d, i));
+ assert(t->flags & TYPE_IS_RESOLVED);
+ return true;
+ } else {
+ if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_FN)) {
+ /* allow using a function before declaring it */
+ if (!type_of_fn(tr, d->expr.fn, &d->expr.type, 0)) return false;
+ *t = d->expr.type;
+ t->flags |= TYPE_IS_RESOLVED; /* for function templates */
+ return true;
+ } else {
+ if (where.start <= d->where.end) {
char *s = ident_to_str(i);
- err_print(where, "Use of identifier %s in its own declaration.", s);
+ err_print(where, "Use of identifier %s before its declaration.", s);
+ info_print(d->where, "%s will be declared here.", s);
free(s);
return false;
+ } else {
+ if (d->flags & DECL_INFER) {
+ err_print(where, "Use of identifier before it has been inferred. You are trying to do stuff with inference which toc doesn't support.");
+ return false;
+ }
+ /* let's type the declaration, and redo this (for evaling future functions) */
+ if (!types_decl(tr, d)) return false;
+ goto top;
}
}
- if (i == fo->index) {
- t->kind = TYPE_BUILTIN;
- t->builtin = BUILTIN_I64;
- t->flags = TYPE_IS_RESOLVED;
- } else {
- assert(i == fo->value);
- *t = fo->type;
- }
- } break;
- case IDECL_NONE:
- assert(0);
- return false;
}
return true;
}
@@ -749,15 +719,14 @@ static Status add_block_to_struct(Typer *tr, Block *b, StructDef *s, Statement *
/* we need to translate d's identifiers to s's scope */
arr_foreach(d->idents, Identifier, ip) {
Identifier redeclared = ident_get(&s->body.idents, (*ip)->str);
- if (redeclared && redeclared->decl_kind != IDECL_NONE) {
+ if (ident_is_declared(redeclared)) {
char *str = ident_to_str(*ip);
err_print(d->where, "Redeclaration of struct member %s", str);
- info_print(ident_decl_location(d->where.file, redeclared), "Previous declaration was here.");
+ info_print(ident_decl_location(redeclared), "Previous declaration was here.");
free(str);
return false;
}
*ip = ident_translate_forced(*ip, &s->body.idents);
- (*ip)->decl_kind = IDECL_DECL;
(*ip)->decl = d;
}
}
@@ -1468,7 +1437,7 @@ static Status get_struct_constant(StructDef *struc, Identifier member, Expressio
return false;
}
Identifier i = ident_translate(member, &struc->body.idents);
- if (!i || i->decl_kind == IDECL_NONE) {
+ if (!i) {
char *member_s = ident_to_str(member);
char *struc_s = struc->name ? ident_to_str(struc->name) : "anonymous struct";
err_print(e->where, "%s is not a member of structure %s.", member_s, struc_s);
@@ -1477,7 +1446,11 @@ static Status get_struct_constant(StructDef *struc, Identifier member, Expressio
if (struc->name) free(struc_s);
return false;
}
- assert((i->decl_kind == IDECL_DECL) && (i->decl->flags & DECL_IS_CONST));
+ if (!(i->decl->flags & DECL_IS_CONST)) {
+ err_print(e->where, "Struct field being used as if it were a constant.");
+ info_print(i->decl->where, "Field was declared here.");
+ return false;
+ }
if (i->decl->flags & DECL_FOUND_VAL) {
/* replace with decl value */
int ident_idx = decl_ident_index(i->decl, i);
@@ -1546,6 +1519,8 @@ static Status types_expr(Typer *tr, Expression *e) {
t->builtin = BUILTIN_CHAR;
break;
case EXPR_FOR: {
+ /* TODO */
+#if 0
ForExpr *fo = e->for_;
bool in_header = true;
*(ForExpr **)typer_arr_add(tr, &tr->in_fors) = fo;
@@ -1584,7 +1559,7 @@ static Status types_expr(Typer *tr, Expression *e) {
}
if (!(fo->flags & FOR_ANNOTATED_TYPE)) {
- fo->type = fo->range.from->type;
+ fo->type = &fo->range.from->type;
}
if (!type_eq(&fo->type, &fo->range.from->type)) {
@@ -1790,6 +1765,7 @@ static Status types_expr(Typer *tr, Expression *e) {
arr_remove_lasta(&tr->in_fors, tr->allocr);
typer_block_exit(tr);
return false;
+ #endif
};
case EXPR_IDENT: {
Block *b = tr->block;
@@ -1849,7 +1825,7 @@ static Status types_expr(Typer *tr, Expression *e) {
also = "also ";
} else {
/* i was declared then used. */
- info_print(ident_decl_location(tr->file, translated), "%s was declared here.", s);
+ info_print(ident_decl_location(translated), "%s was declared here.", s);
}
info_print(use->expr.where, "...and %simported by this use statement.", also);
return false;
@@ -2260,7 +2236,6 @@ static Status types_expr(Typer *tr, Expression *e) {
/* add each vararg separately */
assert(arg->kind == EXPR_IDENT);
Identifier ident = arg->ident;
- assert(ident->decl_kind == IDECL_DECL);
Declaration *decl = ident->decl;
VarArg *varargs_here = decl->val.varargs;
size_t nvarargs_here = arr_len(varargs_here);
@@ -2966,7 +2941,6 @@ static Status types_expr(Typer *tr, Expression *e) {
StructDef *struc = struct_type->struc;
Identifier struct_ident = ident_translate(rhs->ident, &struc->body.idents);
if (ident_is_declared(struct_ident)) {
- assert(struct_ident->decl_kind == IDECL_DECL);
Field *field = struct_ident->decl->field;
field += ident_index_in_decl(struct_ident, struct_ident->decl);
e->binary.dot.field = field;
@@ -2999,7 +2973,6 @@ static Status types_expr(Typer *tr, Expression *e) {
/* replace with val */
assert(of->kind == EXPR_IDENT);
Identifier ident = of->ident;
- assert(ident->decl_kind == IDECL_DECL);
Declaration *decl = ident->decl;
e->kind = EXPR_VAL;
e->val.i64 = (I64)arr_len(decl->val.varargs);
@@ -3295,6 +3268,8 @@ static Status types_decl(Typer *tr, Declaration *d) {
used->flags = EXPR_FOUND_TYPE;
used->type = *decl_type_at_index(d, idx++);
used->ident = i;
+ used->where = d->where;
+
}
}
diff --git a/types.h b/types.h
index 25a9881..e04f025 100644
--- a/types.h
+++ b/types.h
@@ -172,23 +172,11 @@ typedef struct VarArg {
Value val;
} VarArg;
-
-typedef enum {
- IDECL_NONE,
- IDECL_DECL,
- IDECL_FOR
-} IdentDeclKind;
-
-
typedef struct IdentSlot {
char *str;
size_t len;
/* where this identifier was declared */
- IdentDeclKind decl_kind;
- union {
- struct Declaration *decl;
- struct ForExpr *decl_for;
- };
+ struct Declaration *decl; /* if NULL, a declaration hasn't been found for it yet */
struct Identifiers *idents;
struct Namespace *nms; /* only exists after typing, and only for namespace-level declarations (i.e. not local variables) */
} IdentSlot;