diff options
-rw-r--r-- | cgen.c | 95 | ||||
-rw-r--r-- | decls_cgen.c | 7 | ||||
-rw-r--r-- | eval.c | 16 | ||||
-rw-r--r-- | identifiers.c | 30 | ||||
-rw-r--r-- | infer.c | 14 | ||||
-rw-r--r-- | main.c | 21 | ||||
-rw-r--r-- | parse.c | 11 | ||||
-rw-r--r-- | sdecls_cgen.c | 4 | ||||
-rw-r--r-- | types.c | 88 | ||||
-rw-r--r-- | types.h | 1 |
10 files changed, 87 insertions, 200 deletions
@@ -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; } @@ -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 @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; |