summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-31 22:00:34 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-31 22:00:34 -0500
commit6ecf77104d061b2035d490c23e45cc5b1a1a0235 (patch)
tree49424b97f7a9833ed2e04e624647b533acbdd834
parente199ae0b9b213f3549398711a793a7f5232da132 (diff)
more namespaces
-rw-r--r--data_structures.c2
-rw-r--r--eval.c8
-rw-r--r--identifiers.c10
-rw-r--r--main.c1
-rw-r--r--parse.c6
-rw-r--r--test.toc5
-rw-r--r--types.c26
-rw-r--r--types.h5
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[];
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 <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;
}
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 <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;
}
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 {