diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | allocator.c | 7 | ||||
-rw-r--r-- | copy.c | 30 | ||||
-rw-r--r-- | eval.c | 12 | ||||
-rw-r--r-- | infer.c | 2 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 11 | ||||
-rw-r--r-- | test.toc | 2 | ||||
-rw-r--r-- | toc.c | 2 | ||||
-rw-r--r-- | types.c | 12 |
10 files changed, 48 insertions, 34 deletions
@@ -91,6 +91,6 @@ Here are the major versions of `toc`. ### Report a bug -If you find a bug, you can report it through [GitHub's issue tracker](https://github.com/pommicket/toc/issues), or by emailing pommicket@pommicket.com. +If you find a bug, you can report it through [GitHub's issue tracker](https://github.com/pommicket/toc/issues), or by emailing pommicket at pommicket dot com. Just send me the `toc` source code which results in the bug, and I'll try to fix it. diff --git a/allocator.c b/allocator.c index fae828a..8baedb5 100644 --- a/allocator.c +++ b/allocator.c @@ -107,13 +107,6 @@ static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t ne return ret; } -static char *allocr_strdup(Allocator *a, char const *s) { - size_t len = strlen(s); - char *ret = allocr_malloc(a, len); - memcpy(ret, s, len); - return ret; -} - static void allocr_free_all(Allocator *a) { for (Page *page = a->first; page;) { Page *next = page->next; @@ -34,31 +34,43 @@ static Copier copier_create(Allocator *a, Block *b) { return c; } -static void copy_val(Allocator *a, Value *out, Value *in, Type *t) { +static void copy_val(Allocator *a, Value *out, Value in, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { case TYPE_BUILTIN: + if (t->builtin == BUILTIN_VARARGS) { + size_t n = arr_len(in.varargs); + out->varargs = NULL; + arr_set_lena(&out->varargs, n, a); + for (size_t i = 0; i < n; ++i) { + Copier c = copier_create(a, NULL); /* since the type is resolved, it doesn't matter that the block is wrong */ + out->varargs[i].type = copy_type_(&c, in.varargs[i].type); + out->varargs[i].val = in.varargs[i].val; + } + break; + } + /* fallthrough */ case TYPE_FN: case TYPE_PTR: case TYPE_SLICE: case TYPE_VOID: case TYPE_UNKNOWN: - *out = *in; + *out = in; break; case TYPE_ARR: { size_t bytes = (size_t)t->arr.n * compiler_sizeof(t->arr.of); out->arr = allocr_malloc(a, bytes); - memcpy(out->arr, in->arr, 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(a, bytes); - memcpy(out->tuple, in->tuple, bytes); + memcpy(out->tuple, in.tuple, bytes); } break; case TYPE_STRUCT: { size_t bytes = compiler_sizeof(t); out->struc = allocr_malloc(a, bytes); - memcpy(out->struc, in->struc, bytes); + memcpy(out->struc, in.struc, bytes); } break; case TYPE_EXPR: assert(0); @@ -66,10 +78,10 @@ static void copy_val(Allocator *a, Value *out, Value *in, Type *t) { } } -static void copy_val_full(Copier *c, Value *out, Value *in, Type *t) { +static void copy_val_full(Copier *c, Value *out, Value in, Type *t) { if (type_is_builtin(t, BUILTIN_TYPE)) { Type *new_type = allocr_malloc(c->allocr, sizeof *new_type); - copy_type(c, new_type, in->type); + copy_type(c, new_type, in.type); out->type = new_type; } else { copy_val(c->allocr, out, in, t); @@ -361,7 +373,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) { copy_type(c, out->typeval = copier_malloc(c, sizeof *out->typeval), in->typeval); break; case EXPR_VAL: - copy_val(a, &out->val, &in->val, &in->type); + copy_val(a, &out->val, in->val, &in->type); break; case EXPR_NMS: out->nms = allocr_malloc(a, sizeof *out->nms); @@ -384,7 +396,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->allocr, &out->val, in->val, &in->type); } if (in->flags & DECL_ANNOTATES_TYPE) copy_type(c, &out->type, &in->type); @@ -1466,7 +1466,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; Type *type = is_tuple ? &p->type.tuple[idx] : &p->type; Value *ival = multiple_idents ? &pval->tuple[idx] : pval; - copy_val(NULL, ival, &arg_val, type); + copy_val(NULL, ival, arg_val, type); ++arg; ++idx; } @@ -1516,7 +1516,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; Value *element = arr_add(&tuple); Type *type = decl_type_at_index(d, i); - copy_val(NULL, element, &this_one, type); + copy_val(NULL, element, this_one, type); ++i; } } @@ -1622,11 +1622,11 @@ static Status eval_decl(Evaluator *ev, Declaration *d) { Type *type = decl_type_at_index(d, index); if (!is_const) { if (has_expr) { - Value *v = is_tuple ? &val.tuple[index] : &val; + Value v = is_tuple ? val.tuple[index] : val; if (need_to_copy) { copy_val(NULL, ival, v, type); } else { - *ival = *v; + *ival = v; } } else { *ival = val_zero(type); @@ -1654,7 +1654,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { Value r; if (!eval_expr(ev, &stmt->ret.expr, &r)) return false; - copy_val(NULL, &ev->ret_val, &r, &stmt->ret.expr.type); + copy_val(NULL, &ev->ret_val, r, &stmt->ret.expr.type); } break; case STMT_INCLUDE: arr_foreach(stmt->inc.stmts, Statement, sub) @@ -1695,7 +1695,7 @@ static Status eval_block(Evaluator *ev, Block *b, Value *v) { } if (!type_is_builtin(&b->ret_expr->type, BUILTIN_TYPE)) { /* make a copy so that r's data isn't freed when we exit the block */ - copy_val(NULL, v, &r, &b->ret_expr->type); + copy_val(NULL, v, r, &b->ret_expr->type); if (b->ret_expr->kind == EXPR_TUPLE) free(r.tuple); } else { @@ -24,7 +24,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi return false; Copier c = copier_create(tr->allocr, tr->block); Value new_val; - copy_val_full(&c, &new_val, &vals[idx], &to->type); + copy_val_full(&c, &new_val, vals[idx], &to->type); vals[idx] = new_val; break; } @@ -8,12 +8,12 @@ /* TODO: -don't allow default varargs don't allow semiconst varargs don't allow struct varargs (yet) make sure varargs[i] isn't an lvalue make sure you can't have a variadic function pointer make sure varargs works with inference +passing varargs variable to varargs function #foreign variadic fns EXPR_VALs don't always need temp variables where @@ -2224,6 +2224,8 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f d->flags = 0; d->val_stack = NULL; + bool is_varargs = false; + if ((flags & PARSE_DECL_ALLOW_EXPORT) && token_is_direct(t->token, DIRECT_EXPORT)) { d->flags |= DECL_EXPORT; ++t->token; @@ -2283,6 +2285,7 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f d->type.flags = 0; d->type.was_expr = NULL; d->type.builtin = BUILTIN_VARARGS; + is_varargs = true; ++t->token; } else { Type type; @@ -2316,6 +2319,10 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f tokr_err(t, "Inferred parameters must be constant."); goto ret_false; } + if (is_varargs) { + tokr_err(t, "Varargs cannot be inferred."); + goto ret_false; + } ++t->token; } else { d->flags |= DECL_HAS_EXPR; @@ -2324,6 +2331,10 @@ static Status parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 f expr_flags |= EXPR_CAN_END_WITH_COMMA; if (ends_with == DECL_END_LBRACE_COMMA) expr_flags |= EXPR_CAN_END_WITH_LBRACE | EXPR_CAN_END_WITH_COMMA; + if (is_varargs) { + tokr_err(t, "Default varargs are not allowed."); + goto ret_false; + } Token *end = expr_find_end(p, expr_flags); if (!end || !ends_decl(end, ends_with)) { if (end) t->token = end; @@ -1,6 +1,6 @@ #include "std/io.toc"; -f ::= fn(x :: ..) int { +f ::= fn(x : ..) int { total := 0; for _, i := x { total += i * (x[0] as int); @@ -97,8 +97,6 @@ static void print_block_location(Block *b); /* misc */ -#define STRINGIFY2(x) #x -#define STRINGIFY(x) STRINGIFY2(x) #define join3(a,b) a##b #define join2(a,b) join3(a,b) #define join(a,b) join2(a,b) @@ -2256,7 +2256,7 @@ static Status types_expr(Typer *tr, Expression *e) { arg_exprs[i].flags = EXPR_FOUND_TYPE; arg_exprs[i].val = arg_val; param_decl->flags |= DECL_FOUND_VAL; - copy_val(tr->allocr, ¶m_decl->val, &arg_val, type); + copy_val(tr->allocr, ¶m_decl->val, arg_val, type); if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) { param_decl->type = *type; } @@ -2289,7 +2289,7 @@ static Status types_expr(Typer *tr, Expression *e) { assert(param->flags & DECL_HAS_EXPR); assert(param->expr.kind == EXPR_VAL); /* this was done by type_of_fn */ arg_exprs[i] = param->expr; - copy_val(tr->allocr, &arg_exprs[i].val, ¶m->expr.val, ¶m->expr.type); + copy_val(tr->allocr, &arg_exprs[i].val, param->expr.val, ¶m->expr.type); } } ++i; @@ -2360,7 +2360,7 @@ static Status types_expr(Typer *tr, Expression *e) { VarArg *varg = typer_arr_add(tr, &varargs_val->varargs); varg->type = copy_type_(&cop, &arg->type); if (is_const) { - copy_val(tr->allocr, &varg->val, &arg->val, varg->type); + copy_val(tr->allocr, &varg->val, arg->val, varg->type); } else { /* use zero value everywhere */ varg->val = val_zero(varg->type); @@ -2379,7 +2379,7 @@ static Status types_expr(Typer *tr, Expression *e) { Value *v = typer_arr_add(tr, &table_index.tuple); Type *type = typer_arr_add(tr, &table_index_type.tuple); copy_type(&cop, type, &arg->type); - copy_val(tr->allocr, v, &arg->val, type); + copy_val(tr->allocr, v, arg->val, type); } } bool instance_already_exists; @@ -2778,7 +2778,7 @@ static Status types_expr(Typer *tr, Expression *e) { /* replace with value */ e->kind = EXPR_VAL; e->type = *vararg->type; - copy_val(tr->allocr, &e->val, &vararg->val, &e->type); + copy_val(tr->allocr, &e->val, vararg->val, &e->type); } else { /* just use vararg's type */ rhs->kind = EXPR_VAL; @@ -3057,7 +3057,7 @@ static Status types_decl(Typer *tr, Declaration *d) { success = false; goto ret; } - copy_val(tr->allocr, &d->val, &val, &d->type); + copy_val(tr->allocr, &d->val, val, &d->type); d->flags |= DECL_FOUND_VAL; } } |