diff options
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | test.toc | 29 | ||||
-rw-r--r-- | tests/varargs.toc | 8 | ||||
-rw-r--r-- | types.c | 33 |
4 files changed, 47 insertions, 24 deletions
@@ -8,7 +8,6 @@ /* TODO: -varargs len make new and del functions! where #returns_code (function/struct body is a block, to be evaluated at compile time, which returns the actual statements -- you can use this for implementation of printf) @@ -1,10 +1,33 @@ printf ::= #foreign("printf","libc.so.6") fn(#C &"const char", #C ..) #C int; +tprintf ::= fn(fmt: []char, args: ..) { + printf(&fmt[0], args); +}; + +sum ::= fn(x: ..) int { + total := 0; + for a, i := x { + total += a + i - i + 1; + } + total - x.len +}; + +sumc ::= fn(x:: ..) int { + total := 0; + for a, i := x { + total += a + i - i + 1; + } + total - x.len +}; -f ::= fn(x: int, y: int) int { - x+y +do_printing ::= fn(x::..) { + tprintf("%ld\n",sum(x)); + tprintf("%ld\n",sumc(x)); }; main ::= fn() { - f(3,4 as typeof f(3,4)); + do_printing(); + do_printing(1,2,3); + do_printing(4); + do_printing(1,10,100,1000,10000); }; diff --git a/tests/varargs.toc b/tests/varargs.toc index 8709a64..0885da4 100644 --- a/tests/varargs.toc +++ b/tests/varargs.toc @@ -6,22 +6,18 @@ tprintf ::= fn(fmt: []char, args: ..) { sum ::= fn(x: ..) int { total := 0; - n := 0; for a, i := x { total += a + i - i + 1; - n += 1; } - total - n + total - x.len }; sumc ::= fn(x:: ..) int { total := 0; - n := 0; for a, i := x { total += a + i - i + 1; - n += 1; } - total - n + total - x.len }; do_printing ::= fn(x::..) { @@ -2585,14 +2585,7 @@ static Status types_expr(Typer *tr, Expression *e) { t->builtin = BUILTIN_BOOL; break; case UNARY_LEN: - t->kind = TYPE_BUILTIN; - t->builtin = BUILTIN_I64; - if (of_type->kind != TYPE_SLICE || of_type->kind != TYPE_ARR) { - char *s = type_to_str(of_type); - err_print(e->where, "Cannot get length of non-array, non-slice type %s.", s); - free(s); - return false; - } + assert(0); /* types_expr is what makes things UNARY_LEN */ break; case UNARY_TYPEOF: { if (of->type.kind == TYPE_VOID) { @@ -2915,19 +2908,31 @@ static Status types_expr(Typer *tr, Expression *e) { return false; break; } - } else if (struct_type->kind == TYPE_SLICE || struct_type->kind == TYPE_ARR) { + } else if (struct_type->kind == TYPE_SLICE || struct_type->kind == TYPE_ARR || type_is_builtin(struct_type, BUILTIN_VARARGS)) { if (!ident_eq_str(rhs->ident, "len")) { - err_print(rhs->where, "Field of array or slice must be .len"); + char *s = type_to_str(struct_type); + err_print(rhs->where, "Field of %s must be .len", s); + free(s); return false; } /* length of slice/arr is i64 */ t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_I64; - /* change expr to UNARY_LEN */ - e->kind = EXPR_UNARY_OP; Expression *of = lhs; - e->unary.op = UNARY_LEN; - e->unary.of = of; + if (type_is_builtin(struct_type, BUILTIN_VARARGS)) { + /* replace with val */ + assert(of->kind == EXPR_IDENT); + Identifier ident = of->ident; + assert(ident->decl_kind == IDECL_DECL); + Declaration *decl = ident->decl; + e->kind = EXPR_VAL; + e->val.i64 = (I64)arr_len(decl->val.varargs); + } else { + /* change expr to UNARY_LEN */ + e->kind = EXPR_UNARY_OP; + e->unary.op = UNARY_LEN; + e->unary.of = of; + } } else if (type_is_builtin(struct_type, BUILTIN_NMS)) { Value nms_val; if (!eval_expr(tr->evalr, lhs, &nms_val)) |