summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-06 11:15:32 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-06 11:15:32 -0500
commitc9bdc5bc684dab3b5d3739b80855be03517d0cd6 (patch)
tree432a40a01437d1efd0fe20046085cef5cab7b3c2
parent2dda92f6daf61345fcfc9f482e6725bc5d456c9b (diff)
more work on new ident system; not quite working yet
-rw-r--r--cgen.c95
-rw-r--r--decls_cgen.c7
-rw-r--r--eval.c16
-rw-r--r--identifiers.c30
-rw-r--r--infer.c14
-rw-r--r--main.c21
-rw-r--r--parse.c11
-rw-r--r--sdecls_cgen.c4
-rw-r--r--types.c88
-rw-r--r--types.h1
10 files changed, 87 insertions, 200 deletions
diff --git a/cgen.c b/cgen.c
index b2cb042..fa1fa2a 100644
--- a/cgen.c
+++ b/cgen.c
@@ -10,7 +10,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e
g->evalr = ev;
g->will_indent = true;
g->indent_lvl = 0;
- g->idents = ids;
+ g->globals = ids;
g->allocr = allocr;
g->nms_prefix = NULL;
*(char *)arr_add(&g->nms_prefix) = '\0';
@@ -18,8 +18,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e
static bool cgen_stmt(CGenerator *g, Statement *s);
enum {
- CGEN_BLOCK_NOENTER = 0x01, /* should cgen_block actually enter and exit the block? */
- CGEN_BLOCK_NOBRACES = 0x02, /* should it use braces? */
+ CGEN_BLOCK_NOBRACES = 0x01 /* should it use braces? */
};
static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, uint16_t flags);
static bool cgen_expr_pre(CGenerator *g, Expression *e);
@@ -36,7 +35,6 @@ static bool cgen_defs_block(CGenerator *g, Block *b);
static bool cgen_defs_decl(CGenerator *g, Declaration *d);
#define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \
- if (!fn_enter(fn, 0)) return false; \
FnExpr *prev_fn = g->f##n; \
g->f##n = fn; \
arr_foreach(fn->params, Declaration, param) \
@@ -47,7 +45,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
return false; \
if (!block_f(g, &fn->body)) \
return false; \
- fn_exit(fn); \
g->f##n = prev_fn;
/* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */
@@ -116,7 +113,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
break; \
case EXPR_FOR: { \
ForExpr *fo = e->for_; \
- if (!for_enter(e)) return false; \
if (fo->flags & FOR_IS_RANGE) { \
if (!f(g, fo->range.from)) \
return false; \
@@ -128,7 +124,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
return false; \
} \
if (!block_f(g, &fo->body)) return false; \
- for_exit(e); \
} break; \
case EXPR_TUPLE: \
arr_foreach(e->tuple, Expression, x) \
@@ -200,34 +195,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d);
-static bool cgen_block_enter(CGenerator *g, Block *b) {
- g->block = b;
- if (b->flags & BLOCK_IS_NMS) {
- return true;
- }
- Statement *stmts;
- if (b == NULL) {
- stmts = g->file->stmts;
- } else {
- stmts = b->stmts;
- }
- if (b) ++g->indent_lvl;
- return block_enter(b, stmts, 0);
-}
-
-static void cgen_block_exit(CGenerator *g, Block *into) {
- Block *b = g->block;
- Statement *stmts;
- if (b == NULL) {
- stmts = g->file->stmts;
- } else {
- stmts = b->stmts;
- }
- block_exit(b, stmts);
- if (b) --g->indent_lvl;
- g->block = into;
-}
-
static inline FILE *cgen_writing_to(CGenerator *g) {
return g->outc; /* for now */
}
@@ -275,12 +242,11 @@ static void cgen_ident(CGenerator *g, Identifier i) {
cgen_write(g, "%s", g->nms_prefix);
} else {
/* do prefix for references to siblings */
- IdentDecl *idecl = ident_decl(i);
- if (g->nms && idecl->scope == &g->nms->body) {
+ if (g->nms && i->scope == &g->nms->body) {
cgen_write(g, "%s", g->nms_prefix);
}
}
- if (i == g->main_ident && ident_decl(i) && ident_decl(i)->scope == NULL) {
+ if (i == g->main_ident && i->decl_kind == IDECL_DECL && i->scope == NULL) {
/* don't conflict with C's main! */
cgen_write(g, "main__");
} else {
@@ -368,12 +334,6 @@ static bool cgen_uses_ptr(Type *t) {
return false;
}
-static inline Identifier cgen_ident_id_to_ident(CGenerator *g, IdentID id) {
- char s[32];
- cgen_ident_id_to_str(s, id);
- return ident_get(g->idents, s);
-}
-
static bool cgen_type_pre(CGenerator *g, Type *t, Location where) {
assert(t->flags & TYPE_IS_RESOLVED);
switch (t->kind) {
@@ -912,7 +872,6 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
}
fo->c.id = id;
- if (!for_enter(e)) return false;
cgen_write(g, "{");
if (is_range) {
if (fo->range.to) {
@@ -1087,7 +1046,6 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
if (!cgen_block(g, &fo->body, ret_name, CGEN_BLOCK_NOBRACES))
return false;
cgen_write(g, "}}");
- for_exit(e);
} break;
case EXPR_BLOCK:
e->block_ret_id = id;
@@ -1329,12 +1287,12 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
bool handled = false;
if (e->type.kind == TYPE_FN) {
/* generate the right function name, because it might be anonymous */
- IdentDecl *idecl = ident_decl(e->ident);
- if (idecl && idecl->kind == IDECL_DECL) {
- Declaration *d = idecl->decl;
+ Identifier i = e->ident;
+ if (i->decl_kind == IDECL_DECL) {
+ Declaration *d = i->decl;
if (d->flags & DECL_IS_CONST) {
if (!(d->flags & DECL_FOREIGN) || d->foreign.lib) {
- int index = decl_ident_index(d, e->ident);
+ int index = decl_ident_index(d, i);
Value fn_val = *decl_val_at_index(d, index);
FnExpr *fn = fn_val.fn;
Expression fn_expr;
@@ -1671,31 +1629,25 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
at least.
*/
static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, U16 flags) {
- Block *prev = g->block;
if (!(flags & CGEN_BLOCK_NOBRACES)) {
cgen_write(g, "{");
cgen_nl(g);
}
- if (!(flags & CGEN_BLOCK_NOENTER))
- if (!cgen_block_enter(g, b))
- return false;
arr_foreach(b->stmts, Statement, s)
if (!cgen_stmt(g, s))
- return false;
+ return false;
if (b->ret_expr && ret_name) {
if (!cgen_expr_pre(g, b->ret_expr))
- return false;
+ return false;
if (b->ret_expr->type.kind == TYPE_TUPLE) {
if (!cgen_set_tuple(g, NULL, NULL, ret_name, b->ret_expr))
- return false;
+ return false;
} else {
if (!cgen_set(g, NULL, ret_name, b->ret_expr, NULL))
- return false;
+ return false;
}
cgen_nl(g);
}
- if (!(flags & CGEN_BLOCK_NOENTER))
- cgen_block_exit(g, prev);
if (!(flags & CGEN_BLOCK_NOBRACES))
cgen_write(g, "}");
return true;
@@ -1731,11 +1683,9 @@ static void cgen_zero_value(CGenerator *g, Type *t) {
static bool cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_args) {
/* see also cgen_defs_expr */
FnExpr *prev_fn = g->fn;
- Block *prev_block = g->block;
U64 which_are_const = compile_time_args ? compile_time_args->u64 : 0;
if (!cgen_should_gen_fn(f))
return true;
- fn_enter(f, 0);
if (!cgen_fn_header(g, f, instance, which_are_const))
return false;
g->fn = f;
@@ -1781,8 +1731,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_
return false;
}
- if (!cgen_block_enter(g, &f->body)) return false;
- if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOENTER | CGEN_BLOCK_NOBRACES))
+ if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOBRACES))
return false;
if (f->ret_decls) {
/* OPTIM */
@@ -1818,10 +1767,8 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_
} else if (f->body.ret_expr) {
if (!cgen_ret(g, f->body.ret_expr)) return false;
}
- cgen_block_exit(g, prev_block);
cgen_write(g, "}");
- fn_exit(f);
cgen_nl(g);
g->fn = prev_fn;
cgen_nl(g);
@@ -2171,22 +2118,20 @@ static bool cgen_defs_stmt(CGenerator *g, Statement *s) {
}
static bool cgen_defs_block(CGenerator *g, Block *b) {
- Block *prev = g->block;
+ /*
+ NOTE: since we exit as soon as there's an error for cgen, we don't need to make sure we
+ set g->block to the previous block
+ */
g->block = b;
- bool success = true;
arr_foreach(b->stmts, Statement, s) {
if (!cgen_defs_stmt(g, s)) {
- success = false;
- goto ret;
+ return false;
}
}
if (b->ret_expr && !cgen_defs_expr(g, b->ret_expr)) {
- success = false;
- goto ret;
+ return false;
}
- ret:
- g->block = prev;
- return success;
+ return true;
}
static bool cgen_file(CGenerator *g, ParsedFile *f) {
diff --git a/decls_cgen.c b/decls_cgen.c
index 797443d..8e61104 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -44,13 +44,10 @@ static bool cgen_decls_type(CGenerator *g, Type *type) {
static bool cgen_single_fn_decl(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
if (cgen_should_gen_fn(f)) {
- if (!fn_enter(f, 0))
- return false;
if (!cgen_fn_header(g, f, instance, which_are_const))
return false;
cgen_write(g, ";");
cgen_nl(g);
- fn_exit(f);
}
return true;
}
@@ -120,15 +117,11 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
}
static bool cgen_decls_block(CGenerator *g, Block *b) {
- Block *prev = g->block;
- if (!cgen_block_enter(g, b))
- return false;
arr_foreach(b->stmts, Statement, s)
if (!cgen_decls_stmt(g, s))
return false;
if (b->ret_expr && !cgen_decls_expr(g, b->ret_expr))
return false;
- cgen_block_exit(g, prev);
return true;
}
diff --git a/eval.c b/eval.c
index ff17b98..0ce6fb7 100644
--- a/eval.c
+++ b/eval.c
@@ -9,8 +9,6 @@ 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);
static bool eval_expr(Evaluator *ev, Expression *e, Value *v);
-static bool block_enter(Block *b, Statement *stmts, U16 flags);
-static void block_exit(Block *b, Statement *stmts);
static Value get_builtin_val(BuiltinVal val);
static void evalr_create(Evaluator *ev, Typer *tr, Allocator *allocr) {
@@ -1522,7 +1520,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
}
if (!eval_block(ev, &fn->body, &e->type, v)) {
- fn_exit(fn);
return false;
}
if (fn->ret_decls) {
@@ -1558,7 +1555,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
*v = ev->ret_val;
ev->returning = false;
}
- fn_exit(fn);
} break;
case EXPR_SLICE: {
SliceExpr *s = &e->slice;
@@ -1638,18 +1634,18 @@ static bool eval_decl(Evaluator *ev, Declaration *d) {
if (!is_const) {
int index = 0;
- arr_foreach(d->idents, Identifier, i) {
- IdentDecl *id = ident_decl(*i);
+ arr_foreach(d->idents, Identifier, ip) {
+ Identifier i = *ip;
Type *type = decl_type_at_index(d, index);
if (!is_const) {
if (has_expr) {
- copy_val(NULL, &id->val, &val, type);
+ copy_val(NULL, &i->val, &val, type);
} else {
- id->val = val_zero(type);
+ i->val = val_zero(type);
}
}
++index;
- id->flags |= IDECL_HAS_VAL;
+ i->flags |= IDENT_HAS_VAL;
}
}
return true;
@@ -1684,7 +1680,6 @@ static bool eval_stmt(Evaluator *ev, Statement *stmt) {
static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v) {
void **prev_to_free = ev->to_free;
ev->to_free = NULL;
- block_enter(b, b->stmts, 0);
arr_foreach(b->stmts, Statement, stmt) {
if (!eval_stmt(ev, stmt))
return false;
@@ -1700,7 +1695,6 @@ static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v) {
if (free_ptr)
*(void **)arr_add(&prev_to_free) = free_ptr;
}
- block_exit(b, b->stmts);
typedef void *VoidPtr;
arr_foreach(ev->to_free, VoidPtr, f) {
free(*f);
diff --git a/identifiers.c b/identifiers.c
index 229b2ce..1ad239a 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -27,13 +27,13 @@ static int is_ident(int c) {
}
/* Initialize Identifiers. */
-static void idents_create(Identifiers *ids) {
- str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), NULL);
+static void idents_create(Identifiers *ids, Allocator *allocr) {
+ str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), allocr);
ids->rseed = 0x27182818;
}
/* advances s until a non-identifier character is reached, then returns the number of characters advanced */
-static size_t ident_str_len(char **s) {
+static size_t ident_str_len_advance(char **s) {
char *original = *s;
while (is_ident(**s)) {
++*s;
@@ -41,9 +41,13 @@ static size_t ident_str_len(char **s) {
return (size_t)(*s - original);
}
+static size_t ident_str_len(char *s) {
+ return ident_str_len_advance(&s);
+}
+
static U64 ident_hash(char **s) {
char *original = *s;
- return str_hash(original, ident_str_len(s));
+ return str_hash(original, ident_str_len_advance(s));
}
/* are these strings equal, up to the first non-ident character? */
@@ -79,7 +83,7 @@ static IdentSlot **ident_slots_insert(IdentSlot **slots, char *s, size_t i) {
/* advances past identifier */
static Identifier ident_insert(Identifiers *ids, char **s) {
char *original = *s;
- size_t len = ident_str_len(s);
+ size_t len = ident_str_len_advance(s);
IdentSlot *slot = (IdentSlot *)str_hash_table_insert_(&ids->table, original, len);
return slot;
}
@@ -108,8 +112,7 @@ static char *ident_to_str(Identifier i) {
static inline void fprint_ident_str(FILE *out, char *s) {
- char *p = s;
- fwrite(s, 1, ident_str_len(&p), out);
+ fwrite(s, 1, ident_str_len(s), out);
}
static void fprint_ident(FILE *out, Identifier id) {
@@ -140,8 +143,7 @@ static void fprint_ident_reduced_charset(FILE *out, Identifier id) {
/* NULL = no such identifier. returns identifier "foo" for both "foo\0" and "foo+92384324..." */
static Identifier ident_get(Identifiers *ids, char *s) {
- char *ptr = s;
- size_t len = ident_str_len(&ptr);
+ size_t len = ident_str_len(s);
return (Identifier)str_hash_table_get_(&ids->table, s, len);
}
@@ -161,16 +163,14 @@ static bool ident_eq(Identifier i, Identifier j) {
return i->len == j->len && memcmp(i->str, j->str, i->len) == 0;
}
-static void idents_free(Identifiers *ids) {
- str_hash_table_free(&ids->table);
-}
-
#ifdef TOC_DEBUG
static void idents_test(void) {
Identifiers ids;
char b[] = "foo_variable bar";
char *s = b;
- idents_create(&ids);
+ Allocator a;
+ allocr_create(&a);
+ idents_create(&ids, &a);
Identifier i1 = ident_insert(&ids, &s);
assert(strs_equal(s, " bar"));
char b2[] = "foo_variable+6";
@@ -178,8 +178,8 @@ static void idents_test(void) {
Identifier i2 = ident_insert(&ids, &s);
assert(strs_equal(s, "+6"));
assert(i1 == i2);
+ allocr_free_all(&a);
- idents_free(&ids);
}
#endif
diff --git a/infer.c b/infer.c
index f577988..2a47865 100644
--- a/infer.c
+++ b/infer.c
@@ -24,10 +24,10 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres
break;
case EXPR_CALL: {
while (to->kind == EXPR_IDENT) {
- IdentDecl *idecl = ident_decl(to->ident);
- if (idecl->kind == IDECL_DECL) {
- Declaration *decl = idecl->decl;
- int index = ident_index_in_decl(to->ident, decl);
+ Identifier i = to->ident;
+ if (i->decl_kind == IDECL_DECL) {
+ Declaration *decl = i->decl;
+ int index = ident_index_in_decl(i, decl);
Expression *expr = NULL;
if (decl->type.kind == TYPE_TUPLE) {
if (decl->expr.kind == EXPR_TUPLE) {
@@ -46,12 +46,12 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres
U16 *order = NULL;
Expression *f = match->call.fn;
- IdentDecl *idecl = ident_decl(f->ident);
- bool is_direct_fn = idecl && idecl->kind == IDECL_DECL && (idecl->decl->flags & DECL_HAS_EXPR) && idecl->decl->expr.kind == EXPR_FN;
+ Identifier ident = f->ident;
+ bool is_direct_fn = f->kind == EXPR_IDENT && ident->decl_kind == IDECL_DECL && (ident->decl->flags & DECL_HAS_EXPR) && ident->decl->expr.kind == EXPR_FN;
if (is_direct_fn) {
if (!types_expr(tr, f))
return false;
- FnExpr *fn_decl = idecl->decl->expr.fn;
+ FnExpr *fn_decl = ident->decl->expr.fn;
if (!call_arg_param_order(tr->allocr, fn_decl, &f->type, m_args, match->where, &order))
return false;
}
diff --git a/main.c b/main.c
index 91b447e..6563a0d 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,6 @@
/*
TODO:
-try to remember why arr_set_len doesn't shrink, then write that reason there
make eval_ptr_to_struct_field return a bool (just in case it successfully returns a NULL pointer)
nms["foo"]
make sure #export still works properly
@@ -81,11 +80,11 @@ int main(int argc, char **argv) {
char *contents = read_file_contents(&main_allocr, in_filename, file_where);
if (!contents) return EXIT_FAILURE;
- Identifiers idents;
- idents_create(&idents);
+ Identifiers globals;
+ idents_create(&globals, &main_allocr);
Tokenizer t;
file.contents = contents;
- tokr_create(&t, &idents, &err_ctx, &main_allocr);
+ tokr_create(&t, &err_ctx, &main_allocr);
if (!tokenize_file(&t, &file)) {
err_text_important(&err_ctx, "Errors occured during preprocessing.\n");
return EXIT_FAILURE;
@@ -101,7 +100,7 @@ int main(int argc, char **argv) {
#endif
Parser p;
- parser_create(&p, &t, &main_allocr);
+ parser_create(&p, &globals, &t, &main_allocr);
ParsedFile f;
if (!parse_file(&p, &f)) {
err_text_important(&err_ctx, "Errors occured during parsing.\n");
@@ -114,11 +113,8 @@ int main(int argc, char **argv) {
Typer tr;
Evaluator ev;
evalr_create(&ev, &tr, &main_allocr);
- typer_create(&tr, &ev, &err_ctx, &main_allocr, &idents);
-
- if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */
- return EXIT_FAILURE;
-
+ typer_create(&tr, &ev, &err_ctx, &main_allocr, &globals);
+
if (!types_file(&tr, &f)) {
/* TODO(eventually): fix this if the error occured while exporting something */
err_text_important(&err_ctx, "Errors occured while determining types.\n");
@@ -135,19 +131,16 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
CGenerator g;
- cgen_create(&g, out, &idents, &ev, &main_allocr);
+ cgen_create(&g, out, &globals, &ev, &main_allocr);
if (!cgen_file(&g, &f)) {
fclose(out);
err_text_important(&err_ctx, "Errors occured while generating C code.\n");
return EXIT_FAILURE;
}
- block_exit(NULL, f.stmts); /* exit global scope */
-
allocr_free_all(&main_allocr);
evalr_free(&ev);
fclose(out);
- idents_free(&idents);
return 0;
}
diff --git a/parse.c b/parse.c
index 092675d..db2dbec 100644
--- a/parse.c
+++ b/parse.c
@@ -784,6 +784,7 @@ static bool parse_block(Parser *p, Block *b) {
Block *prev_block = p->block;
b->flags = 0;
b->ret_expr = NULL;
+ idents_create(&b->idents, p->allocr);
if (!token_is_kw(t->token, KW_LBRACE)) {
tokr_err(t, "Expected '{' to open block.");
return false;
@@ -955,9 +956,8 @@ static int op_precedence(Keyword op) {
}
static Identifier parser_ident_insert(Parser *p, char *str) {
- /* TODO TODO TODO NOW */
- (void)p;
- return NULL;
+ Identifiers *idents = p->block ? &p->block->idents : p->globals;
+ return ident_insert(idents, &str);
}
static bool parse_expr(Parser *p, Expression *e, Token *end) {
@@ -1065,7 +1065,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
case KW_NMS: {
Namespace *n = &e->nms;
- idents_create(&n->idents);
+ idents_create(&n->idents, p->allocr);
e->kind = EXPR_NMS;
++t->token;
@@ -2101,9 +2101,10 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
return true;
}
-static void parser_create(Parser *p, Tokenizer *t, Allocator *allocr) {
+static void parser_create(Parser *p, Identifiers *globals, Tokenizer *t, Allocator *allocr) {
p->tokr = t;
p->block = NULL;
+ p->globals = globals;
p->allocr = allocr;
}
diff --git a/sdecls_cgen.c b/sdecls_cgen.c
index 3a35087..529041a 100644
--- a/sdecls_cgen.c
+++ b/sdecls_cgen.c
@@ -37,15 +37,11 @@ static bool cgen_sdecls_type(CGenerator *g, Type *type) {
}
static bool cgen_sdecls_block(CGenerator *g, Block *b) {
- Block *prev = g->block;
- if (!cgen_block_enter(g, b))
- return false;
arr_foreach(b->stmts, Statement, s)
if (!cgen_sdecls_stmt(g, s))
return false;
if (b->ret_expr && !cgen_sdecls_expr(g, b->ret_expr))
return false;
- cgen_block_exit(g, prev);
return true;
}
diff --git a/types.c b/types.c
index cd5b688..07d9cf8 100644
--- a/types.c
+++ b/types.c
@@ -108,12 +108,11 @@ static bool expr_must_lval(Expression *e) {
/* NOTE: make sure you update eval when you change this */
switch (e->kind) {
case EXPR_IDENT: {
- IdentDecl *id_decl = ident_decl(e->ident);
- assert(id_decl);
- if (id_decl->kind == IDECL_DECL) {
- Declaration *d = id_decl->decl;
+ Identifier i = e->ident;
+ if (i->decl_kind == IDECL_DECL) {
+ Declaration *d = i->decl;
if (d->flags & DECL_IS_CONST) {
- char *istr = ident_to_str(e->ident);
+ char *istr = ident_to_str(i);
err_print(e->where, "Use of constant %s as a non-constant expression.", istr);
info_print(d->where, "%s was declared here.", istr);
return false;
@@ -239,8 +238,6 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
size_t idx = 0;
bool has_constant_params = false;
Type *ret_type = typer_arr_add(tr, &t->fn.types);
- if (!fn_enter(f, SCOPE_CHECK_REDECL))
- return false;
tr->fn = f;
size_t nparams = arr_len(f->params);
entered_fn = true;
@@ -363,7 +360,6 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
tr->block = prev_block;
/* cleanup */
if (entered_fn) {
- fn_exit(f);
tr->fn = prev_fn;
}
return success;
@@ -371,19 +367,12 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
t->flags = 0;
- IdentDecl *decl = ident_decl(i);
- if (!decl) {
- char *s = ident_to_str(i);
- err_print(where, "Undeclared identifier: %s", s);
- free(s);
- return false;
- }
- switch (decl->kind) {
+ switch (i->decl_kind) {
case IDECL_DECL: {
- Declaration *d = decl->decl;
+ Declaration *d = i->decl;
bool captured = false;
- if (decl->scope != NULL && !(decl->scope->flags & BLOCK_IS_NMS)) {
- Block *decl_scope = decl->scope;
+ if (i->scope != NULL && !(i->scope->flags & BLOCK_IS_NMS)) {
+ Block *decl_scope = i->scope;
if (!(decl_scope->flags & BLOCK_IS_NMS)) {
/* go back through scopes */
for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) {
@@ -451,7 +440,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
}
} break;
case IDECL_EXPR: {
- Expression *e = decl->expr;
+ Expression *e = i->expr;
/* are we inside this expression? */
typedef Expression *ExpressionPtr;
arr_foreach(tr->in_expr_decls, ExpressionPtr, in_e) {
@@ -462,7 +451,6 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
return false;
}
}
-
switch (e->kind) {
case EXPR_FOR:
if (i == e->for_->index) {
@@ -476,6 +464,12 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
default: assert(0); return false;
}
} break;
+ case IDECL_NONE: {
+ char *s = ident_to_str(i);
+ err_print(where, "Undeclared identifier: %s", s);
+ free(s);
+ return false;
+ }
}
return true;
}
@@ -753,7 +747,6 @@ static bool arg_is_const(Expression *arg, Constness constness) {
static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) {
FnExpr *prev_fn = tr->fn;
bool success = true;
- bool entered_fn = false;
Expression *ret_expr;
Type *ret_type;
bool has_named_ret_vals;
@@ -766,11 +759,6 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) {
}
tr->fn = f;
- if (!fn_enter(f, SCOPE_CHECK_REDECL)) {
- success = false;
- goto ret;
- }
- entered_fn = true;
if (!types_block(tr, &f->body)) {
success = false;
goto ret;
@@ -813,8 +801,6 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) {
goto ret;
}
ret:
- if (entered_fn)
- fn_exit(f);
tr->fn = prev_fn;
return success;
}
@@ -862,7 +848,7 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, A
bool found = false;
arr_foreach(fn->params, Declaration, pa) {
arr_foreach(pa->idents, Identifier, id) {
- if (ident_eq(*id, arg->name)) {
+ if (ident_eq_str(*id, arg->name)) {
found = true;
break;
}
@@ -871,9 +857,12 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, A
if (found) break;
}
if (!found) {
- char *s = ident_to_str(arg->name);
- err_print(arg->where, "Argument '%s' does not appear in declaration of function.", s);
- free(s);
+ char *name_end = arg->name + ident_str_len(arg->name);
+ /* temporarily null-terminate string to print it out */
+ char before = *name_end;
+ *name_end = 0;
+ err_print(arg->where, "Argument '%s' does not appear in declaration of function.", arg->name);
+ *name_end = before;
info_print(fn->where, "Declaration is here.");
return false;
}
@@ -1114,7 +1103,6 @@ static bool types_expr(Typer *tr, Expression *e) {
case EXPR_FOR: {
ForExpr *fo = e->for_;
*(Expression **)typer_arr_add(tr, &tr->in_expr_decls) = e;
- if (!for_enter(e)) return false;
if (fo->flags & FOR_IS_RANGE) {
/* TODO: allow user-defined numerical types */
if (!types_expr(tr, fo->range.from)) return false;
@@ -1233,7 +1221,6 @@ 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;
- for_exit(e);
if (fo->body.ret_expr) {
*t = fo->body.ret_expr->type;
@@ -2162,8 +2149,6 @@ static bool types_expr(Typer *tr, Expression *e) {
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);
@@ -2173,27 +2158,10 @@ static bool types_expr(Typer *tr, Expression *e) {
return true;
}
-static bool typer_block_enter(Typer *tr, Block *b) {
- tr->block = b;
- *(Block **)arr_adda(&tr->blocks, tr->allocr) = b;
- if (!block_enter(b, b->stmts, SCOPE_CHECK_REDECL)) return false;
- return true;
-}
-
-static void typer_block_exit(Typer *tr) {
- Block *b = tr->block;
- block_exit(b, b->stmts);
- arr_remove_last(&tr->blocks);
- tr->block = *(Block **)arr_last(tr->blocks);
-}
-
-
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;
arr_foreach(b->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
success = false;
@@ -2225,7 +2193,6 @@ static bool types_block(Typer *tr, Block *b) {
}
ret:
- typer_block_exit(tr);
b->flags |= BLOCK_FOUND_TYPES;
return success;
}
@@ -2450,7 +2417,7 @@ static bool types_stmt(Typer *tr, Statement *s) {
if (!contents)
return false;
Tokenizer tokr;
- tokr_create(&tokr, tr->idents, tr->err_ctx, tr->allocr);
+ tokr_create(&tokr, tr->err_ctx, tr->allocr);
File *file = typer_calloc(tr, 1, sizeof *file);
file->filename = filename;
file->contents = contents;
@@ -2458,7 +2425,8 @@ static bool types_stmt(Typer *tr, Statement *s) {
if (!tokenize_file(&tokr, file))
return false;
Parser parser;
- parser_create(&parser, &tokr, tr->allocr);
+ parser_create(&parser, tr->globals, &tokr, tr->allocr);
+ parser.block = tr->block;
ParsedFile parsed_file;
if (!parse_file(&parser, &parsed_file)) {
return false;
@@ -2468,10 +2436,6 @@ static bool types_stmt(Typer *tr, Statement *s) {
arr_foreach(stmts_inc, Statement, s_incd) {
if (!types_stmt(tr, s_incd))
return false;
- if (s_incd->kind == STMT_DECL) {
- if (!add_ident_decls(tr->block, &s_incd->decl, SCOPE_CHECK_REDECL))
- return false;
- }
}
} break;
}
@@ -2488,7 +2452,7 @@ static void typer_create(Typer *tr, Evaluator *ev, ErrCtx *err_ctx, Allocator *a
tr->in_decls = NULL;
tr->in_expr_decls = NULL;
tr->allocr = allocr;
- tr->idents = idents;
+ tr->globals = idents;
tr->is_reference_stack = NULL;
*(Block **)arr_adda(&tr->blocks, allocr) = NULL;
}
diff --git a/types.h b/types.h
index 0667549..67c0645 100644
--- a/types.h
+++ b/types.h
@@ -855,6 +855,7 @@ typedef struct ParsedFile {
typedef struct Parser {
Tokenizer *tokr;
Allocator *allocr;
+ Identifiers *globals;
File *file;
Block *block; /* which block are we in? NULL = file scope */
ParsedFile *parsed_file;