diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-13 17:29:35 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-13 17:29:35 -0400 |
commit | 23c054dcfe3642753504bc5e51c10e31f51f722a (patch) | |
tree | 2dc7bb4948745790009732ede7f8d0dd0219e61d | |
parent | 1a512580a6e433341bbeb51ec2ee04a289112909 (diff) |
cleaned up ident system; working except for for
-rw-r--r-- | cgen.c | 43 | ||||
-rw-r--r-- | copy.c | 1 | ||||
-rw-r--r-- | eval.c | 116 | ||||
-rw-r--r-- | infer.c | 24 | ||||
-rw-r--r-- | main.c | 10 | ||||
-rw-r--r-- | parse.c | 34 | ||||
-rw-r--r-- | test.toc | 18 | ||||
-rw-r--r-- | types.c | 211 | ||||
-rw-r--r-- | types.h | 14 |
9 files changed, 200 insertions, 271 deletions
@@ -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: @@ -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; } @@ -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; @@ -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) { @@ -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 @@ -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; @@ -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; } @@ -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; + } } @@ -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; |