summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-07 15:52:11 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-07 15:52:11 -0500
commit2ffd5ed0334788b444922357873cd4bfc342f0e9 (patch)
treeaa59a2488675437b1e966ae8f2f100d887c9e8e0
parenteee36346d65080feee7d70b8ecc7a39f83f5f3eb (diff)
new ident system almost working
-rw-r--r--location.c5
-rw-r--r--parse.c21
-rw-r--r--test.toc24
-rw-r--r--toc.c2
-rw-r--r--types.c78
5 files changed, 81 insertions, 49 deletions
diff --git a/location.c b/location.c
index 36e95bb..12c932f 100644
--- a/location.c
+++ b/location.c
@@ -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 {
diff --git a/parse.c b/parse.c
index 4853848..56f495d 100644
--- a/parse.c
+++ b/parse.c
@@ -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) {
diff --git a/test.toc b/test.toc
index 4811e46..ac60b69 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/toc.c b/toc.c
index 9a5be2f..3b09888 100644
--- a/toc.c
+++ b/toc.c
@@ -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 */
diff --git a/types.c b/types.c
index 4d2391a..a5c30c0 100644
--- a/types.c
+++ b/types.c
@@ -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;
}