diff options
-rw-r--r-- | allocator.c | 3 | ||||
-rw-r--r-- | copy.c | 19 | ||||
-rw-r--r-- | err.c | 29 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | parse.c | 8 | ||||
-rwxr-xr-x | runv | 2 | ||||
-rw-r--r-- | test.toc | 22 | ||||
-rw-r--r-- | toc.c | 6 | ||||
-rw-r--r-- | types.c | 33 | ||||
-rw-r--r-- | types.h | 14 |
10 files changed, 89 insertions, 52 deletions
diff --git a/allocator.c b/allocator.c index 4394201..202b238 100644 --- a/allocator.c +++ b/allocator.c @@ -1,3 +1,6 @@ +static void *err_malloc(size_t bytes); +static void *err_calloc(size_t n, size_t sz); +static void *err_realloc(void *prev, size_t new_size); #define NO_ALLOCATOR 1 /* useful for debugging; valgrind (maybe) checks writing past the end of a malloc, but that won't work with an allocator */ /* number of bytes a page hold, not including the header */ #define PAGE_BYTES (16384 - sizeof(Page)) @@ -8,8 +8,9 @@ typedef struct { static void copy_expr(Copier *c, Expression *out, Expression *in); static void copy_decl(Copier *c, Declaration *out, Declaration *in); static void copy_block(Copier *c, Block *out, Block *in); +static void copy_type(Copier *c, Type *out, Type *in); -static void copy_val(Allocator *allocr, Value *out, Value *in, Type *t) { +static void copy_val(Copier *c, Value *out, Value *in, Type *t) { switch (t->kind) { case TYPE_BUILTIN: case TYPE_FN: @@ -17,27 +18,29 @@ static void copy_val(Allocator *allocr, Value *out, Value *in, Type *t) { case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: - case TYPE_TYPE: *out = *in; break; case TYPE_ARR: { size_t bytes = t->arr.n * compiler_sizeof(t->arr.of); - out->arr = allocr_malloc(allocr, bytes); + out->arr = allocr_malloc(c->allocr, bytes); memcpy(out->arr, in->arr, bytes); } break; case TYPE_TUPLE: { size_t bytes = arr_len(t->tuple) * sizeof(*out->tuple); - out->tuple = allocr_malloc(allocr, bytes); + out->tuple = allocr_malloc(c->allocr, bytes); memcpy(out->tuple, in->tuple, bytes); } break; case TYPE_STRUCT: { size_t bytes = compiler_sizeof(t); - out->struc = allocr_malloc(allocr, bytes); + out->struc = allocr_malloc(c->allocr, bytes); memcpy(out->struc, in->struc, bytes); } break; case TYPE_USER: - copy_val(allocr, out, in, type_user_underlying(t)); + copy_val(c, out, in, type_user_underlying(t)); break; + case TYPE_TYPE: + copy_type(c, out->type = allocr_malloc(c->allocr, sizeof *out->type), in->type); + break; } } @@ -222,7 +225,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) { copy_type(c, &out->typeval, &in->typeval); break; case EXPR_VAL: - copy_val(a, &out->val, &in->val, &in->type); + copy_val(c, &out->val, &in->val, &in->type); break; } } @@ -234,7 +237,7 @@ static void copy_decl(Copier *c, Declaration *out, Declaration *in) { if (in->flags & DECL_HAS_EXPR) copy_expr(c, &out->expr, &in->expr); if (in->flags & DECL_FOUND_VAL) { - copy_val(c->allocr, &out->val, &in->val, &in->type); + copy_val(c, &out->val, &in->val, &in->type); } if (in->flags & DECL_ANNOTATES_TYPE) copy_type(c, &out->type, &in->type); @@ -49,17 +49,30 @@ static void warn_print_header_(Location where) { err_fprint(TEXT_WARN("warning:") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); } -static void err_print_footer_(const char *context) { - const char *end = strchr(context, '\n'); +static void err_print_location_text(Location where) { + const char *text = where.code; + const char *end = strchr(text, '\n'); int has_newline = end != NULL; if (!has_newline) - end = strchr(context, '\0'); + end = strchr(text, '\0'); assert(end); - err_fprint("\n\there: --> "); - err_fwrite(context, 1, (size_t)(end - context)); + err_fprint("\there: --> "); if (!has_newline) err_fprint("<end of file>"); + else + err_fwrite(text, 1, (size_t)(end - text)); err_fprint("\n"); + +} + +static void err_print_footer_(Location where) { + ErrCtx *ctx = where.ctx; + err_fprint("\n"); + err_print_location_text(where); + arr_foreach(ctx->instance_stack, Location, inst) { + err_fprint("While generating the instance of a function\n"); + err_print_location_text(*inst); + } } /* Write nicely-formatted errors to the error file */ @@ -69,7 +82,7 @@ static void err_vprint(Location where, const char *fmt, va_list args) { if (!where.ctx->enabled) return; err_print_header_(where); err_vfprint(fmt, args); - err_print_footer_(where.code); + err_print_footer_(where); } static void err_print_(int line, const char *file, Location where, const char *fmt, ...) { @@ -90,7 +103,7 @@ static void info_print(Location where, const char *fmt, ...) { va_start(args, fmt); info_print_header_(where); err_vfprint(fmt, args); - err_print_footer_(where.code); + err_print_footer_(where); va_end(args); } @@ -100,7 +113,7 @@ static void warn_print(Location where, const char *fmt, ...) { va_start(args, fmt); warn_print_header_(where); err_vfprint(fmt, args); - err_print_footer_(where.code); + err_print_footer_(where); va_end(args); } @@ -1,9 +1,10 @@ /* TODO: -better errors (show where instance is) +fix alias type, instead of creating a new type. make sure fn(t @ Type, x : t = 1598, y @ t = 9832) works don't cgen decls etc. in parameter initializers +check for leaks struct parameters don't allow while {3; 5} (once break is added) @@ -60,7 +61,7 @@ int main(int argc, char **argv) { Tokenizer t; Allocator main_allocr; allocr_create(&main_allocr); - ErrCtx err_ctx; + ErrCtx err_ctx = {0}; err_ctx.filename = in_filename; err_ctx.enabled = true; tokr_create(&t, &file_idents, &err_ctx, &main_allocr); @@ -1955,6 +1955,10 @@ static void fprint_block(FILE *out, Block *b) { } static void fprint_fn_expr(FILE *out, FnExpr *f) { + bool anyc = fn_has_any_const_params(f); + bool prev = parse_printing_after_types; + if (anyc) + parse_printing_after_types = false; fprintf(out, "fn ("); arr_foreach(f->params, Declaration, decl) { if (decl != f->params) @@ -1964,10 +1968,6 @@ static void fprint_fn_expr(FILE *out, FnExpr *f) { fprintf(out, ") "); fprint_type(out, &f->ret_type); fprintf(out, " "); - bool anyc = fn_has_any_const_params(f); - bool prev = parse_printing_after_types; - if (anyc) - parse_printing_after_types = false; fprint_block(out, &f->body); if (anyc) parse_printing_after_types = prev; @@ -1,5 +1,5 @@ #!/bin/sh -valgrind -q --track-origins=yes --error-exitcode=1 --malloc-fill=0xcd ./toc test.toc || exit 1 +valgrind -q --track-origins=yes --error-exitcode=1 --malloc-fill=0xcd --free-fill=0xef --num-callers=100 ./toc test.toc || exit 1 if [ "$1" = "c" ]; then gcc out.c && ./a.out elif [ "$1" = "pc" ]; then @@ -1,20 +1,20 @@ -puti @= fn(x: int) { - #C("printf(\"%ld\\n\", (long)x); -"); -}; -putf @= fn(x: float) { - #C("printf(\"%f\\n\", (double)x); -"); -}; +// puti @= fn(x: int) { +// #C("printf(\"%ld\\n\", (long)x); +// "); +// }; +// putf @= fn(x: float) { +// #C("printf(\"%f\\n\", (double)x); +// "); +// }; main @= fn() { - puti(g(int)); - puti(g()); + g(int); + g(); }; -g @= fn(t @= u8) int { +g @= fn(t @= int) int { 87347 as t as int }; @@ -28,11 +28,11 @@ static Type *type_inner(Type *t) { return t; } -#include "rand.c" -#include "location.c" -#include "err.c" #include "allocator.c" #include "arr.c" +#include "location.c" +#include "err.c" +#include "rand.c" #include "blockarr.c" #include "str.c" #include "instance_table.c" @@ -605,9 +605,11 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, Instance *instance) { FnExpr *prev_fn = tr->fn; bool success = true; + ErrCtx *err_ctx = where.ctx; assert(t->kind == TYPE_FN); if (instance) { + *(Location *)arr_add(&err_ctx->instance_stack) = where; Copier cop = {.allocr = tr->allocr, .block = f->body.parent}; copy_fn_expr(&cop, &instance->fn, f, true); f = &instance->fn; @@ -630,8 +632,10 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, semi_const_arg_idx++; } } - if (!type_of_fn(tr, f, where, t, TYPE_OF_FN_NO_COPY_EVEN_IF_CONST)) + if (!type_of_fn(tr, f, where, t, TYPE_OF_FN_NO_COPY_EVEN_IF_CONST)) { + arr_remove_last(&err_ctx->instance_stack); return false; + } } else { if (t->fn.constness) return true; /* don't type function body yet; we need to do that for every instance */ @@ -688,6 +692,8 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, goto ret; } ret: + if (instance) + arr_remove_last(&err_ctx->instance_stack); tr->fn = prev_fn; return success; } @@ -1102,14 +1108,18 @@ static bool types_expr(Typer *tr, Expression *e) { return false; if (!eval_expr(tr->evalr, ©, &default_val)) return false; + new_args[i].kind = EXPR_VAL; new_args[i].flags = copy.flags; new_args[i].type = copy.type.kind == TYPE_TUPLE ? copy.type.tuple[ident_idx] : copy.type; - new_args[i].val = copy.type.kind == TYPE_TUPLE - ? default_val.tuple[ident_idx] - : default_val; + + copy_val(&cop, &new_args[i].val, + copy.type.kind == TYPE_TUPLE + ? &default_val.tuple[ident_idx] + : &default_val, &new_args[i].type); + } else { /* it's already been evaluated */ assert(param->expr.kind == EXPR_VAL); /* evaluated in type_of_fn */ @@ -1149,7 +1159,6 @@ static bool types_expr(Typer *tr, Expression *e) { int semi_const_index = 0; for (size_t i = 0; i < arr_len(fn_type->types)-1; i++) { 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)) { @@ -1158,12 +1167,16 @@ static bool types_expr(Typer *tr, Expression *e) { } return false; } - new_args[i].kind = EXPR_VAL; - new_args[i].flags = 0; - new_args[i].val = *arg_val; Type *type = arr_add(&table_index_type.tuple); *type = fn_type->types[i+1]; + + new_args[i].kind = EXPR_VAL; + new_args[i].flags = EXPR_FOUND_TYPE; + Copier cop = {.allocr = tr->allocr, .block = tr->block}; + copy_val(&cop, &new_args[i].val, arg_val, type); + new_args[i].val = *arg_val; + new_args[i].type = *type; if (fn_type->constness[i] == CONSTNESS_SEMI) { if (semi_const_index >= 64) { @@ -1668,7 +1681,8 @@ static bool types_decl(Typer *tr, Declaration *d) { success = false; goto ret; } - copy_val(tr->allocr, &d->val, &val, &d->type); + Copier cop = {.block = tr->block, .allocr = tr->allocr}; + copy_val(&cop, &d->val, &val, &d->type); d->flags |= DECL_FOUND_VAL; } } @@ -1779,6 +1793,7 @@ static void typer_create(Typer *tr, Evaluator *ev, Allocator *allocr) { tr->in_decls = NULL; tr->in_expr_decls = NULL; tr->allocr = allocr; + } static bool types_file(Typer *tr, ParsedFile *f) { @@ -49,16 +49,18 @@ typedef U32 IdentID; /* identifier ID for cgen (anonymous variables) */ typedef uint32_t LineNo; -typedef struct { +typedef struct Location { + LineNo line; + char *code; + struct ErrCtx *ctx; +} Location; + +typedef struct ErrCtx { const char *filename; bool enabled; + Location *instance_stack; /* stack of locations which generate the instances we're dealing with */ } ErrCtx; -typedef struct { - LineNo line; - char *code; - ErrCtx *ctx; -} Location; typedef struct Page { struct Page *next; |