X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=herp.c;fp=herp.c;h=0000000000000000000000000000000000000000;hb=cfdc1dc7ae5bdc755b92c639a6251ea06336da4e;hp=2b3ee4929e586b1fee558ab45e0dd461b0fa89c4;hpb=98e6239b969281c227be6ede859054786dd7b933;p=p5sagit%2FFunction-Parameters.git diff --git a/herp.c b/herp.c deleted file mode 100644 index 2b3ee49..0000000 --- a/herp.c +++ /dev/null @@ -1,164 +0,0 @@ - -#define DEFSTRUCT(T) typedef struct T T; struct T - -DEFSTRUCT(ParamInit) { - SV *name; - OP *init; -}; - -#define DEFVECTOR(T, B) DEFSTRUCT(T) { \ - B (*data); \ - size_t used, size; \ -} - -DEFVECTOR(ParamInitVec, ParamInit); -DEFVECTOR(ParamVec, SV *); - -DEFSTRUCT(ParamSpec) { - SV *invocant; - ParamVec positional_required; - ParamInitVec positional_optional; - ParamVec named_required; - ParamInitVec named_optional; - SV *slurpy; -}; - -#define DEFVECTOR_CLEAR(T, N, F) static void N(T *p) { \ - while (p->used) { \ - p->used--; \ - F(p->data[p->used]); \ - } \ - Safefree(p->data); \ - p->data =NULL; \ - p->size = 0; \ -} static void N(T *) - -static void pi_clear(ParamInit pi) { - if (pi.name) { - SvREFCNT_dec(pi.name); - } - if (pi.init) { - op_free(pi.init); - } -} - -DEFVECTOR_CLEAR(ParamVec, pv_clear, SvREFCNT_dec); -DEFVECTOR_CLEAR(ParamInitVec, piv_clear, pi_clear); - -static void ps_free(ParamSpec *ps) { - if (ps->invocant) { - SvREFCNT_dec(ps->invocant); - ps->invocant = NULL; - } - pv_clear(&ps->positional_required); - piv_clear(&ps->positional_optional); - pv_clear(&ps->named_required); - piv_clear(&ps->named_optional); - if (ps->slurpy) { - SvREFCNT_dec(ps->slurpy); - ps->slurpy = NULL; - } - Safefree(ps); -} - -static int args_min(const ParamSpec *ps) { - int n = 0; - if (ps->invocant) { - n++; - } - n += ps->positional_required.used; - n += ps->named_required.used * 2; - return n; -} - -static int args_max(const ParamSpec *ps) { - int n = 0; - if (ps->invocant) { - n++; - } - n += ps->positional_required.used; - n += ps->positional_optional.used; - if (ps->named_required.used || ps->named_optional.used || ps->slurpy) { - n = -1; - } - return n; -} - -static size_t count_positional_params(const ParamSpec *ps) { - return ps->positional_required.used + ps->positional_optional.used; -} - -static size_t count_named_params(const ParamSpec *ps) { - return ps->named_required.used + ps->named_optional.used; -} - -static void gen(ParamSpec *ps) { - int amin = args_min(ps); - if (amin > 0) { - printf("croak 'not enough' if @_ < %d;\n", amin); - } - int amax = args_max(ps); - if (amax >= 0) { - printf("croak 'too many' if @_ > %d;\n", amax); - } - size_t named_params = count_named_params(ps); - if (named_params || (ps->slurpy && SvPV_nolen(ps->slurpy)[0] == '%')) { - size_t t = named_params + !!ps->invocant; - printf("croak 'odd' if (@_ - %zu) > 0 && (@_ - %zu) % 2;\n", t, t); - } - if (ps->invocant) { - printf("%s = shift @_;\n", SvPV_nolen(ps->invocant)); - } - // XXX (...) = @_; - size_t positional_params = count_positional_params(ps); - for (size_t i = 0; i < ps->positional_optional.used; i++) { - printf("%*sif (@_ < %zu) {\n", (int)i * 2, "", positional_params - i); - } - for (size_t i = 0; i < ps->positional_optional.used; i++) { - ParamInit *pi = &ps->positional_optional.data[i]; - printf("%*s %s = %p;\n", (int)(ps->positional_optional.used - i - 1) * 2, "", SvPV_nolen(pi->name), pi->init); - printf("%*s}\n", (int)(ps->positional_optional.used - i - 1) * 2, ""); - } - if (named_params) { - printf("if (@_ > %zu) {\n", positional_params); - printf(" my $_b = '';\n"); - printf(" my $_i = %zu;\n", positional_params); - printf(" while ($_i < @_) {\n"); - printf(" my $_k = $_[$_i];\n"); - size_t req = ps->named_required.used; - for (size_t i = 0; i < named_params; i++) { - printf(" "); - if (i) { - printf("els"); - } - SV *param = i >= req ? ps->named_optional.data[i - req] : ps->named_required.data[i]; - printf("if ($_k eq '%s') {\n", SvPV_nolen(param) + 1); - printf(" %s = $_[$_i + 1];\n", SvPV_nolen(param)); - printf(" vec($_b, %zu, 1) = 1;\n", i); - printf(" }\n"); - } - printf(" else {\n"); - if (ps->slurpy) { - const char *slurpy = SvPV_nolen(ps->slurpy); - if (slurpy[0] == '%') { - printf(" $%s{$_k} = $_[$_i + 1];\n", slurpy + 1); - } else { - printf(" push %s, $_k, $_[$_i + 1];\n", slurpy); - } - } else { - printf(" croak 'no such param ' . $_k;\n"); - } - printf(" }\n"); - printf(" $_i += 2;\n"); - printf(" }\n"); - if (ps->named_required.used) { - printf(" if (($_b & pack('b*', '1' x %zu)) ne pack('b*', '1' x %zu)) {\n", ps->named_required.used, ps->named_required.used); - printf(" croak 'missing required named args';\n"); // XXX - printf(" }\n"); - } - for (size_t i = 0; i < ps->named_optional.used; i++) { - printf(" %s = %p unless vec $_k, %zu, 1;\n", SvPV_nolen(ps->named_optional[i].name), ps->named_optional[i].init, ps->named_required.used + i); - } - printf("}\n"); - } -}