diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-10 23:11:26 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-10 23:11:26 -0400 |
commit | 0469df66bd9c907b7a90241ab8ed7eb716d7f700 (patch) | |
tree | 28dd025f85b6bba9554e2ddaae256173e141280a | |
parent | 960583df2ff6f8baa205d0e1a5dd07667978b92a (diff) |
varargs seem to be fully working now
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | test.toc | 13 | ||||
-rw-r--r-- | types.c | 21 |
4 files changed, 25 insertions, 18 deletions
@@ -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]; @@ -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 */ @@ -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 @@ -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; } |