diff options
-rw-r--r-- | location.c | 5 | ||||
-rw-r--r-- | parse.c | 21 | ||||
-rw-r--r-- | test.toc | 24 | ||||
-rw-r--r-- | toc.c | 2 | ||||
-rw-r--r-- | types.c | 78 |
5 files changed, 81 insertions, 49 deletions
@@ -20,13 +20,16 @@ static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_po /* go back to last newline / 0 byte */ while (*line_start != '\0' && *line_start != '\n') --line_start; if (line_start < start) ++line_start; + + /* skip space at start of line */ + while (isspace(*line_start) && line_start < end) + ++line_start; char *line_end = strchr(start, '\n'); int has_newline = line_end != NULL; if (!has_newline) line_end = strchr(start, '\0'); assert(line_end); - fprintf(out, "\t"); if (!line_start[0]) fprintf(out, "<end of file>"); else { @@ -787,15 +787,18 @@ static bool parse_block(Parser *p, Block *b, U8 flags) { Block *prev_block = p->block; b->flags = 0; b->ret_expr = NULL; + p->block = b; if (!(flags & PARSE_BLOCK_DONT_CREATE_IDENTS)) idents_create(&b->idents, p->allocr, p->block); if (!token_is_kw(t->token, KW_LBRACE)) { tokr_err(t, "Expected '{' to open block."); return false; } - p->block = b; b->where = parser_mk_loc(p); b->where.start = t->token; +#ifdef TOC_DEBUG + b->where.end = t->token + 1; +#endif ++t->token; /* move past { */ b->stmts = NULL; bool ret = true; @@ -970,6 +973,7 @@ static int op_precedence(Keyword op) { static Identifier parser_ident_insert(Parser *p, char *str) { Identifiers *idents = p->block ? &p->block->idents : p->globals; Identifier i = ident_insert(idents, &str); + assert(i->idents->scope == p->block); return i; } @@ -2191,8 +2195,19 @@ static void fprint_block(FILE *out, Block *b) { } static void print_block(Block *b) { - fprint_block(stdout, b); - printf("\n"); + if (b) { + fprint_block(stdout, b); + printf("\n"); + } else { + printf("(null block)\n"); + } +} + +static void print_block_location(Block *b) { + if (b) + print_location(b->where); + else + printf("(global scope)\n"); } static void fprint_fn_expr(FILE *out, FnExpr *f) { @@ -1,19 +1,7 @@ - -// it would be nice if Arr.data.len == Arr.len (: but this will require some C code... -Arr ::= fn (t :: Type) Type { - // struct { - // data : []t; - // len, cap : int; - // } - t +getstdin ::= fn(){ + buffer : int; + while true { + while buffer { + } + } }; - -arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { -}; - -main ::= fn() { - arr : Arr(int); - for i := 1..100 { - arr_add(int, &arr, 3); - } -};
\ No newline at end of file @@ -45,6 +45,8 @@ /* forward declarations for debugging */ static void print_val(Value v, Type *t); static void print_token(Token *t); +static void print_block(Block *b); +static void print_block_location(Block *b); /* misc */ @@ -19,6 +19,16 @@ static inline void *typer_arr_add_(Typer *tr, void **arr, size_t sz) { return arr_adda_(arr, sz, tr->allocr); } +static inline void typer_block_enter(Typer *tr, Block *b) { + *(Block **)arr_add(&tr->blocks) = b; + tr->block = b; +} + +static inline void typer_block_exit(Typer *tr) { + arr_remove_last(&tr->blocks); + tr->block = *(Block **)arr_last(tr->blocks); +} + #define typer_arr_add(tr, a) typer_arr_add_(tr, (void **)(a), sizeof **(a)) static bool type_eq(Type *a, Type *b) { @@ -220,18 +230,11 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { FnExpr *prev_fn = tr->fn; FnExpr fn_copy = {0}; - Block *prev_block = tr->block; - /* - fakely enter the body of the function, so that - fn (x : int) y := x {} works - */ - tr->block = &f->body; - *(Block **)arr_adda(&tr->blocks, tr->allocr) = tr->block; /* f has compile time params, but it's not an instance! */ bool generic = !(flags & TYPE_OF_FN_IS_INSTANCE) && fn_has_any_const_params(f); if (generic) { - Copier cop = copier_create(tr->allocr, tr->block); + Copier cop = copier_create(tr->allocr, &f->body); copy_fn_expr(&cop, &fn_copy, f, false); f = &fn_copy; } @@ -239,6 +242,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { bool has_constant_params = false; Type *ret_type = typer_arr_add(tr, &t->fn.types); tr->fn = f; + typer_block_enter(tr, &f->body); size_t nparams = arr_len(f->params); entered_fn = true; for (param_idx = 0; param_idx < nparams; ++param_idx) { @@ -356,9 +360,8 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { *ret_type = f->ret_type; ret: - arr_remove_lasta(&tr->blocks, tr->allocr); - tr->block = prev_block; /* cleanup */ + typer_block_exit(tr); if (entered_fn) { tr->fn = prev_fn; } @@ -369,7 +372,19 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) { t->flags = 0; Identifier i = *ident; +#ifdef TOC_DEBUG + if (i->idents->scope != tr->block) { + printf("Ident declaration mismatch for this ident:\n"); + print_location(where); + printf("Typer is typing:\n"); + print_block_location(tr->block); + printf("But the identifier's scope is:\n"); + print_block_location(i->idents->scope); + abort(); + } +#else assert(i->idents->scope == tr->block); +#endif if (i->decl_kind == IDECL_NONE) { long nblocks = (long)arr_len(tr->blocks); long idx; @@ -379,6 +394,11 @@ static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); if (!translated) continue; if (translated->decl_kind != IDECL_NONE) { + /* printf("translated %s from\n", ident_to_str(i)); */ + /* print_block_location(i->idents->scope); */ + /* printf(" to \n"); */ + /* print_block_location(translated->idents->scope); */ + i = *ident = translated; break; } @@ -1127,9 +1147,10 @@ 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; + typer_block_enter(tr, &fo->body); /* while this block is being typed, fo->body will be in tr->blocks twice. hopefully that doesn't mess anything up! */ if (fo->flags & FOR_IS_RANGE) { /* TODO: allow user-defined numerical types */ - if (!types_expr(tr, fo->range.from)) return false; + if (!types_expr(tr, fo->range.from)) goto for_fail; { Type *ft = &fo->range.from->type; if (ft->kind != TYPE_BUILTIN || !type_builtin_is_numerical(ft->builtin)) { @@ -1139,7 +1160,7 @@ static bool types_expr(Typer *tr, Expression *e) { } } if (fo->range.step) { - if (!types_expr(tr, fo->range.step)) return false; + if (!types_expr(tr, fo->range.step)) goto for_fail; Type *st = &fo->range.step->type; if (st->kind != TYPE_BUILTIN || !type_builtin_is_numerical(st->builtin)) { char *s = type_to_str(st); @@ -1148,7 +1169,7 @@ static bool types_expr(Typer *tr, Expression *e) { } } if (fo->range.to) { - if (!types_expr(tr, fo->range.to)) return false; + if (!types_expr(tr, fo->range.to)) goto for_fail; Type *tt = &fo->range.to->type; if (tt->kind != TYPE_BUILTIN || !type_builtin_is_numerical(tt->builtin)) { char *s = type_to_str(tt); @@ -1166,7 +1187,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *got = type_to_str(&fo->range.from->type); err_print(e->where, "Type of for loop does not match the type of the from expression. Expected %s, but got %s.", exp, got); free(exp); free(got); - return false; + goto for_fail; } if (fo->range.step && !type_eq(&fo->type, &fo->range.step->type)) { @@ -1174,7 +1195,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *got = type_to_str(&fo->range.step->type); err_print(e->where, "Type of for loop does not match the type of the step expression. Expected %s, but got %s.", exp, got); free(exp); free(got); - return false; + goto for_fail; } if ((fo->type.flags & TYPE_IS_FLEXIBLE) && fo->range.step) @@ -1185,7 +1206,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *got = type_to_str(&fo->range.to->type); err_print(e->where, "Type of for loop does not match the type of the to expression. Expected %s, but got %s.", exp, got); free(exp); free(got); - return false; + goto for_fail; } if ((fo->type.flags & TYPE_IS_FLEXIBLE) && fo->range.to) @@ -1193,7 +1214,7 @@ static bool types_expr(Typer *tr, Expression *e) { fo->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; } else { if (!types_expr(tr, fo->of)) - return false; + goto for_fail; Type *iter_type = &fo->of->type; bool uses_ptr = false; @@ -1212,7 +1233,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *s = type_to_str(&fo->of->type); err_print(e->where, "Cannot iterate over non-array non-slice type %s.", s); free(s); - return false; + goto for_fail; } } Type ptr_type = {0}; @@ -1228,7 +1249,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *got = type_to_str(&fo->type); err_print(e->where, "Expected to iterate over type %s, but it was annotated as iterating over type %s."); free(exp); free(got); - return false; + goto for_fail; } } else fo->type = *iter_type; } @@ -1236,7 +1257,7 @@ static bool types_expr(Typer *tr, Expression *e) { Value *stepval = typer_malloc(tr, sizeof *fo->range.stepval); if (!eval_expr(tr->evalr, fo->range.step, stepval)) { info_print(fo->range.step->where, "Note that the step of a for loop must be a compile-time constant."); - return false; + goto for_fail; } val_cast(stepval, &fo->range.step->type, stepval, &fo->type); fo->range.stepval = stepval; @@ -1244,7 +1265,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)) goto for_fail; if (fo->body.ret_expr) { *t = fo->body.ret_expr->type; @@ -1252,7 +1273,12 @@ static bool types_expr(Typer *tr, Expression *e) { t->kind = TYPE_VOID; t->flags |= TYPE_IS_RESOLVED; } - } break; + typer_block_exit(tr); + break; + for_fail: + typer_block_exit(tr); + return false; + }; case EXPR_IDENT: { if (!type_of_ident(tr, e->where, &e->ident, t)) return false; } break; @@ -2183,12 +2209,11 @@ static bool types_expr(Typer *tr, Expression *e) { return true; } + static bool types_block(Typer *tr, Block *b) { - *(Block **)arr_add(&tr->blocks) = b; - tr->block = b; if (b->flags & BLOCK_FOUND_TYPES) return true; - + typer_block_enter(tr, b); bool success = true; arr_foreach(b->stmts, Statement, s) { if (!types_stmt(tr, s)) { @@ -2221,8 +2246,7 @@ static bool types_block(Typer *tr, Block *b) { } ret: - tr->block = *(Block **)arr_last(tr->blocks); - arr_remove_last(&tr->blocks); + typer_block_exit(tr); b->flags |= BLOCK_FOUND_TYPES; return success; } |