diff options
-rw-r--r-- | cgen.c | 1 | ||||
-rw-r--r-- | eval.c | 7 | ||||
-rw-r--r-- | identifiers.c | 1 | ||||
-rw-r--r-- | parse.c | 13 | ||||
-rw-r--r-- | scope.c | 8 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | types.c | 69 | ||||
-rw-r--r-- | types.h | 2 |
8 files changed, 63 insertions, 52 deletions
@@ -266,6 +266,7 @@ static inline void cgen_ident_simple(CGenerator *g, Identifier i) { } static void cgen_ident(CGenerator *g, Identifier i) { + if (g->block && (g->block->flags & BLOCK_IS_NMS) && !g->fn) { /* namespace prefix */ cgen_write(g, "%s", g->nms_prefix); @@ -4,10 +4,7 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -enum { - TYPES_BLOCK_NAMESPACE = 0x01 -}; -static bool types_block(Typer *tr, Block *b, U16 flags); +static bool types_block(Typer *tr, Block *b); static bool types_decl(Typer *tr, Declaration *d); static bool type_resolve(Typer *tr, Type *t, Location where); static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v); @@ -1506,7 +1503,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { break; } /* make sure function body is typed before calling it */ - if (!types_block(ev->typer, &fn->body, 0)) { + if (!types_block(ev->typer, &fn->body)) { return false; } /* NOTE: we're not calling fn_enter because we're manually entering the function */ diff --git a/identifiers.c b/identifiers.c index da1db17..ed5e675 100644 --- a/identifiers.c +++ b/identifiers.c @@ -30,7 +30,6 @@ static int is_ident(int c) { static void idents_create(Identifiers *ids) { str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), NULL); ids->rseed = 0x27182818; - } /* advances s until a non-identifier character is reached, then returns the number of characters advanced */ @@ -1065,18 +1065,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { ++t->token; if (!parse_block(p, &n->body)) return false; - /* don't set BLOCK_IS_NMS yet (done by types.c) */ - arr_foreach(e->nms.body.stmts, Statement, sub) { - if (sub->kind != STMT_DECL) { - err_print(sub->where, "Only declarations can be in namespaces."); - return false; - } - Declaration *decl = &sub->decl; - arr_foreach(decl->idents, Identifier, i) { - *i = ident_translate_forced(*i, &n->idents); - } - } - goto success; + goto success; } case KW_IF: { IfExpr *i = &e->if_; @@ -58,16 +58,16 @@ static void remove_ident_decls(Block *b, Declaration *d) { } /* pass NULL for block for global scope */ -static bool block_enter(Block *b, Statement *stmts, U16 flags) { - if (b && (b->flags & BLOCK_IS_NMS)) /* we only enter namespaces once, when they're created */ - return true; - +static bool block_enter(Block *b, Statement *stmts, U16 flags) { bool ret = true; arr_foreach(stmts, Statement, stmt) { if (stmt->kind == STMT_DECL) { Declaration *decl = &stmt->decl; if (!add_ident_decls(b, decl, flags)) ret = false; + } else if (stmt->kind == STMT_INCLUDE) { + if (!block_enter(b, stmt->inc.stmts, flags)) + return false; } } return ret; @@ -6,11 +6,11 @@ n ::= nms { main ::= fn() { - a := counter(); - b := counter(); - counter(); - c := counter(); - puti(a); - puti(b); - puti(c); + a := n.counter(); + b := n.counter(); + n.counter(); + c := n.counter(); + // puti(a); + // puti(b); + // puti(c); }; @@ -384,11 +384,13 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { bool captured = false; if (decl->scope != NULL && !(decl->scope->flags & BLOCK_IS_NMS)) { Block *decl_scope = decl->scope; - /* go back through scopes */ - for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { - if ((*block)->flags & BLOCK_IS_FN) { - captured = true; - break; + if (!(decl_scope->flags & BLOCK_IS_NMS)) { + /* go back through scopes */ + for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { + if ((*block)->flags & BLOCK_IS_FN) { + captured = true; + break; + } } } } @@ -769,7 +771,7 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) { goto ret; } entered_fn = true; - if (!types_block(tr, &f->body, 0)) { + if (!types_block(tr, &f->body)) { success = false; goto ret; } @@ -1036,6 +1038,32 @@ static char *eval_expr_as_cstr(Typer *tr, Expression *e, const char *what_is_thi return str; } +static bool nms_translate_idents_in_stmts(Namespace *nms, Statement *stmts) { + arr_foreach(stmts, Statement, s) { + switch (s->kind) { + case STMT_INCLUDE: + if (!nms_translate_idents_in_stmts(nms, s->inc.stmts)) + return false; + break; + case STMT_DECL: { + Declaration *d = &s->decl; + arr_foreach(d->idents, Identifier, i) { + *i = ident_translate_forced(*i, &nms->idents); + } + } break; + case STMT_EXPR: + case STMT_RET: + err_print(s->where, "Only declarations can appear in namespaces."); + return false; + } + } + return true; +} + +static inline bool nms_translate_idents(Namespace *nms) { + return nms_translate_idents_in_stmts(nms, nms->body.stmts); +} + static bool types_expr(Typer *tr, Expression *e) { if (e->flags & EXPR_FOUND_TYPE) return true; Type *t = &e->type; @@ -1204,7 +1232,7 @@ static bool types_expr(Typer *tr, Expression *e) { arr_remove_lasta(&tr->in_expr_decls, tr->allocr); - if (!types_block(tr, &fo->body, 0)) return false; + if (!types_block(tr, &fo->body)) return false; for_exit(e); if (fo->body.ret_expr) { @@ -1262,7 +1290,7 @@ static bool types_expr(Typer *tr, Expression *e) { IfExpr *curr = i; Type *curr_type = t; bool has_else = false; - if (!types_block(tr, &curr->body, 0)) + if (!types_block(tr, &curr->body)) return false; if (curr->body.ret_expr) { *t = curr->body.ret_expr->type; @@ -1287,7 +1315,7 @@ static bool types_expr(Typer *tr, Expression *e) { IfExpr *nexti = &curr->next_elif->if_; Type *next_type = &curr->next_elif->type; curr->next_elif->flags |= EXPR_FOUND_TYPE; - if (!types_block(tr, &nexti->body, 0)) { + if (!types_block(tr, &nexti->body)) { return false; } if (nexti->body.ret_expr) { @@ -1322,7 +1350,7 @@ static bool types_expr(Typer *tr, Expression *e) { bool ret = true; if (w->cond && !types_expr(tr, w->cond)) ret = false; - if (!types_block(tr, &w->body, 0)) + if (!types_block(tr, &w->body)) ret = false; if (!ret) return false; if (w->cond != NULL && w->body.ret_expr != NULL) { @@ -1691,7 +1719,7 @@ static bool types_expr(Typer *tr, Expression *e) { } break; case EXPR_BLOCK: { Block *b = &e->block; - if (!types_block(tr, b, 0)) + if (!types_block(tr, b)) return false; if (b->ret_expr) { *t = b->ret_expr->type; @@ -2126,11 +2154,16 @@ static bool types_expr(Typer *tr, Expression *e) { t->builtin = BUILTIN_TYPE; break; case EXPR_NMS: { - if (!types_block(tr, &e->nms.body, TYPES_BLOCK_NAMESPACE)) + e->nms.body.flags |= BLOCK_IS_NMS; + if (!types_block(tr, &e->nms.body)) return false; e->nms.associated_ident = NULL; /* set when we type the declaration */ t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_NMS; + if (!nms_translate_idents(&e->nms)) + return false; + if (!block_enter(&e->nms.body, e->nms.body.stmts, 0)) + return false; } break; case EXPR_VAL: assert(0); @@ -2155,14 +2188,12 @@ static void typer_block_exit(Typer *tr) { } -static bool types_block(Typer *tr, Block *b, U16 flags) { +static bool types_block(Typer *tr, Block *b) { if (b->flags & BLOCK_FOUND_TYPES) return true; bool success = true; if (!typer_block_enter(tr, b)) return false; - if (flags & TYPES_BLOCK_NAMESPACE) - b->flags |= BLOCK_IS_NMS; /* do this after typer_block_enter because otherwise it won't actually enter the block */ arr_foreach(b->stmts, Statement, s) { if (!types_stmt(tr, s)) { success = false; @@ -2194,13 +2225,7 @@ static bool types_block(Typer *tr, Block *b, U16 flags) { } ret: - if (flags & TYPES_BLOCK_NAMESPACE) { - /* don't exit block because we don't want to have to re-enter each time we grab something from the namespace */ - arr_remove_last(&tr->blocks); - tr->block = *(Block **)arr_last(tr->blocks); - } else { - typer_block_exit(tr); - } + typer_block_exit(tr); b->flags |= BLOCK_FOUND_TYPES; return success; } @@ -702,7 +702,7 @@ typedef struct Namespace { Identifiers idents; /* these do not include local variables */ Identifier associated_ident; /* if this is foo ::= nms { ... }, then associated_ident is foo; can be NULL */ struct { - IdentID id; /* used as prefix is associated_ident is unavailable */ + IdentID id; /* used as prefix if prefix is NULL */ } c; } Namespace; |