From 4a1f37e189f518dbde3cfc7911040df0ef748869 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 19 Nov 2019 14:40:56 -0500 Subject: fixed problems with const params --- cgen.c | 221 +++++++++++++++++++++++++++++++---------------------------- copy.c | 156 ++++++++++++++++++++++------------------- decls_cgen.c | 6 +- main.c | 2 +- test.toc | 20 +++--- tokenizer.c | 2 +- types.c | 21 +++--- 7 files changed, 231 insertions(+), 197 deletions(-) diff --git a/cgen.c b/cgen.c index 8191d71..5d98814 100644 --- a/cgen.c +++ b/cgen.c @@ -26,106 +26,120 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where); static bool cgen_defs_block(CGenerator *g, Block *b); static bool cgen_defs_decl(CGenerator *g, Declaration *d); +#define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \ + if (!fn_enter(fn, 0)) return false; \ + arr_foreach(fn->params, Declaration, param) \ + if (!decl_f(g, param)) \ + return false; \ + arr_foreach(fn->ret_decls, Declaration, r) \ + if (!decl_f(g, r)) \ + return false; \ + if (!block_f(g, &fn->body)) \ + return false; \ + fn_exit(fn); + /* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */ -#define cgen_recurse_subexprs(g, e, f, block_f, decl_f) \ - switch (e->kind) { \ - case EXPR_TYPE: \ - case EXPR_VAL: \ - case EXPR_C: \ - case EXPR_DSIZEOF: \ - case EXPR_DALIGNOF: \ - case EXPR_IDENT: \ - case EXPR_LITERAL_BOOL: \ - case EXPR_LITERAL_INT: \ - case EXPR_LITERAL_STR: \ - case EXPR_LITERAL_CHAR: \ - case EXPR_LITERAL_FLOAT: \ - break; \ - case EXPR_UNARY_OP: \ - if (!f(g, e->unary.of)) return false; \ - break; \ - case EXPR_BINARY_OP: \ - if (!f(g, e->binary.lhs)) return false; \ - if (e->binary.op != BINARY_DOT) \ - if (!f(g, e->binary.rhs)) \ - return false; \ - break; \ - case EXPR_CAST: \ - if (!f(g, e->cast.expr)) \ - return false; \ - break; \ - case EXPR_CALL: \ - if (!f(g, e->call.fn)) \ - return false; \ - arr_foreach(e->call.arg_exprs, Expression, arg) \ - if (!f(g, arg)) \ - return false; \ - break; \ - case EXPR_BLOCK: \ - if (!block_f(g, &e->block)) \ - return false; \ - break; \ - case EXPR_IF: \ - if (e->if_.cond) \ - if (!f(g, e->if_.cond)) \ - return false; \ - if (!block_f(g, &e->if_.body)) \ - return false; \ - if (e->if_.next_elif) \ - if (!f(g, e->if_.next_elif)) \ - return false; \ - break; \ - case EXPR_WHILE: \ - if (e->while_.cond) \ - if (!f(g, e->while_.cond)) \ - return false; \ - if (!block_f(g, &e->while_.body)) \ - return false; \ - break; \ - case EXPR_EACH: { \ - EachExpr *ea = &e->each; \ - if (!each_enter(e)) return false; \ - if (ea->flags & EACH_IS_RANGE) { \ - if (!f(g, ea->range.from)) \ - return false; \ - if (ea->range.to && !f(g, ea->range.to)) \ - return false; \ - /* step is a value, not an expression */ \ - } else { \ - if (!f(g, ea->of)) \ - return false; \ - } \ - if (!block_f(g, &ea->body)) return false; \ - each_exit(e); \ - } break; \ - case EXPR_TUPLE: \ - arr_foreach(e->tuple, Expression, x) \ - if (!f(g, x)) \ - return false; \ - break; \ - case EXPR_SLICE: \ - if (!f(g, e->slice.of)) return false; \ - if (e->slice.from && !f(g, e->slice.from)) \ - return false; \ - if (e->slice.to && !f(g, e->slice.to)) \ - return false; \ - break; \ - case EXPR_FN: \ - if (!fn_enter(&e->fn, 0)) return false; \ - arr_foreach(e->fn.params, Declaration, param) \ - if (!decl_f(g, param)) \ - return false; \ - arr_foreach(e->fn.ret_decls, Declaration, r) \ - if (!decl_f(g, r)) \ - return false; \ - if (!block_f(g, &e->fn.body)) \ - return false; \ - fn_exit(&e->fn); \ - break; \ - case EXPR_NEW: \ - if (e->new.n && !f(g, e->new.n)) \ - return false; \ - break; \ +#define cgen_recurse_subexprs(g, e, f, block_f, decl_f) \ + switch (e->kind) { \ + case EXPR_TYPE: \ + case EXPR_VAL: \ + case EXPR_C: \ + case EXPR_DSIZEOF: \ + case EXPR_DALIGNOF: \ + case EXPR_IDENT: \ + case EXPR_LITERAL_BOOL: \ + case EXPR_LITERAL_INT: \ + case EXPR_LITERAL_STR: \ + case EXPR_LITERAL_CHAR: \ + case EXPR_LITERAL_FLOAT: \ + break; \ + case EXPR_UNARY_OP: \ + if (!f(g, e->unary.of)) return false; \ + break; \ + case EXPR_BINARY_OP: \ + if (!f(g, e->binary.lhs)) return false; \ + if (e->binary.op != BINARY_DOT) \ + if (!f(g, e->binary.rhs)) \ + return false; \ + break; \ + case EXPR_CAST: \ + if (!f(g, e->cast.expr)) \ + return false; \ + break; \ + case EXPR_CALL: \ + if (!f(g, e->call.fn)) \ + return false; \ + arr_foreach(e->call.arg_exprs, Expression, arg) \ + if (!f(g, arg)) \ + return false; \ + break; \ + case EXPR_BLOCK: \ + if (!block_f(g, &e->block)) \ + return false; \ + break; \ + case EXPR_IF: \ + if (e->if_.cond) \ + if (!f(g, e->if_.cond)) \ + return false; \ + if (!block_f(g, &e->if_.body)) \ + return false; \ + if (e->if_.next_elif) \ + if (!f(g, e->if_.next_elif)) \ + return false; \ + break; \ + case EXPR_WHILE: \ + if (e->while_.cond) \ + if (!f(g, e->while_.cond)) \ + return false; \ + if (!block_f(g, &e->while_.body)) \ + return false; \ + break; \ + case EXPR_EACH: { \ + EachExpr *ea = &e->each; \ + if (!each_enter(e)) return false; \ + if (ea->flags & EACH_IS_RANGE) { \ + if (!f(g, ea->range.from)) \ + return false; \ + if (ea->range.to && !f(g, ea->range.to)) \ + return false; \ + /* step is a value, not an expression */ \ + } else { \ + if (!f(g, ea->of)) \ + return false; \ + } \ + if (!block_f(g, &ea->body)) return false; \ + each_exit(e); \ + } break; \ + case EXPR_TUPLE: \ + arr_foreach(e->tuple, Expression, x) \ + if (!f(g, x)) \ + return false; \ + break; \ + case EXPR_SLICE: \ + if (!f(g, e->slice.of)) return false; \ + if (e->slice.from && !f(g, e->slice.from)) \ + return false; \ + if (e->slice.to && !f(g, e->slice.to)) \ + return false; \ + break; \ + case EXPR_FN: { \ + FnExpr *fn = &e->fn; \ + if (e->type.fn.constness) { \ + Instance **data = fn->instance.data; \ + for (U64 i = 0; i < f->instances.cap; i++) { \ + if (f->instances.occupied[i]) { \ + cgen_recurse_subexprs_fn_simple(&(*data)->fn, decl_f, block_f); \ + } \ + data++; \ + } \ + } else { \ + cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f); \ + } \ + break; \ + case EXPR_NEW: \ + if (e->new.n && !f(g, e->new.n)) \ + return false; \ + break; \ } static bool cgen_block_enter(CGenerator *g, Block *b) { @@ -1377,7 +1391,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case EXPR_TUPLE: /* the only time this should happen is if you're stating a tuple, e.g. 3, 5;, but we've errored about that before - (the comma operator does not exist in toc!) */ + */ case EXPR_TYPE: assert(0); break; @@ -1692,7 +1706,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { struct declarations are handled by typedefs_cgen, and struct definitions are handled by decls_cgen. we don't need to do anything here. - */ + */ continue; } else if (type->kind == TYPE_FN && (d->flags & DECL_IS_CONST)) { /* don't generate function pointer declaration for constant fns */ @@ -1766,6 +1780,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { /* does NOT call cgen_expr_pre for ret. */ static bool cgen_ret(CGenerator *g, Expression *ret) { assert((g->fn->ret_type.kind == TYPE_VOID) == (ret == NULL)); + if (ret) assert(type_eq(&g->fn->ret_type, &ret->type)); if (!ret) { cgen_write(g, "return"); } else if (cgen_uses_ptr(&g->fn->ret_type)) { @@ -1834,7 +1849,7 @@ static bool cgen_defs_expr(CGenerator *g, Expression *e) { for (U64 i = 0; i < instances->cap; i++) { if (instances->occupied[i]) { /* generate this instance */ - if (!cgen_fn(g, f, e->where, is[i]->c.id, is[i]->val.tuple)) + if (!cgen_fn(g, &is[i]->fn, e->where, is[i]->c.id, is[i]->val.tuple)) return false; } } @@ -1891,7 +1906,7 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { /* TODO: to improve compile times, don't include stdlib.h (you can even get away with not including stdio.h with posix file descriptors) - */ + */ cgen_write(g, "#include \n" "#include \n" "#include \n" diff --git a/copy.c b/copy.c index 1677a7d..a296171 100644 --- a/copy.c +++ b/copy.c @@ -1,8 +1,13 @@ /* these copy functions MUST be used before typing!!!! (except for copy_val) */ -static void copy_expr(Allocator *a, Expression *out, Expression *in); -static void copy_decl(Allocator *a, Declaration *out, Declaration *in); -static void copy_block(Allocator *a, Block *out, Block *in); +typedef struct { + Allocator *allocr; + Block *block; +} Copier; + +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_val(Allocator *allocr, Value *out, Value *in, Type *t) { switch (t->kind) { @@ -36,7 +41,7 @@ static void copy_val(Allocator *allocr, Value *out, Value *in, Type *t) { } } -static void copy_type(Allocator *a, Type *out, Type *in) { +static void copy_type(Copier *c, Type *out, Type *in) { assert(!(in->flags & TYPE_IS_RESOLVED)); *out = *in; switch (in->kind) { @@ -49,65 +54,69 @@ static void copy_type(Allocator *a, Type *out, Type *in) { case TYPE_FN: { size_t ntypes = arr_len(in->fn.types); out->fn.types = NULL; - arr_set_lena(&out->fn.types, ntypes, a); + arr_set_lena(&out->fn.types, ntypes, c->allocr); for (size_t i = 0; i < ntypes; i++) { - copy_type(a, &out->fn.types[i], &in->fn.types[i]); + copy_type(c, &out->fn.types[i], &in->fn.types[i]); } } break; case TYPE_TUPLE: { size_t ntypes = arr_len(in->tuple); out->tuple = NULL; - arr_set_lena(&out->tuple, ntypes, a); + arr_set_lena(&out->tuple, ntypes, c->allocr); for (size_t i = 0; i < ntypes; i++) { - copy_type(a, &out->tuple[i], &in->tuple[i]); + copy_type(c, &out->tuple[i], &in->tuple[i]); } } break; case TYPE_ARR: - out->arr.n_expr = allocr_malloc(a, sizeof *out->arr.n_expr); - copy_expr(a, out->arr.n_expr, in->arr.n_expr); - out->arr.of = allocr_malloc(a, sizeof *out->arr.of); - copy_type(a, out->arr.of, in->arr.of); + out->arr.n_expr = allocr_malloc(c->allocr, sizeof *out->arr.n_expr); + copy_expr(c, out->arr.n_expr, in->arr.n_expr); + out->arr.of = allocr_malloc(c->allocr, sizeof *out->arr.of); + copy_type(c, out->arr.of, in->arr.of); break; case TYPE_PTR: - out->ptr = allocr_malloc(a, sizeof *out->ptr); - copy_type(a, out->ptr, in->ptr); + out->ptr = allocr_malloc(c->allocr, sizeof *out->ptr); + copy_type(c, out->ptr, in->ptr); break; case TYPE_SLICE: - out->ptr = allocr_malloc(a, sizeof *out->slice); - copy_type(a, out->slice, in->slice); + out->ptr = allocr_malloc(c->allocr, sizeof *out->slice); + copy_type(c, out->slice, in->slice); break; case TYPE_STRUCT: { size_t nfields = arr_len(in->struc.fields); out->struc.fields = NULL; - arr_set_lena(&out->struc.fields, nfields, a); + arr_set_lena(&out->struc.fields, nfields, c->allocr); for (size_t i = 0; i < nfields; i++) { Field *fout = &out->struc.fields[i]; Field *fin = &in->struc.fields[i]; *fout = *fin; - copy_type(a, fout->type, fin->type); + copy_type(c, fout->type, fin->type); } } break; } } -static void copy_fn_expr(Allocator *a, FnExpr *fout, FnExpr *fin, bool copy_body) { +static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, bool copy_body) { + *fout = *fin; size_t i; size_t nparam_decls = arr_len(fin->params); fout->params = NULL; - arr_set_lena(&fout->params, nparam_decls, a); + arr_set_lena(&fout->params, nparam_decls, c->allocr); for (i = 0; i < nparam_decls; i++) - copy_decl(a, fout->params + i, fin->params + i); + copy_decl(c, fout->params + i, fin->params + i); size_t nret_decls = arr_len(fin->ret_decls); - fout->ret_decls = NULL; - arr_set_lena(&fout->ret_decls, nret_decls, a); - for (i = 0; i < nret_decls; i++) - copy_decl(a, fout->ret_decls + i, fin->ret_decls + i); - copy_type(a, &fout->ret_type, &fin->ret_type); + if (fin->ret_decls) { + fout->ret_decls = NULL; + arr_set_lena(&fout->ret_decls, nret_decls, c->allocr); + for (i = 0; i < nret_decls; i++) + copy_decl(c, fout->ret_decls + i, fin->ret_decls + i); + } + copy_type(c, &fout->ret_type, &fin->ret_type); if (copy_body) - copy_block(a, &fout->body, &fin->body); + copy_block(c, &fout->body, &fin->body); } -static void copy_expr(Allocator *a, Expression *out, Expression *in) { +static void copy_expr(Copier *c, Expression *out, Expression *in) { + Allocator *a = c->allocr; *out = *in; switch (in->kind) { case EXPR_LITERAL_FLOAT: @@ -118,99 +127,99 @@ static void copy_expr(Allocator *a, Expression *out, Expression *in) { case EXPR_IDENT: break; case EXPR_UNARY_OP: - copy_expr(a, out->unary.of = allocr_malloc(a, sizeof *out->unary.of), in->unary.of); + copy_expr(c, out->unary.of = allocr_malloc(a, sizeof *out->unary.of), in->unary.of); break; case EXPR_BINARY_OP: - copy_expr(a, out->binary.lhs = allocr_malloc(a, sizeof *out->binary.lhs), in->binary.lhs); - copy_expr(a, out->binary.rhs = allocr_malloc(a, sizeof *out->binary.rhs), in->binary.rhs); + copy_expr(c, out->binary.lhs = allocr_malloc(a, sizeof *out->binary.lhs), in->binary.lhs); + copy_expr(c, out->binary.rhs = allocr_malloc(a, sizeof *out->binary.rhs), in->binary.rhs); break; case EXPR_IF: { IfExpr *iin = &in->if_; IfExpr *iout = &out->if_; if (iin->cond) - copy_expr(a, iout->cond = allocr_malloc(a, sizeof *iout->cond), iin->cond); + copy_expr(c, iout->cond = allocr_malloc(a, sizeof *iout->cond), iin->cond); if (iin->next_elif) - copy_expr(a, iout->next_elif = allocr_malloc(a, sizeof *iout->next_elif), iin->next_elif); - copy_block(a, &iout->body, &iin->body); + copy_expr(c, iout->next_elif = allocr_malloc(a, sizeof *iout->next_elif), iin->next_elif); + copy_block(c, &iout->body, &iin->body); } break; case EXPR_WHILE: { WhileExpr *win = &in->while_; WhileExpr *wout = &out->while_; if (win->cond) - copy_expr(a, wout->cond = allocr_malloc(a, sizeof *wout->cond), win->cond); - copy_block(a, &wout->body, &win->body); + copy_expr(c, wout->cond = allocr_malloc(a, sizeof *wout->cond), win->cond); + copy_block(c, &wout->body, &win->body); } break; case EXPR_EACH: { EachExpr *ein = &in->each; EachExpr *eout = &out->each; - copy_type(a, &eout->type, &ein->type); + copy_type(c, &eout->type, &ein->type); if (ein->flags & EACH_IS_RANGE) { - copy_expr(a, eout->range.from = allocr_malloc(a, sizeof *eout->range.from), ein->range.from); + copy_expr(c, eout->range.from = allocr_malloc(a, sizeof *eout->range.from), ein->range.from); if (ein->range.to) - copy_expr(a, eout->range.to = allocr_malloc(a, sizeof *eout->range.to), ein->range.to); + copy_expr(c, eout->range.to = allocr_malloc(a, sizeof *eout->range.to), ein->range.to); if (ein->range.step) - copy_expr(a, eout->range.step = allocr_malloc(a, sizeof *eout->range.step), ein->range.step); + copy_expr(c, eout->range.step = allocr_malloc(a, sizeof *eout->range.step), ein->range.step); } else { - copy_expr(a, eout->of = allocr_malloc(a, sizeof *eout->of), ein->of); + copy_expr(c, eout->of = allocr_malloc(a, sizeof *eout->of), ein->of); } - copy_block(a, &eout->body, &ein->body); + copy_block(c, &eout->body, &ein->body); } break; case EXPR_FN: - copy_fn_expr(a, &out->fn, &in->fn, true); + copy_fn_expr(c, &out->fn, &in->fn, true); break; case EXPR_CAST: { CastExpr *cin = &in->cast; CastExpr *cout = &out->cast; - copy_type(a, &cout->type, &cin->type); - copy_expr(a, cout->expr = allocr_malloc(a, sizeof *cout->expr), cin->expr); + copy_type(c, &cout->type, &cin->type); + copy_expr(c, cout->expr = allocr_malloc(a, sizeof *cout->expr), cin->expr); } break; case EXPR_NEW: { NewExpr *nin = &in->new; NewExpr *nout = &out->new; - copy_type(a, &nout->type, &nin->type); - if (nin->n) copy_expr(a, nout->n = allocr_malloc(a, sizeof *nout->n), nin->n); + copy_type(c, &nout->type, &nin->type); + if (nin->n) copy_expr(c, nout->n = allocr_malloc(a, sizeof *nout->n), nin->n); } break; case EXPR_CALL: { CallExpr *cin = &in->call; CallExpr *cout = &out->call; - copy_expr(a, cout->fn = allocr_malloc(a, sizeof *cout->fn), cin->fn); + copy_expr(c, cout->fn = allocr_malloc(a, sizeof *cout->fn), cin->fn); size_t nargs = arr_len(cin->arg_exprs); cout->arg_exprs = NULL; arr_set_lena(&cout->arg_exprs, nargs, a); for (size_t i = 0; i < nargs; i++) { - copy_expr(a, cout->arg_exprs + i, cin->arg_exprs + i); + copy_expr(c, cout->arg_exprs + i, cin->arg_exprs + i); } } break; case EXPR_BLOCK: - copy_block(a, &out->block, &in->block); + copy_block(c, &out->block, &in->block); break; case EXPR_TUPLE: { size_t nexprs = arr_len(in->tuple); out->tuple = NULL; arr_set_lena(&out->tuple, nexprs, a); for (size_t i = 0; i < nexprs; i++) - copy_expr(a, out->tuple + i, in->tuple + i); + copy_expr(c, out->tuple + i, in->tuple + i); } break; case EXPR_C: - copy_expr(a, out->c.code = allocr_malloc(a, sizeof *out->c.code), in->c.code); + copy_expr(c, out->c.code = allocr_malloc(a, sizeof *out->c.code), in->c.code); break; case EXPR_DSIZEOF: - copy_expr(a, out->dsizeof.of = allocr_malloc(a, sizeof *out->dsizeof.of), in->dsizeof.of); + copy_expr(c, out->dsizeof.of = allocr_malloc(a, sizeof *out->dsizeof.of), in->dsizeof.of); break; case EXPR_DALIGNOF: - copy_expr(a, out->dalignof.of = allocr_malloc(a, sizeof *out->dalignof.of), in->dalignof.of); + copy_expr(c, out->dalignof.of = allocr_malloc(a, sizeof *out->dalignof.of), in->dalignof.of); break; case EXPR_SLICE: { SliceExpr *sin = &in->slice; SliceExpr *sout = &out->slice; - copy_expr(a, sout->of = allocr_malloc(a, sizeof *sout->of), sin->of); + copy_expr(c, sout->of = allocr_malloc(a, sizeof *sout->of), sin->of); if (sin->from) - copy_expr(a, sout->from = allocr_malloc(a, sizeof *sout->from), sin->from); + copy_expr(c, sout->from = allocr_malloc(a, sizeof *sout->from), sin->from); if (sin->to) - copy_expr(a, sout->to = allocr_malloc(a, sizeof *sout->to), sin->to); + copy_expr(c, sout->to = allocr_malloc(a, sizeof *sout->to), sin->to); } break; case EXPR_TYPE: - copy_type(a, &out->typeval, &in->typeval); + copy_type(c, &out->typeval, &in->typeval); break; case EXPR_VAL: copy_val(a, &out->val, &in->val, &in->type); @@ -218,41 +227,48 @@ static void copy_expr(Allocator *a, Expression *out, Expression *in) { } } -static void copy_decl(Allocator *a, Declaration *out, Declaration *in) { +static void copy_decl(Copier *c, Declaration *out, Declaration *in) { *out = *in; + assert(!(in->flags & DECL_FOUND_TYPE)); + if (in->flags & DECL_HAS_EXPR) - copy_expr(a, &out->expr, &in->expr); + copy_expr(c, &out->expr, &in->expr); if (in->flags & DECL_FOUND_VAL) { - copy_val(a, &out->val, &in->val, &in->type); + copy_val(c->allocr, &out->val, &in->val, &in->type); } if (in->flags & DECL_ANNOTATES_TYPE) - copy_type(a, &out->type, &in->type); + copy_type(c, &out->type, &in->type); } -static void copy_stmt(Allocator *a, Statement *out, Statement *in) { +static void copy_stmt(Copier *c, Statement *out, Statement *in) { *out = *in; - assert(!(in->decl.flags & DECL_FOUND_TYPE)); switch (in->kind) { case STMT_RET: if (in->flags & RET_HAS_EXPR) - copy_expr(a, &out->ret.expr, &in->ret.expr); + copy_expr(c, &out->ret.expr, &in->ret.expr); break; case STMT_EXPR: - copy_expr(a, &out->expr, &in->expr); + copy_expr(c, &out->expr, &in->expr); break; case STMT_DECL: - copy_decl(a, &out->decl, &in->decl); + copy_decl(c, &out->decl, &in->decl); break; } } -static void copy_block(Allocator *a, Block *out, Block *in) { +static void copy_block(Copier *c, Block *out, Block *in) { *out = *in; size_t nstmts = arr_len(in->stmts); out->stmts = NULL; - arr_set_lena(&out->stmts, nstmts, a); + out->parent = c->block; + c->block = out; + if (in->ret_expr) + copy_expr(c, out->ret_expr = allocr_malloc(c->allocr, sizeof *out->ret_expr), in->ret_expr); + + arr_set_lena(&out->stmts, nstmts, c->allocr); for (size_t i = 0; i < nstmts; i++) { - copy_stmt(a, &out->stmts[i], &in->stmts[i]); + copy_stmt(c, &out->stmts[i], &in->stmts[i]); } + c->block = out->parent; } diff --git a/decls_cgen.c b/decls_cgen.c index 19eb0bc..f07b17e 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -73,11 +73,9 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) { if (!cgen_fn_header(g, &d->expr.fn, d->where, 0, 0)) return false; cgen_write(g, ";"); - cgen_nl(g); + fn_exit(&d->expr.fn); } - if (!cgen_decls_block(g, &d->expr.fn.body)) - return false; - fn_exit(&d->expr.fn); + cgen_recurse_subexprs(g, (&d->expr), cgen_decls_expr, cgen_decls_block, cgen_decls_decl); } else if (d->flags & DECL_HAS_EXPR) { if (d->flags & DECL_IS_CONST) { for (size_t idx = 0; idx < arr_len(d->idents); idx++) { diff --git a/main.c b/main.c index cc3c36c..b59d7ab 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /* TODO: deal with typing functions with type parameters (we need to type every single instance) -do typedefs for each instance +don't cgen decls etc. in parameter initializers struct parameters don't allow while {3; 5} (once break is added) diff --git a/test.toc b/test.toc index 1ea719b..8adf650 100644 --- a/test.toc +++ b/test.toc @@ -2,17 +2,17 @@ puti @= fn(x: int) { #C("printf(\"%ld\\n\", (long)x); "); }; -// putf @= fn(x: float) { - // #C("printf(\"%f\\n\", (double)x); -// "); -// }; +putf @= fn(x: float) { + #C("printf(\"%f\\n\", (double)x); +"); +}; -// main @= fn() { -// puti(f(17)); -// }; +main @= fn() { + puti(g(int)); +}; -// f @= fn(k @ int) int { -// k -// }; \ No newline at end of file +g @= fn(t @ Type) int { + 87347 as t as int +}; \ No newline at end of file diff --git a/tokenizer.c b/tokenizer.c index 342bbd7..6481cfb 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -214,7 +214,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { case '/': /* single line comment */ tokr_nextchar(t); for (t->s++; *t->s && *t->s != '\n'; t->s++); - if (t->s) tokr_nextchar(t); /* skip newline */ + if (*t->s) tokr_nextchar(t); /* skip newline */ break; case '*': { /* multi line comment */ tokr_nextchar(t); diff --git a/types.c b/types.c index 89587f3..c607f2f 100644 --- a/types.c +++ b/types.c @@ -191,7 +191,8 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) if (!(flags & TYPE_OF_FN_NO_COPY_EVEN_IF_CONST) && fn_has_any_const_params(f)) { /* OPTIM don't copy so much */ newf = typer_malloc(tr, sizeof *newf); - copy_fn_expr(tr->allocr, newf, f, false); + Copier cop = {.block = f->body.parent, .allocr = tr->allocr}; + copy_fn_expr(&cop, newf, f, false); f = newf; } @@ -607,7 +608,8 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, assert(t->kind == TYPE_FN); if (instance) { - copy_fn_expr(tr->allocr, &instance->fn, f, true); + Copier cop = {.allocr = tr->allocr, .block = f->body.parent}; + copy_fn_expr(&cop, &instance->fn, f, true); f = &instance->fn; Value *compile_time_args = instance->val.tuple; U64 which_are_const = compile_time_args[0].u64; @@ -1162,11 +1164,14 @@ static bool types_expr(Typer *tr, Expression *e) { bool instance_already_exists; c->instance = instance_table_adda(tr->allocr, &fn->instances, table_index, &table_index_type, &instance_already_exists); - c->instance->c.id = fn->instances.n; /* let's help cgen out and assign an ID to this */ - arr_clear(&table_index_type.tuple); - /* type this instance */ - if (!types_fn(tr, fn, &f->type, e->where, c->instance)) - return false; + if (!instance_already_exists) { + c->instance->c.id = fn->instances.n; /* let's help cgen out and assign an ID to this */ + + /* type this instance */ + if (!types_fn(tr, fn, &f->type, e->where, c->instance)) + return false; + arr_clear(&table_index_type.tuple); + } } *t = *ret_type; c->arg_exprs = new_args; @@ -1702,7 +1707,7 @@ static bool types_stmt(Typer *tr, Statement *s) { return false; } if (s->expr.type.kind == TYPE_TUPLE) { - err_print(s->where, "Statement of a tuple is not allowed. The comma operator does not exist in toc; use a semicolon instead."); + err_print(s->where, "Statement of a tuple is not allowed. Use a semicolon instead of a comma here."); return false; } break; -- cgit v1.2.3