From 1111a904dfa39bf74742549ed5a5a6d205c4b36f Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 13 Oct 2022 12:12:26 +0200 Subject: [PATCH] array#fill -> array#new --- pez.c | 40 +++++++++++++++++++++++++++------------- test.pez | 4 ++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/pez.c b/pez.c index 790ddab..591b760 100644 --- a/pez.c +++ b/pez.c @@ -2039,20 +2039,20 @@ f_dilambda(PezContext *cx, int argc) } static bool -f_arrayfill(PezContext *cx, int argc) +f_arraynew(PezContext *cx, int argc) { fixnum n; Array *arr; - TRY(pez_checksig(cx, argc, "array#fill", "number, any")); - n = unbox_num(cx->stktop[-2]); + TRY(pez_checksig(cx, argc, "array#new", "number, ?any")); + n = unbox_num(cx->stktop[-argc]); if (n < 0 || fixtrunc(n) != n) { - pez_error(cx, "array#fill", "argument #1 should be positive integer"); + pez_error(cx, "array#new", "argument #0 should be positive integer"); return 0; } TRY(arr = newarr(cx, fixtoint(n))); arr->len = fixtoint(n); for (int i = 0; i < fixtoint(n); ++i) { - arr->dat[i] = cx->stktop[-1]; + arr->dat[i] = argc == 2 ? cx->stktop[-1] : VOID; } return push(cx, box_obj(arr)); } @@ -2071,7 +2071,7 @@ static const struct coredef { const char *n; PezCFn *f; } core[] = { { "printf", f_printf }, { "sprintf", f_sprintf }, { "dilambda", f_dilambda }, - { "array#fill", f_arrayfill }, + { "array#new", f_arraynew }, { "array#push", f_arraypush }, }; @@ -4107,11 +4107,21 @@ skipspaces(const char **s) } static const char * -sigget(const char **s) +sigget(const char **s, bool *opt) { - const char *t = *s; - assert((*t == '*' || aisalpha(*t)) && "bad sig"); + const char *t; + t = *s; + assert((*t == '*' || aisalpha(*t) || *t == '?') && "bad sig"); for (; **s && !aissep(**s); ++*s) ; + *opt = 0; + if (*t == '?') { + ++(*s); + skipspaces(s); + t = *s; + for (; **s && !aissep(**s); ++*s) ; + assert(aisalpha(*t) && "bad sig"); + *opt = 1; + } return t; } @@ -4128,7 +4138,8 @@ pez_checksig(PezContext *cx, int argc, const char *fn, const char *sig) int typ; typ = 1 << pez_typeof(cx, -argc + arg); do { - const char *t = sigget(&sig); + bool opt; + const char *t = sigget(&sig, &opt); if (!strncmp(t, "any", 3)) mask |= ~0u; else if (!strncmp(t, "void", 4)) mask |= 1 << PEZ_TVoid; else if (!strncmp(t, "number", 6)) mask |= 1 << PEZ_TNumber; @@ -4151,8 +4162,11 @@ pez_checksig(PezContext *cx, int argc, const char *fn, const char *sig) } else assert(0 && "bad sig type"); if (arg >= argc) { - pez_error(cx, fn, "too few args for [%s] (got %d)", osig, argc); - return 0; + if (opt) { + break; + } else { + return pez_error(cx, fn, "too few args for [%s] (got %d)", osig, argc), 0; + } } thisn = sig - this; assert(!*sig || *sig == '|' || *sig == ','); @@ -4171,7 +4185,7 @@ pez_checksig(PezContext *cx, int argc, const char *fn, const char *sig) } skipspaces(&sig); } - if (arg != argc) { + if (arg < argc) { pez_error(cx, fn, "too many args for [%s] (got %d)", osig, argc); return 0; } diff --git a/test.pez b/test.pez index e4542d0..7f35b30 100644 --- a/test.pez +++ b/test.pez @@ -6,7 +6,7 @@ } @Array2d: {[w, h] - @data: array#fill[w * h, 0] + @data: array#new[w * h, 0] dilambda[ {[x, y] data[x + (y * w)] }, {[x, y, new] data[x + (y * w)] = new } @@ -44,7 +44,7 @@ printf["4+1+3: %a\n", add[4,1,3]] printf["test %a\n", gather[-1, (), 'x]] @map: {[f, xs] - @ys: array#filled[xs.len, ()] + @ys: array#new[xs.len] FOR [@i: 0][< xs.len][+ 1] ys[i] = f[xs[i]] ys -- 2.38.5