summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-04 15:51:21 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-04 15:51:21 -0400
commit6cf714ba462b691135e21146f817f88e5a991b05 (patch)
treef936710a08ea307c7db351e6096861560c5963a0
parent4b0246b6ca0434817f5dd8763cc5336120d6e0f0 (diff)
fixed namespace problem
-rw-r--r--cgen.c21
-rw-r--r--decls_cgen.c3
-rw-r--r--parse.c1
-rw-r--r--test.toc2
-rw-r--r--types.c94
5 files changed, 61 insertions, 60 deletions
diff --git a/cgen.c b/cgen.c
index 8fb7468..e7ce012 100644
--- a/cgen.c
+++ b/cgen.c
@@ -39,13 +39,16 @@ static void cgen_defs_decl(CGenerator *g, Declaration *d);
#define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \
if (!(fn->flags & FN_EXPR_FOREIGN)) { \
FnExpr *prev_fn = g->f##n; \
+ Block *prev_block = g->block; \
g->f##n = fn; \
- arr_foreach(fn->params, Declaration, param) \
+ g->block = &fn->body; \
+ arr_foreach(fn->params, Declaration, param) \
decl_f(g, param); \
arr_foreach(fn->ret_decls, Declaration, r) \
decl_f(g, r); \
block_f(g, &fn->body); \
g->f##n = prev_fn; \
+ g->block = prev_block; \
}
/* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */
@@ -256,7 +259,7 @@ static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) {
/* should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) */
static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) {
- return g->fn == NULL && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1;
+ return (!g->block || g->block->kind == BLOCK_NMS) && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1;
}
static bool fn_has_instances(FnExpr *f) {
@@ -1812,12 +1815,14 @@ static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) {
if (f->flags & FN_EXPR_FOREIGN)
return; /* handled by decls_cgen */
/* see also cgen_defs_expr */
- FnExpr *prev_fn = g->fn;
U64 which_are_const = compile_time_args ? compile_time_args->u64 : 0;
if (!cgen_should_gen_fn(f))
return;
- cgen_fn_header(g, f, which_are_const);
+ FnExpr *prev_fn = g->fn;
+ Block *prev_block = g->block;
g->fn = f;
+ g->block = &f->body;
+ cgen_fn_header(g, f, which_are_const);
cgen_write(g, " {");
cgen_nl(g);
if (compile_time_args) {
@@ -1874,20 +1879,16 @@ static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) {
}
cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOBRACES);
- Block *prev = g->block;
- g->block = &f->body;
- /* cgen_ret needs to think it's in the function body */
cgen_ret(g, &f->body, f->body.ret_expr);
- g->block = prev;
cgen_writeln(g, "}");
-
+ g->block = prev_block;
g->fn = prev_fn;
cgen_nl(g);
cgen_nl(g);
}
static void cgen_decl(CGenerator *g, Declaration *d) {
- if (g->block == NULL && g->fn == NULL)
+ if (!g->block || (g->block->kind == BLOCK_NMS))
return; /* already dealt with */
int has_expr = d->flags & DECL_HAS_EXPR;
if (cgen_fn_is_direct(g, d))
diff --git a/decls_cgen.c b/decls_cgen.c
index 5b4467b..78f51a3 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -340,7 +340,7 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) {
if (d->flags & DECL_HAS_EXPR) {
cgen_decls_expr(g, &d->expr);
}
- if (g->fn == NULL) {
+ if (!g->block || g->block->kind == BLOCK_NMS) {
/* global variables */
for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) {
Identifier ident = d->idents[i];
@@ -353,6 +353,7 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) {
cgen_ident(g, ident);
cgen_type_post(g, type);
if (d->flags & DECL_HAS_EXPR) {
+ assert(d->flags & DECL_FOUND_VAL);
Value *val = decl_val_at_index(d, i);
cgen_write(g, " = ");
cgen_val(g, val, type);
diff --git a/parse.c b/parse.c
index 4c81213..bd25189 100644
--- a/parse.c
+++ b/parse.c
@@ -1292,6 +1292,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
++t->token;
if (!parse_block(p, &n->body, 0))
return false;
+ n->body.kind = BLOCK_NMS;
goto success;
}
case KW_IF:
diff --git a/test.toc b/test.toc
index e7bd007..de22166 100644
--- a/test.toc
+++ b/test.toc
@@ -7,5 +7,5 @@ main ::= fn() {
p ::= nms {
y := 5;
}
- puti(p.x);
+ puti(p.y);
}
diff --git a/types.c b/types.c
index e16fd22..9539170 100644
--- a/types.c
+++ b/types.c
@@ -577,47 +577,54 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
}
/* may modify ident */
-static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) {
+enum {
+ TYPE_OF_IDENT_BLOCK_IS_CORRECT = 0x01 /* *ident is already from the right block (it doesn't need translation) */
+};
+static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t, U16 flags) {
t->flags = 0;
Identifier i = *ident;
Block *b = tr->block;
bool undeclared = true;
- while (1) { /* for each block we are inside... */
- /* OPTIM: only hash once */
- Identifier translated = ident_translate(i, b ? &b->idents : tr->globals);
- if (ident_is_declared(translated)) {
+ if (flags & TYPE_OF_IDENT_BLOCK_IS_CORRECT) {
+ undeclared = !ident_is_declared(*ident);
+ } else {
+ while (1) { /* for each block we are inside... */
+ /* OPTIM: only hash once */
+ Identifier translated = ident_translate(i, b ? &b->idents : tr->globals);
+ if (ident_is_declared(translated)) {
#if 0
- printf("translated %s from\n", ident_to_str(i));
- print_block_location(i->idents->body);
- printf(" to \n");
- print_block_location(translated->idents->body);
+ printf("translated %s from\n", ident_to_str(i));
+ print_block_location(i->idents->body);
+ printf(" to \n");
+ print_block_location(translated->idents->body);
#endif
- i = *ident = translated;
- undeclared = false;
- }
- Use **uses = b ? b->uses : tr->uses;
+ i = *ident = translated;
+ undeclared = false;
+ }
+ Use **uses = b ? b->uses : tr->uses;
- Use *previous_use_which_uses_i = NULL;
- (void)previous_use_which_uses_i;
- arr_foreach(uses, UsePtr, usep) {
- Use *use = *usep;
- Expression *e = &use->expr;
- if (type_is_builtin(&e->type, BUILTIN_NMS)) {
-
+ Use *previous_use_which_uses_i = NULL;
+ (void)previous_use_which_uses_i;
+ arr_foreach(uses, UsePtr, usep) {
+ Use *use = *usep;
+ Expression *e = &use->expr;
+ if (type_is_builtin(&e->type, BUILTIN_NMS)) {
+
+ } else {
+ /* it's a struct */
+ Type *struct_type = &e->type;
+ if (struct_type->kind == TYPE_PTR)
+ struct_type = struct_type->ptr;
+ assert(struct_type->kind == TYPE_STRUCT);
+ }
+ }
+ if (!undeclared) break;
+ if (b) {
+ b = b->parent;
} else {
- /* it's a struct */
- Type *struct_type = &e->type;
- if (struct_type->kind == TYPE_PTR)
- struct_type = struct_type->ptr;
- assert(struct_type->kind == TYPE_STRUCT);
+ break;
}
}
- if (!undeclared) break;
- if (b) {
- b = b->parent;
- } else {
- break;
- }
}
if (undeclared) {
char *s = ident_to_str(i);
@@ -699,7 +706,7 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *
}
/* let's type the declaration, and redo this (for evaling future functions) */
if (!types_decl(tr, d)) return false;
- return type_of_ident(tr, where, ident, t);
+ return type_of_ident(tr, where, ident, t, flags);
}
}
}
@@ -725,13 +732,10 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *
*t = fo->type;
}
} break;
- case IDECL_NONE: {
- char *s = ident_to_str(i);
- err_print(where, "Undeclared identifier: %s", s);
- free(s);
+ case IDECL_NONE:
+ assert(0);
return false;
}
- }
return true;
}
@@ -1828,7 +1832,7 @@ static Status types_expr(Typer *tr, Expression *e) {
return false;
};
case EXPR_IDENT: {
- if (!type_of_ident(tr, e->where, &e->ident, t)) return false;
+ if (!type_of_ident(tr, e->where, &e->ident, t, 0)) return false;
} break;
case EXPR_CAST: {
CastExpr *c = &e->cast;
@@ -2922,7 +2926,7 @@ static Status types_expr(Typer *tr, Expression *e) {
e->binary.op = BINARY_DOT;
e->binary.rhs->kind = EXPR_IDENT;
e->binary.rhs->ident = ident_get_with_len(&nms->body.idents, member_name.slice.data, (size_t)member_name.slice.n);
- if (!type_of_ident(tr, rhs->where, &e->binary.rhs->ident, t)) {
+ if (!type_of_ident(tr, rhs->where, &e->binary.rhs->ident, t, TYPE_OF_IDENT_BLOCK_IS_CORRECT)) {
return false;
}
break;
@@ -3049,13 +3053,10 @@ static Status types_expr(Typer *tr, Expression *e) {
Namespace *nms = nms_val.nms;
lhs->kind = EXPR_VAL;
lhs->val.nms = nms;
- Block *prev = tr->block;
- /* briefly pretend we are in the namespace */
- tr->block = &nms->body;
- if (!type_of_ident(tr, rhs->where, &rhs->ident, t)) {
+ rhs->ident = ident_translate(rhs->ident, &nms->body.idents);
+ if (!type_of_ident(tr, rhs->where, &rhs->ident, t, TYPE_OF_IDENT_BLOCK_IS_CORRECT)) {
return false;
}
- tr->block = prev;
} else {
char *s = type_to_str(lhs_type);
err_print(e->where, "Operator . applied to type %s, which is not a structure or pointer to structure.", s);
@@ -3121,7 +3122,6 @@ static Status types_expr(Typer *tr, Expression *e) {
tr->nms = prev_nms;
return false;
}
- n->body.kind = BLOCK_NMS;
tr->nms = prev_nms;
n->associated_ident = NULL; /* set when we type the declaration which contains this namespace */
t->kind = TYPE_BUILTIN;
@@ -3239,8 +3239,7 @@ static Status types_decl(Typer *tr, Declaration *d) {
d->type = d->expr.type;
d->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; /* x := 5; => x is not flexible */
}
- bool need_value = (d->flags & DECL_IS_CONST) || tr->fn == NULL;
-
+ bool need_value = (d->flags & DECL_IS_CONST) || !tr->block || tr->block->kind == BLOCK_NMS;
if (need_value) {
if (!(d->flags & DECL_FOUND_VAL)) {
Value val;
@@ -3252,7 +3251,6 @@ static Status types_decl(Typer *tr, Declaration *d) {
d->flags |= DECL_FOUND_VAL;
}
}
-
}
for (size_t i = 0; i < arr_len(d->idents); ++i) {