summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-04 17:51:40 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-04 17:51:40 -0500
commit3350b49826dcdf046835ec70a954122e1c21855d (patch)
tree045a06abedb4af1878cd9f3f72d96c8cc4aff032
parentd2b60a4be9e6b2172a267c6a9554567f1c54211a (diff)
more namespaces
-rw-r--r--cgen.c1
-rw-r--r--eval.c7
-rw-r--r--identifiers.c1
-rw-r--r--parse.c13
-rw-r--r--scope.c8
-rw-r--r--test.toc14
-rw-r--r--types.c69
-rw-r--r--types.h2
8 files changed, 63 insertions, 52 deletions
diff --git a/cgen.c b/cgen.c
index 41d156c..57d9d9d 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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);
diff --git a/eval.c b/eval.c
index a70a1f8..58fff10 100644
--- a/eval.c
+++ b/eval.c
@@ -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 */
diff --git a/parse.c b/parse.c
index 390624c..eac681b 100644
--- a/parse.c
+++ b/parse.c
@@ -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_;
diff --git a/scope.c b/scope.c
index 1f3f687..ed70875 100644
--- a/scope.c
+++ b/scope.c
@@ -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;
diff --git a/test.toc b/test.toc
index 7c662e0..fffb4e4 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
};
diff --git a/types.c b/types.c
index 1bc9d5d..73c0da0 100644
--- a/types.c
+++ b/types.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;
}
diff --git a/types.h b/types.h
index a9d7a2f..158fd04 100644
--- a/types.h
+++ b/types.h
@@ -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;