diff options
-rw-r--r-- | copy.c | 8 | ||||
-rw-r--r-- | eval.c | 25 | ||||
-rw-r--r-- | identifiers.c | 14 | ||||
-rw-r--r-- | parse.c | 30 | ||||
-rw-r--r-- | test.toc | 10 | ||||
-rw-r--r-- | types.c | 57 | ||||
-rw-r--r-- | types.h | 6 |
7 files changed, 97 insertions, 53 deletions
@@ -248,13 +248,13 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) { if (fout->index) { copier_ident_translate(c, &fout->index); - fout->index->decl_kind = IDECL_FOR; - fout->index->for_ = fout; + fout->index->decl_kind = IDECL_EXPR; + fout->index->decl_expr = out; } if (fout->value) { copier_ident_translate(c, &fout->value); - fout->value->decl_kind = IDECL_FOR; - fout->value->for_ = fout; + fout->value->decl_kind = IDECL_EXPR; + fout->value->decl_expr = out; } if (fin->flags & FOR_ANNOTATED_TYPE) copy_type(c, &fout->type, &fin->type); @@ -726,17 +726,22 @@ static bool eval_expr_ptr_at_index(Evaluator *ev, Expression *e, void **ptr, Typ static Value *ident_val(Identifier i) { switch (i->decl_kind) { - case IDECL_FOR: { - ForExpr *fo = i->for_; - Value *v = *(Value **)arr_last(fo->val_stack); - if (i == fo->index) { - if (fo->value) - v = &v->tuple[0]; - } else { - if (fo->index) - v = &v->tuple[1]; + case IDECL_EXPR: { + switch (i->decl_expr->kind) { + case EXPR_FOR: { + ForExpr *fo = i->decl_expr->for_; + Value *v = *(Value **)arr_last(fo->val_stack); + if (i == fo->index) { + if (fo->value) + v = &v->tuple[0]; + } else { + if (fo->index) + v = &v->tuple[1]; + } + return v; + } + default: assert(0); return NULL; } - return v; } case IDECL_DECL: { Declaration *decl = i->decl; diff --git a/identifiers.c b/identifiers.c index 876c55a..a70028d 100644 --- a/identifiers.c +++ b/identifiers.c @@ -231,3 +231,17 @@ static int ident_index_in_decl(Identifier i, Declaration *d) { } return -1; } + +static Location ident_decl_location(Identifier i) { + switch (i->decl_kind) { + case IDECL_DECL: + return i->decl->where; + case IDECL_EXPR: + return i->decl_expr->where; + case IDECL_NONE: + break; + } + assert(0); + Location l = {0}; + return l; +} @@ -1042,6 +1042,20 @@ static Identifier parser_ident_insert(Parser *p, char *str) { return i; } +static bool check_ident_redecl(Parser *p, Identifier i) { + Tokenizer *t = p->tokr; + if (i->idents == &p->block->idents) { + if (i->decl_kind != IDECL_NONE) { + char *s = ident_to_str(i); + tokr_err(t, "Redeclaration of identifier %s.", s); + info_print(ident_decl_location(i), "Previous declaration was here."); + free(s); + return false; + } + } + return true; +} + static bool parse_expr(Parser *p, Expression *e, Token *end) { Tokenizer *t = p->tokr; @@ -1254,8 +1268,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { && token_is_kw(t->token + 3, KW_COLON))))) { if (t->token->kind == TOKEN_IDENT) { fo->value = parser_ident_insert(p, t->token->ident); - fo->value->decl_kind = IDECL_FOR; - fo->value->for_ = fo; + if (!check_ident_redecl(p, fo->value)) + goto for_fail; + fo->value->decl_kind = IDECL_EXPR; + fo->value->decl_expr = e; if (ident_eq_str(fo->value, "_")) /* ignore value */ fo->value = NULL; ++t->token; @@ -1263,8 +1279,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { ++t->token; if (t->token->kind == TOKEN_IDENT) { fo->index = parser_ident_insert(p, t->token->ident); - fo->index->decl_kind = IDECL_FOR; - fo->index->for_ = fo; + if (!check_ident_redecl(p, fo->index)) + goto for_fail; + fo->index->decl_kind = IDECL_EXPR; + fo->index->decl_expr = e; if (ident_eq_str(fo->index, "_")) /* ignore index */ fo->index = NULL; ++t->token; @@ -1334,7 +1352,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { err_print(token_location(p->file, first_end), "Expected { or .. to follow expression in for statement."); goto for_fail; } - + e->where.end = t->token; /* temporarily set end so that redeclaration errors aren't messed up */ if (!parse_block(p, &fo->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) goto for_fail; p->block = prev_block; @@ -1931,6 +1949,8 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla *ident = parser_ident_insert(p, t->token->ident); { Identifier i = *ident; + if (!check_ident_redecl(p, i)) + goto ret_false; i->decl_kind = IDECL_DECL; i->decl = d; } @@ -2,12 +2,10 @@ io ::= nms { #include "std/io.toc"; }; -f ::= fn(a,b::=3) int { - a + b +p ::= struct(x::Type) { + y:int; }; - main ::= fn() { - x ::= f(); - io.puti(x); - io.puti(f()); +z:p(int); +for z := 1..100 {z:=12;} };
\ No newline at end of file @@ -483,24 +483,30 @@ static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) } } } break; - case IDECL_FOR: { - ForExpr *fo = i->for_; - /* are we inside this for? */ - typedef ForExpr *ForExprPtr; - arr_foreach(tr->in_fors, ForExprPtr, in_f) { - if (*in_f == fo) { + case IDECL_EXPR: { + Expression *e = i->decl_expr; + /* are we inside this expr? */ + typedef Expression *ExprPtr; + arr_foreach(tr->in_exprs, ExprPtr, in_e) { + if (*in_e == e) { char *s = ident_to_str(i); err_print(where, "Use of identifier %s in its own declaration.", s); free(s); return false; } } - if (i == fo->index) { - t->kind = TYPE_BUILTIN; - t->builtin = BUILTIN_I64; - } else { - assert(i == fo->value); - *t = fo->type; + switch (e->kind) { + case EXPR_FOR: { + ForExpr *fo = e->for_; + if (i == fo->index) { + t->kind = TYPE_BUILTIN; + t->builtin = BUILTIN_I64; + } else { + assert(i == fo->value); + *t = fo->type; + } + } break; + default: assert(0); break; } } break; case IDECL_NONE: { @@ -1213,7 +1219,7 @@ static bool types_expr(Typer *tr, Expression *e) { case EXPR_FOR: { ForExpr *fo = e->for_; bool in_header = true; - *(ForExpr **)typer_arr_add(tr, &tr->in_fors) = fo; + *(Expression **)typer_arr_add(tr, &tr->in_exprs) = 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 */ @@ -1224,6 +1230,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *s = type_to_str(ft); err_print(e->where, "from expression of for loop must be a builtin numerical type, not %s", s); free(s); + goto for_fail; } } if (fo->range.step) { @@ -1233,6 +1240,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *s = type_to_str(st); err_print(e->where, "step expression of for loop must be a builtin numerical type, not %s", s); free(s); + goto for_fail; } } if (fo->range.to) { @@ -1242,6 +1250,7 @@ static bool types_expr(Typer *tr, Expression *e) { char *s = type_to_str(tt); err_print(e->where, "to expression of for loop must be a builtin numerical type, not %s", s); free(s); + goto for_fail; } } @@ -1330,7 +1339,7 @@ static bool types_expr(Typer *tr, Expression *e) { fo->range.stepval = stepval; } - arr_remove_lasta(&tr->in_fors, tr->allocr); + arr_remove_lasta(&tr->in_exprs, tr->allocr); in_header = false; if (!types_block(tr, &fo->body)) goto for_fail; @@ -1344,7 +1353,7 @@ static bool types_expr(Typer *tr, Expression *e) { break; for_fail: if (in_header) - arr_remove_lasta(&tr->in_fors, tr->allocr); + arr_remove_lasta(&tr->in_exprs, tr->allocr); typer_block_exit(tr); return false; }; @@ -1535,12 +1544,12 @@ static bool types_expr(Typer *tr, Expression *e) { int ident_idx = 0; /* temporarily add this instance to the stack, while we type the decl, in case you, e.g., pass t = float to struct(t::Type, u::t = "hello") */ *(Location *)arr_add(&err_ctx->instance_stack) = e->where; - if (!types_decl(tr, param)) { - arr_remove_last(&err_ctx->instance_stack); - return false; - } + typer_block_enter(tr, &struc.scope); + bool success = types_decl(tr, param); arr_remove_last(&err_ctx->instance_stack); - + typer_block_exit(tr); + if (!success) return false; + arr_foreach(param->idents, Identifier, ident) { Type *type = decl_type_at_index(param, ident_idx); arg_types[p] = *type; @@ -1599,11 +1608,9 @@ static bool types_expr(Typer *tr, Expression *e) { struct_t.kind = TYPE_STRUCT; struct_t.struc = &inst->struc; *(Location *)arr_add(&err_ctx->instance_stack) = e->where; - if (!type_resolve(tr, &struct_t, e->where)) /* resolve the struct */ { - arr_remove_last(&err_ctx->instance_stack); - return false; - } + bool success = type_resolve(tr, &struct_t, e->where); /* resolve the struct */ arr_remove_last(&err_ctx->instance_stack); + if (!success) return false; inst->struc.instance_id = table->n; } @@ -2759,7 +2766,7 @@ static void typer_create(Typer *tr, Evaluator *ev, ErrCtx *err_ctx, Allocator *a tr->evalr = ev; tr->err_ctx = err_ctx; tr->in_decls = NULL; - tr->in_fors = NULL; + tr->in_exprs = NULL; tr->allocr = allocr; tr->globals = idents; tr->is_reference_stack = NULL; @@ -170,7 +170,7 @@ typedef union Value { typedef enum { IDECL_NONE, IDECL_DECL, - IDECL_FOR + IDECL_EXPR } IdentDeclKind; @@ -181,7 +181,7 @@ typedef struct IdentSlot { IdentDeclKind decl_kind; union { struct Declaration *decl; - struct ForExpr *for_; + struct Expression *decl_expr; }; struct Identifiers *idents; SOURCE_LOCATION @@ -899,7 +899,7 @@ typedef struct Typer { Allocator *allocr; Evaluator *evalr; Identifiers *globals; - ForExpr **in_fors; /* which fors we are currently inside the header of */ + Expression **in_exprs; /* which expression declarations we are currently inside (e.g. for x := foo)*/ Declaration **in_decls; /* array of declarations we are currently inside */ Block *block; Block **blocks; /* dyn array of all the block's we're in ([0] = NULL for global scope) */ |