summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--allocator.c7
-rw-r--r--copy.c30
-rw-r--r--eval.c12
-rw-r--r--infer.c2
-rw-r--r--main.c2
-rw-r--r--parse.c11
-rw-r--r--test.toc2
-rw-r--r--toc.c2
-rw-r--r--types.c12
10 files changed, 48 insertions, 34 deletions
diff --git a/README.md b/README.md
index 745b880..a843c2f 100644
--- a/README.md
+++ b/README.md
@@ -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;
diff --git a/copy.c b/copy.c
index 07b003b..6f39dab 100644
--- a/copy.c
+++ b/copy.c
@@ -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);
diff --git a/eval.c b/eval.c
index 9f3d461..d8b66a7 100644
--- a/eval.c
+++ b/eval.c
@@ -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 {
diff --git a/infer.c b/infer.c
index bcb3103..544ca78 100644
--- a/infer.c
+++ b/infer.c
@@ -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;
}
diff --git a/main.c b/main.c
index 7f8c244..d6ea395 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/parse.c b/parse.c
index ba9904c..d5b21a4 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
diff --git a/test.toc b/test.toc
index 458e67b..da2dd79 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
diff --git a/toc.c b/toc.c
index 58c8aee..aed9423 100644
--- a/toc.c
+++ b/toc.c
@@ -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)
diff --git a/types.c b/types.c
index 9ad26ab..e43e6f8 100644
--- a/types.c
+++ b/types.c
@@ -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, &param_decl->val, &arg_val, type);
+ copy_val(tr->allocr, &param_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, &param->expr.val, &param->expr.type);
+ copy_val(tr->allocr, &arg_exprs[i].val, param->expr.val, &param->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;
}
}