From 6cf714ba462b691135e21146f817f88e5a991b05 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 4 Apr 2020 15:51:21 -0400 Subject: fixed namespace problem --- cgen.c | 21 +++++++------- decls_cgen.c | 3 +- parse.c | 1 + test.toc | 2 +- types.c | 94 +++++++++++++++++++++++++++++------------------------------- 5 files changed, 61 insertions(+), 60 deletions(-) diff --git a/cgen.c b/cgen.c index 8fb7468..e7ce012 100644 --- a/cgen.c +++ b/cgen.c @@ -39,13 +39,16 @@ static void cgen_defs_decl(CGenerator *g, Declaration *d); #define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \ if (!(fn->flags & FN_EXPR_FOREIGN)) { \ FnExpr *prev_fn = g->f##n; \ + Block *prev_block = g->block; \ g->f##n = fn; \ - arr_foreach(fn->params, Declaration, param) \ + g->block = &fn->body; \ + arr_foreach(fn->params, Declaration, param) \ decl_f(g, param); \ arr_foreach(fn->ret_decls, Declaration, r) \ decl_f(g, r); \ block_f(g, &fn->body); \ g->f##n = prev_fn; \ + g->block = prev_block; \ } /* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */ @@ -256,7 +259,7 @@ static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) { /* should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) */ static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) { - return g->fn == NULL && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; + return (!g->block || g->block->kind == BLOCK_NMS) && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; } static bool fn_has_instances(FnExpr *f) { @@ -1812,12 +1815,14 @@ static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) { if (f->flags & FN_EXPR_FOREIGN) return; /* handled by decls_cgen */ /* see also cgen_defs_expr */ - FnExpr *prev_fn = g->fn; U64 which_are_const = compile_time_args ? compile_time_args->u64 : 0; if (!cgen_should_gen_fn(f)) return; - cgen_fn_header(g, f, which_are_const); + FnExpr *prev_fn = g->fn; + Block *prev_block = g->block; g->fn = f; + g->block = &f->body; + cgen_fn_header(g, f, which_are_const); cgen_write(g, " {"); cgen_nl(g); if (compile_time_args) { @@ -1874,20 +1879,16 @@ static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) { } cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOBRACES); - Block *prev = g->block; - g->block = &f->body; - /* cgen_ret needs to think it's in the function body */ cgen_ret(g, &f->body, f->body.ret_expr); - g->block = prev; cgen_writeln(g, "}"); - + g->block = prev_block; g->fn = prev_fn; cgen_nl(g); cgen_nl(g); } static void cgen_decl(CGenerator *g, Declaration *d) { - if (g->block == NULL && g->fn == NULL) + if (!g->block || (g->block->kind == BLOCK_NMS)) return; /* already dealt with */ int has_expr = d->flags & DECL_HAS_EXPR; if (cgen_fn_is_direct(g, d)) diff --git a/decls_cgen.c b/decls_cgen.c index 5b4467b..78f51a3 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -340,7 +340,7 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) { if (d->flags & DECL_HAS_EXPR) { cgen_decls_expr(g, &d->expr); } - if (g->fn == NULL) { + if (!g->block || g->block->kind == BLOCK_NMS) { /* global variables */ for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) { Identifier ident = d->idents[i]; @@ -353,6 +353,7 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) { cgen_ident(g, ident); cgen_type_post(g, type); if (d->flags & DECL_HAS_EXPR) { + assert(d->flags & DECL_FOUND_VAL); Value *val = decl_val_at_index(d, i); cgen_write(g, " = "); cgen_val(g, val, type); diff --git a/parse.c b/parse.c index 4c81213..bd25189 100644 --- a/parse.c +++ b/parse.c @@ -1292,6 +1292,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { ++t->token; if (!parse_block(p, &n->body, 0)) return false; + n->body.kind = BLOCK_NMS; goto success; } case KW_IF: diff --git a/test.toc b/test.toc index e7bd007..de22166 100644 --- a/test.toc +++ b/test.toc @@ -7,5 +7,5 @@ main ::= fn() { p ::= nms { y := 5; } - puti(p.x); + puti(p.y); } diff --git a/types.c b/types.c index e16fd22..9539170 100644 --- a/types.c +++ b/types.c @@ -577,47 +577,54 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } /* may modify ident */ -static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) { +enum { + TYPE_OF_IDENT_BLOCK_IS_CORRECT = 0x01 /* *ident is already from the right block (it doesn't need translation) */ +}; +static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t, U16 flags) { t->flags = 0; Identifier i = *ident; Block *b = tr->block; bool undeclared = true; - while (1) { /* for each block we are inside... */ - /* OPTIM: only hash once */ - Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); - if (ident_is_declared(translated)) { + if (flags & TYPE_OF_IDENT_BLOCK_IS_CORRECT) { + undeclared = !ident_is_declared(*ident); + } else { + while (1) { /* for each block we are inside... */ + /* OPTIM: only hash once */ + Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); + if (ident_is_declared(translated)) { #if 0 - printf("translated %s from\n", ident_to_str(i)); - print_block_location(i->idents->body); - printf(" to \n"); - print_block_location(translated->idents->body); + printf("translated %s from\n", ident_to_str(i)); + print_block_location(i->idents->body); + printf(" to \n"); + print_block_location(translated->idents->body); #endif - i = *ident = translated; - undeclared = false; - } - Use **uses = b ? b->uses : tr->uses; + i = *ident = translated; + undeclared = false; + } + Use **uses = b ? b->uses : tr->uses; - Use *previous_use_which_uses_i = NULL; - (void)previous_use_which_uses_i; - arr_foreach(uses, UsePtr, usep) { - Use *use = *usep; - Expression *e = &use->expr; - if (type_is_builtin(&e->type, BUILTIN_NMS)) { - + Use *previous_use_which_uses_i = NULL; + (void)previous_use_which_uses_i; + arr_foreach(uses, UsePtr, usep) { + Use *use = *usep; + Expression *e = &use->expr; + if (type_is_builtin(&e->type, BUILTIN_NMS)) { + + } else { + /* it's a struct */ + Type *struct_type = &e->type; + if (struct_type->kind == TYPE_PTR) + struct_type = struct_type->ptr; + assert(struct_type->kind == TYPE_STRUCT); + } + } + if (!undeclared) break; + if (b) { + b = b->parent; } else { - /* it's a struct */ - Type *struct_type = &e->type; - if (struct_type->kind == TYPE_PTR) - struct_type = struct_type->ptr; - assert(struct_type->kind == TYPE_STRUCT); + break; } } - if (!undeclared) break; - if (b) { - b = b->parent; - } else { - break; - } } if (undeclared) { char *s = ident_to_str(i); @@ -699,7 +706,7 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * } /* let's type the declaration, and redo this (for evaling future functions) */ if (!types_decl(tr, d)) return false; - return type_of_ident(tr, where, ident, t); + return type_of_ident(tr, where, ident, t, flags); } } } @@ -725,13 +732,10 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * *t = fo->type; } } break; - case IDECL_NONE: { - char *s = ident_to_str(i); - err_print(where, "Undeclared identifier: %s", s); - free(s); + case IDECL_NONE: + assert(0); return false; } - } return true; } @@ -1828,7 +1832,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; }; case EXPR_IDENT: { - if (!type_of_ident(tr, e->where, &e->ident, t)) return false; + if (!type_of_ident(tr, e->where, &e->ident, t, 0)) return false; } break; case EXPR_CAST: { CastExpr *c = &e->cast; @@ -2922,7 +2926,7 @@ static Status types_expr(Typer *tr, Expression *e) { e->binary.op = BINARY_DOT; e->binary.rhs->kind = EXPR_IDENT; e->binary.rhs->ident = ident_get_with_len(&nms->body.idents, member_name.slice.data, (size_t)member_name.slice.n); - if (!type_of_ident(tr, rhs->where, &e->binary.rhs->ident, t)) { + if (!type_of_ident(tr, rhs->where, &e->binary.rhs->ident, t, TYPE_OF_IDENT_BLOCK_IS_CORRECT)) { return false; } break; @@ -3049,13 +3053,10 @@ static Status types_expr(Typer *tr, Expression *e) { Namespace *nms = nms_val.nms; lhs->kind = EXPR_VAL; lhs->val.nms = nms; - Block *prev = tr->block; - /* briefly pretend we are in the namespace */ - tr->block = &nms->body; - if (!type_of_ident(tr, rhs->where, &rhs->ident, t)) { + rhs->ident = ident_translate(rhs->ident, &nms->body.idents); + if (!type_of_ident(tr, rhs->where, &rhs->ident, t, TYPE_OF_IDENT_BLOCK_IS_CORRECT)) { return false; } - tr->block = prev; } else { char *s = type_to_str(lhs_type); err_print(e->where, "Operator . applied to type %s, which is not a structure or pointer to structure.", s); @@ -3121,7 +3122,6 @@ static Status types_expr(Typer *tr, Expression *e) { tr->nms = prev_nms; return false; } - n->body.kind = BLOCK_NMS; tr->nms = prev_nms; n->associated_ident = NULL; /* set when we type the declaration which contains this namespace */ t->kind = TYPE_BUILTIN; @@ -3239,8 +3239,7 @@ static Status types_decl(Typer *tr, Declaration *d) { d->type = d->expr.type; d->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; /* x := 5; => x is not flexible */ } - bool need_value = (d->flags & DECL_IS_CONST) || tr->fn == NULL; - + bool need_value = (d->flags & DECL_IS_CONST) || !tr->block || tr->block->kind == BLOCK_NMS; if (need_value) { if (!(d->flags & DECL_FOUND_VAL)) { Value val; @@ -3252,7 +3251,6 @@ static Status types_decl(Typer *tr, Declaration *d) { d->flags |= DECL_FOUND_VAL; } } - } for (size_t i = 0; i < arr_len(d->idents); ++i) { -- cgit v1.2.3