diff options
-rw-r--r-- | arr.c | 19 | ||||
-rw-r--r-- | eval.c | 5 | ||||
-rw-r--r-- | location.c | 5 | ||||
-rw-r--r-- | test.toc | 26 | ||||
-rw-r--r-- | types.c | 73 |
5 files changed, 69 insertions, 59 deletions
@@ -44,12 +44,25 @@ static void arr_resva_(void **arr, size_t n, size_t item_sz, Allocator *a) { } } +static void arr_clear_(void **arr) { + if (*arr) { + free(arr_hdr(*arr)); + *arr = NULL; + } +} static void arr_set_len_(void **arr, size_t n, size_t item_sz) { + if (n == 0) { + arr_clear_(arr); + return; + } arr_resv_(arr, n, item_sz); arr_hdr(*arr)->len = n; } static void arr_set_lena_(void **arr, size_t n, size_t item_sz, Allocator *a) { + if (n == 0) { + /* OPTIM: arr_cleara */ + } arr_resva_(arr, n, item_sz, a); arr_hdr(*arr)->len = n; } @@ -83,12 +96,6 @@ static void *arr_adda_(void **arr, size_t item_sz, Allocator *a) { return &(((char *)hdr->data)[(hdr->len++) * item_sz]); } -static void arr_clear_(void **arr) { - if (*arr) { - free(arr_hdr(*arr)); - *arr = NULL; - } -} static void *arr_last_(void *arr, size_t item_sz) { if (arr) { @@ -1324,6 +1324,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { *v = idecl->val; } else if (is_decl && (d->flags & DECL_IS_CONST)) { if (!(d->flags & DECL_FOUND_VAL)) { + if (!(d->flags & DECL_HAS_EXPR)){ + print_location(d->where); + abort(); + assert(d->flags & DECL_HAS_EXPR); /* KEEP */ + } if (!eval_expr(ev, &d->expr, &d->val)) return false; d->flags |= DECL_FOUND_VAL; } @@ -3,9 +3,14 @@ static bool location_after(Location a, Location b) { /* a is after b? */ return a.code > b.code; } +/* for debugging */ static void fprint_location(FILE *out, Location location) { char *newline = strchr(location.code, '\n'); if (newline) *newline = 0; fprintf(out, "Line %ld: %s\n", (long)location.line, location.code); if (newline) *newline = '\n'; } + +static void print_location(Location location) { + fprint_location(stdout, location); +} @@ -9,23 +9,23 @@ Arr @= fn (t @ Type) Type { struct { - data : []t; - len, cap : u64; + data : t; + // len, cap : u64; } }; // todo: test that t @ type doesn't cause problems -arr_add @= fn(t @ Type, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); - each i := 0..a.len { - new_data[i] = a.data[i]; - } - a.data = new_data; - } - a.data[a.len] = x; - a.len += 1; +arr_add @= fn(t @ Type, a : &Arr(t)) { + // if a.len >= a.cap { + // a.cap = a.cap * 2 + 2; + // new_data := new(t, a.cap); + // each i := 0..a.len { + // new_data[i] = a.data[i]; + // } + // a.data = new_data; + // } + // a.data[a.len] = x; + // a.len += 1; }; @@ -193,7 +193,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) t->fn.constness = NULL; /* OPTIM: constness doesn't need to be a dynamic array */ bool success = true; bool entered_fn = false; - bool added_param_decls = false; + size_t param_idx; FnExpr *prev_fn = tr->fn; FnExpr fn_copy; @@ -202,31 +202,33 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) copy_fn_expr(&cop, &fn_copy, f, false); f = &fn_copy; } - 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; - arr_foreach(f->params, Declaration, decl) { - if (!types_decl(tr, decl)) { + for (param_idx = 0; param_idx < nparams; param_idx++) { + Declaration *param = &f->params[param_idx]; + print_location(param->where); + if (!types_decl(tr, param)) { success = false; goto ret; } - if (decl->type.kind == TYPE_TUPLE) { - err_print(decl->where, "Functions can't have tuple parameters."); + if (param->type.kind == TYPE_TUPLE) { + err_print(param->where, "Functions can't have tuple parameters."); success = false; goto ret; } - if (!type_resolve(tr, &decl->type, where)) { + if (!type_resolve(tr, ¶m->type, where)) { success = false; goto ret; } - U32 is_at_all_const = decl->flags & (DECL_IS_CONST | DECL_SEMI_CONST); + U32 is_at_all_const = param->flags & (DECL_IS_CONST | DECL_SEMI_CONST); if (is_at_all_const) { if (!t->fn.constness) { has_constant_params = true; @@ -235,31 +237,26 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) } } } - if (decl->flags & DECL_HAS_EXPR) { - if (decl->expr.kind != EXPR_VAL) { + if (param->flags & DECL_HAS_EXPR) { + if (param->expr.kind != EXPR_VAL) { Value val; - if (!eval_expr(tr->evalr, &decl->expr, &val)) { - info_print(decl->where, "Was trying to evaluate default arguments (which must be constants!)"); - for (Declaration *p = f->params; p != decl; p++) { - if (p->flags & DECL_IS_CONST) - arr_foreach(p->idents, Identifier, ident) - arr_remove_last(&(*ident)->decls); - } + if (!eval_expr(tr->evalr, ¶m->expr, &val)) { + info_print(param->where, "Was trying to evaluate default arguments (which must be constants!)"); success = false; goto ret; } - decl->expr.kind = EXPR_VAL; - decl->expr.val = val; + param->expr.kind = EXPR_VAL; + param->expr.val = val; } } - for (size_t i = 0; i < arr_len(decl->idents); i++) { + for (size_t i = 0; i < arr_len(param->idents); i++) { Type *param_type = typer_arr_add(tr, &t->fn.types); - *param_type = decl->type; + *param_type = param->type; if (has_constant_params) { Constness constn; - if (decl->flags & DECL_IS_CONST) { + if (param->flags & DECL_IS_CONST) { constn = CONSTNESS_YES; - } else if (decl->flags & DECL_SEMI_CONST) { + } else if (param->flags & DECL_SEMI_CONST) { constn = CONSTNESS_SEMI; } else { constn = CONSTNESS_NO; @@ -269,15 +266,13 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) idx++; } - if (decl->flags & DECL_IS_CONST) { + if (param->flags & DECL_IS_CONST) { /* allow constant declarations to be used in other parameters, e.g. fn(x @ int, y := x) */ - arr_foreach(decl->idents, Identifier, ident) { - ident_add_decl(*ident, decl, &f->body); + arr_foreach(param->idents, Identifier, ident) { + ident_add_decl(*ident, param, &f->body); } } } - added_param_decls = true; - if (f->ret_decls && f->ret_type.kind == TYPE_VOID /* haven't found return type yet */) { /* find return type */ @@ -315,20 +310,18 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) } ret: /* cleanup */ - if (entered_fn) { fn_exit(f); tr->fn = prev_fn; - - if (added_param_decls) { - /* remove constant parameter ident decls */ - arr_foreach(f->params, Declaration, param) { - if (param->flags & DECL_IS_CONST) { - arr_foreach(param->idents, Identifier, ident) - arr_remove_last(&(*ident)->decls); - } - } + + /* remove declarations from parameters we've already dealt with */ + for (size_t i = 0; i < param_idx; i++) { + Declaration *p = &f->params[i]; + if (p->flags & DECL_IS_CONST) + arr_foreach(p->idents, Identifier, ident) + arr_remove_last(&(*ident)->decls); } + } return success; } @@ -635,6 +628,7 @@ static bool arg_is_const(Expression *arg, Constness constness) { } +/* MUST be called after type_of_fn. */ /* pass NULL for instance if this isn't an instance */ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, Instance *instance) { @@ -1182,7 +1176,6 @@ static bool types_expr(Typer *tr, Expression *e) { bool should_be_evald = arg_is_const(&new_args[i], fn_type->constness[i]); if (should_be_evald) { Value *arg_val = typer_arr_add(tr, &table_index.tuple); - if (!eval_expr(tr->evalr, &new_args[i], arg_val)) { if (tr->evalr->enabled) { info_print(new_args[i].where, "(error occured while trying to evaluate compile-time argument, argument #%lu)", 1+(unsigned long)i); |