diff options
-rw-r--r-- | data_structures.c | 2 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rw-r--r-- | identifiers.c | 10 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | parse.c | 6 | ||||
-rw-r--r-- | test.toc | 5 | ||||
-rw-r--r-- | types.c | 26 | ||||
-rw-r--r-- | 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 <http://unlicense.org/> */ /* OPTIM: is it faster to store void *end? */ -typedef struct { +typedef struct ArrHeader { size_t len; size_t cap; MaxAlign data[]; @@ -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 <https://www.gnu.org/licenses/>. */ -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; } @@ -20,6 +20,7 @@ TODO: namespace make sure #export still works properly +check for leaks constants in structs #if @@ -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; } @@ -1,8 +1,9 @@ foo ::= nms { -bar ::= 12; +bar := 12; }; yep :: Namespace = nms { -bar ::= 12; +bar := 12; +adfasdf ::= fn() {}; }; @@ -4,7 +4,6 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ 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; } @@ -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 { |