From 6ecf77104d061b2035d490c23e45cc5b1a1a0235 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 31 Jan 2020 22:00:34 -0500 Subject: more namespaces --- data_structures.c | 2 +- eval.c | 8 ++++++-- identifiers.c | 10 +++++++--- main.c | 1 + parse.c | 6 ++++++ test.toc | 5 +++-- types.c | 26 ++++++++++++++++---------- types.h | 5 +++-- 8 files changed, 43 insertions(+), 20 deletions(-) diff --git a/data_structures.c b/data_structures.c index 3393c6b..524f916 100644 --- a/data_structures.c +++ b/data_structures.c @@ -24,7 +24,7 @@ For more information, please refer to */ /* OPTIM: is it faster to store void *end? */ -typedef struct { +typedef struct ArrHeader { size_t len; size_t cap; MaxAlign data[]; diff --git a/eval.c b/eval.c index 4995ea3..635c93d 100644 --- a/eval.c +++ b/eval.c @@ -3,7 +3,11 @@ This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. You should have received a copy of the GNU General Public License along with toc. If not, see . */ -static bool types_block(Typer *tr, Block *b); + +enum { + TYPES_BLOCK_NAMESPACE = 0x01 +}; +static bool types_block(Typer *tr, Block *b, U16 flags); 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); @@ -1461,7 +1465,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)) { + if (!types_block(ev->typer, &fn->body, 0)) { 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 6eb0bfa..25eaea1 100644 --- a/identifiers.c +++ b/identifiers.c @@ -30,6 +30,7 @@ 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 */ @@ -89,7 +90,8 @@ static Identifier ident_new_anonymous(Identifiers *ids) { static Identifier ident_insert(Identifiers *ids, char **s) { char *original = *s; size_t len = ident_str_len(s); - return (Identifier)str_hash_table_insert_(&ids->table, original, len); + IdentSlot *slot = (IdentSlot *)str_hash_table_insert_(&ids->table, original, len); + return slot; } static char *ident_to_str(Identifier i) { @@ -163,9 +165,11 @@ static Identifier ident_get(Identifiers *ids, char *s) { return (Identifier)str_hash_table_get_(&ids->table, s, len); } -static Identifier ident_translate(Identifier i, Identifiers *to_idents) { +/* translate and insert if not already there */ +static Identifier ident_translate_forced(Identifier i, Identifiers *to_idents) { if (!i || i->anonymous) return NULL; - Identifier new_ident = ident_get(to_idents, i->str); + char *p = i->str; + Identifier new_ident = ident_insert(to_idents, &p); return new_ident; } diff --git a/main.c b/main.c index 8baf641..fe09cf1 100644 --- a/main.c +++ b/main.c @@ -20,6 +20,7 @@ TODO: namespace make sure #export still works properly +check for leaks constants in structs #if diff --git a/parse.c b/parse.c index 99489be..0235ace 100644 --- a/parse.c +++ b/parse.c @@ -1055,6 +1055,8 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { } case KW_NMS: { Namespace *n = &e->nms; + idents_create(&n->idents); + e->kind = EXPR_NMS; ++t->token; if (!parse_block(p, &n->body)) @@ -1064,6 +1066,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { 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; } diff --git a/test.toc b/test.toc index f511440..2c5d7e7 100644 --- a/test.toc +++ b/test.toc @@ -1,8 +1,9 @@ foo ::= nms { -bar ::= 12; +bar := 12; }; yep :: Namespace = nms { -bar ::= 12; +bar := 12; +adfasdf ::= fn() {}; }; diff --git a/types.c b/types.c index bbed29c..b911ca9 100644 --- a/types.c +++ b/types.c @@ -4,7 +4,6 @@ You should have received a copy of the GNU General Public License along with toc. If not, see . */ static bool types_stmt(Typer *tr, Statement *s); -static bool types_block(Typer *tr, Block *b); static bool type_resolve(Typer *tr, Type *t, Location where); @@ -769,7 +768,7 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) { goto ret; } entered_fn = true; - if (!types_block(tr, &f->body)) { + if (!types_block(tr, &f->body, 0)) { success = false; goto ret; } @@ -1204,7 +1203,7 @@ static bool types_expr(Typer *tr, Expression *e) { arr_remove_lasta(&tr->in_expr_decls, tr->allocr); - if (!types_block(tr, &fo->body)) return false; + if (!types_block(tr, &fo->body, 0)) return false; for_exit(e); if (fo->body.ret_expr) { @@ -1262,7 +1261,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)) + if (!types_block(tr, &curr->body, 0)) return false; if (curr->body.ret_expr) { *t = curr->body.ret_expr->type; @@ -1287,7 +1286,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)) { + if (!types_block(tr, &nexti->body, 0)) { return false; } if (nexti->body.ret_expr) { @@ -1322,7 +1321,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)) + if (!types_block(tr, &w->body, 0)) ret = false; if (!ret) return false; if (w->cond != NULL && w->body.ret_expr != NULL) { @@ -1691,7 +1690,7 @@ static bool types_expr(Typer *tr, Expression *e) { } break; case EXPR_BLOCK: { Block *b = &e->block; - if (!types_block(tr, b)) + if (!types_block(tr, b, 0)) return false; if (b->ret_expr) { *t = b->ret_expr->type; @@ -2125,7 +2124,7 @@ static bool types_expr(Typer *tr, Expression *e) { t->builtin = BUILTIN_TYPE; break; case EXPR_NMS: { - if (!types_block(tr, &e->nms.body)) + if (!types_block(tr, &e->nms.body, TYPES_BLOCK_NAMESPACE)) return false; t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_NMS; @@ -2152,7 +2151,8 @@ static void typer_block_exit(Typer *tr) { tr->block = *(Block **)arr_last(tr->blocks); } -static bool types_block(Typer *tr, Block *b) { + +static bool types_block(Typer *tr, Block *b, U16 flags) { if (b->flags & BLOCK_FOUND_TYPES) return true; bool success = true; @@ -2190,7 +2190,13 @@ static bool types_block(Typer *tr, Block *b) { } ret: - typer_block_exit(tr); + 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); + } b->flags |= BLOCK_FOUND_TYPES; return success; } diff --git a/types.h b/types.h index f499ef8..7f9328a 100644 --- a/types.h +++ b/types.h @@ -194,7 +194,7 @@ typedef struct IdentSlot { IdentDecl *decls; /* array of declarations of this identifier */ } IdentSlot; -typedef struct { +typedef struct StrHashTableSlot { const char *str; size_t len; MaxAlign data[]; @@ -202,7 +202,7 @@ typedef struct { typedef StrHashTableSlot *StrHashTableSlotPtr; -typedef struct { +typedef struct StrHashTable { StrHashTableSlot **slots; Allocator *allocr; U32 rand_seed; @@ -697,6 +697,7 @@ const char *const builtin_val_names[BUILTIN_VAL_COUNT] = typedef struct Namespace { Block body; + Identifiers idents; /* these do not include local variables */ } Namespace; enum { -- cgit v1.2.3