summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-10 23:11:26 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-10 23:11:26 -0400
commit0469df66bd9c907b7a90241ab8ed7eb716d7f700 (patch)
tree28dd025f85b6bba9554e2ddaae256173e141280a
parent960583df2ff6f8baa205d0e1a5dd07667978b92a (diff)
varargs seem to be fully working now
-rw-r--r--eval.c4
-rw-r--r--main.c5
-rw-r--r--test.toc13
-rw-r--r--types.c21
4 files changed, 25 insertions, 18 deletions
diff --git a/eval.c b/eval.c
index 184e86c..9f3d461 100644
--- a/eval.c
+++ b/eval.c
@@ -692,9 +692,9 @@ static Value *ident_val(Identifier i) {
else
return &decl->val;
}
- } else if (decl->flags & DECL_IS_CONST)
+ } else if (decl->flags & DECL_IS_CONST) {
return decl_val_at_index(decl, idx);
- else if (decl->val_stack) {
+ } else if (decl->val_stack) {
Value *valp = *(Value **)arr_last(decl->val_stack);
if (arr_len(decl->idents) > 1)
return &valp->tuple[idx];
diff --git a/main.c b/main.c
index 1cfb32e..2f596c4 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,7 @@
/*
TODO:
-fix compile time non-const varargs
+test for v := v (where v is a varargs param)
varargs only exist in decls. not a type of its own
don't allow default varargs
don't allow semiconst varargs
@@ -25,7 +25,6 @@ continue
switch
enums
typeof
-macros
unions
---
switch to / add as an alternative: libffi
@@ -36,6 +35,8 @@ allow omission of trailing ; in foo ::= fn() {...} or foo ::= nms {...} or foo :
consider- should #sizeof always take a Type? it would be more verbose, but we might not actually need
#sizeof that much, given that we have new.
it probably should, because #sizeof(x[0]) can't be evaluated at compile time if x is not a constant
+---
+macros
*/
diff --git a/test.toc b/test.toc
index 52672d8..03b1158 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 a := x {
total += a as int;
@@ -8,13 +8,12 @@ f ::= fn(x : ..) int {
total
};
+
main ::= fn() {
puti(f(1,2,3));
- puti(f(1,2,3,4,5,6));
puti(f(1,2,3,4));
- puti(f(1,7,3));
- puti(f(1,2,4,4,5,6));
- puti(f(1,2,-7.3,4.656));
+ puti(f(1,2,3,5,6));
+ puti(f(1,2,3,1,2));
+};
- puti(f(7.3,4.656));
-}; \ No newline at end of file
+main(); \ No newline at end of file
diff --git a/types.c b/types.c
index 0cecd09..08c395b 100644
--- a/types.c
+++ b/types.c
@@ -1585,13 +1585,15 @@ static Status types_expr(Typer *tr, Expression *e) {
case TYPE_BUILTIN:
switch (iter_type->builtin) {
case BUILTIN_VARARGS: {
+ /* exit for body */
+ typer_block_exit(tr);
arr_remove_lasta(&tr->in_exprs, tr->allocr);
/* create one block, containing a block for each vararg */
/* e.g. for x := varargs { total += x; } => { { x := varargs[0]; total += x; } { x := varargs[0]; total += x; } } */
assert(fo->of->kind == EXPR_IDENT);
- Identifier ident = fo->of->ident;
- assert(ident->decl_kind == IDECL_DECL);
- Declaration *idecl = ident->decl;
+ Identifier varargs_ident = fo->of->ident;
+ assert(varargs_ident->decl_kind == IDECL_DECL);
+ Declaration *idecl = varargs_ident->decl;
VarArg *varargs = idecl->val.varargs;
size_t nvarargs = arr_len(varargs);
/* create surrounding block */
@@ -1619,16 +1621,19 @@ static Status types_expr(Typer *tr, Expression *e) {
arr_set_lena(&sub->stmts, total_nstmts, tr->allocr);
Copier copier = copier_create(tr->allocr, sub);
if (has_val) {
- /* TODO: don't put a decl in each block, just put one at the start */
+ /* TODO(eventually): don't put a decl in each block, just put one at the start */
sub->stmts[0].flags = 0;
sub->stmts[0].kind = STMT_DECL;
sub->stmts[0].where = e->where;
+
/* declare value */
Declaration *decl = sub->stmts[0].decl = typer_calloc(tr, 1, sizeof *decl);
decl->where = fo->of->where;
- *(Identifier *)arr_adda(&decl->idents, tr->allocr) = fo->value;
- fo->value->decl_kind = IDECL_DECL;
- fo->value->decl = decl;
+ Identifier ident = ident_translate_forced(fo->value, &sub->idents);
+ *(Identifier *)arr_adda(&decl->idents, tr->allocr) = ident;
+ ident->decl_kind = IDECL_DECL;
+ ident->decl = decl;
+
decl->flags |= DECL_HAS_EXPR;
decl->expr.kind = EXPR_BINARY_OP;
decl->expr.binary.op = BINARY_AT_INDEX;
@@ -3154,6 +3159,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
}
}
if (tr->block == NULL) {
+ /* evaluate expression statements at global scope */
if (s->expr.kind != EXPR_C) {
if (!eval_stmt(tr->evalr, s))
return false;
@@ -3274,5 +3280,6 @@ static Status types_file(Typer *tr, ParsedFile *f) {
ret = false;
}
}
+ assert(tr->block == NULL);
return ret;
}