diff options
-rw-r--r-- | args.c | 12 | ||||
-rw-r--r-- | args.h | 12 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | ffi.c | 2 | ||||
-rw-r--r-- | lib.c | 39 | ||||
-rw-r--r-- | struct.c | 4 |
6 files changed, 39 insertions, 34 deletions
@@ -46,7 +46,7 @@ val args_add_checked(val name, struct args *args, val arg) return args_add(args, arg); } -void args_normalize(struct args *args, cnum fill) +void args_normalize_exact(struct args *args, cnum fill) { bug_unless (fill <= args->argc); @@ -58,9 +58,17 @@ void args_normalize(struct args *args, cnum fill) } +void args_normalize_least(struct args *args, cnum minfill) +{ + bug_unless (args->fill <= args->argc); + + while (args->fill < minfill && args->list) + args_add(args, pop(&args->list)); +} + void args_normalize_fill(struct args *args, cnum minfill, cnum maxfill) { - args_normalize(args, maxfill); + args_normalize_least(args, maxfill); if (args->fill >= minfill) while (args->fill < maxfill) @@ -134,14 +134,15 @@ INLINE int args_two_more(struct args *args, cnum index) cdr(args->list); } -void args_normalize(struct args *args, cnum fill); +void args_normalize_exact(struct args *args, cnum fill); +void args_normalize_least(struct args *args, cnum fill); void args_normalize_fill(struct args *args, cnum minfill, cnum maxfill); INLINE val args_get_list(struct args *args) { if (args->fill == 0) return z(args->list); - args_normalize(args, 0); + args_normalize_exact(args, 0); return z(args->list); } @@ -149,7 +150,7 @@ INLINE val args_get_rest(struct args *args, cnum index) { if (args->fill == index) return z(args->list); - args_normalize(args, index); + args_normalize_exact(args, index); return z(args->list); } @@ -176,11 +177,6 @@ INLINE val args_get(struct args *args, cnum *arg_index) return pop(&args->list); } -INLINE void args_clear(struct args *args) -{ - args->fill = 0; -} - INLINE cnum args_count(struct args *args) { return args->fill + c_num(length_list(args->list)); @@ -4535,7 +4535,7 @@ static val gather_free_refs(val info_cons, val exc, struct args *args) { (void) exc; - args_normalize(args, 2); + args_normalize_least(args, 2); if (args_count(args) == 2) { val tag = args_at(args, 1); @@ -4931,7 +4931,7 @@ static val prod_common(val fun, struct args *lists, args_decl(args_reset, max(argc, ARGS_MIN)); args_decl(args_work, max(argc, ARGS_MIN)); args_copy(args_reset, lists); - args_normalize(args_reset, argc); + args_normalize_exact(args_reset, argc); args_copy(args_work, args_reset); list_collect_decl (out, ptail); @@ -4173,7 +4173,7 @@ val ffi_call_wrap(val fptr, val ffi_call_desc, struct args *args) args = args_copy; } - args_normalize(args, n); + args_normalize_least(args, n); if (args->fill < n || args->list) uw_throwf(error_s, lit("~a: ~s requires ~s arguments"), @@ -6064,7 +6064,7 @@ val generic_funcall(val fun, struct args *args_in) case BUF: carray: bug_unless (args->argc >= ARGS_MIN); - args_normalize(args, 3); + args_normalize_least(args, 3); switch (args->fill) { case 0: @@ -6097,7 +6097,7 @@ val generic_funcall(val fun, struct args *args_in) case COBJ: if (fun->co.cls == hash_s) { bug_unless (args->argc >= ARGS_MIN); - args_normalize(args, 3); + args_normalize_least(args, 3); switch (args->fill) { case 0: @@ -6111,7 +6111,7 @@ val generic_funcall(val fun, struct args *args_in) } } else if (fun->co.cls == regex_s) { bug_unless (args->argc >= ARGS_MIN); - args_normalize(args, 3); + args_normalize_least(args, 3); switch (args->fill) { case 0: @@ -6144,7 +6144,7 @@ val generic_funcall(val fun, struct args *args_in) val *arg = 0; if (args->argc < fixparam) { - args_decl(args_copy, fixparam); + args_decl(args_copy, max(fixparam, ARGS_MIN)); args_copy_zap(args_copy, args_in); args = args_copy; } @@ -6195,9 +6195,8 @@ val generic_funcall(val fun, struct args *args_in) val *arg = 0; if (args->argc < fixparam) { - args_decl(args_copy, fixparam); - args_copy_zap(args_copy, args_in); - args = args_copy; + args_decl(args_copy, max(fixparam, ARGS_MIN)); + args = args_copy_zap(args_copy, args_in); } arg = args->arg; @@ -6207,7 +6206,10 @@ val generic_funcall(val fun, struct args *args_in) if (args->fill < reqargs) callerror(fun, lit("missing required arguments")); - args_clear(args); + { + args_decl(args_copy, max(args->fill - fixparam, ARGS_MIN)); + args = args_cat_zap_from(args_copy, args, fixparam); + } switch (fun->f.functype) { case FINTERP: @@ -9950,20 +9952,19 @@ val dwim_set(val place_p, val seq, varg vargs) case COBJ: if (type(seq) == COBJ) { if (seq->co.cls == hash_s) { - cnum nva = args_count(vargs); - - if (nva < 2) - goto fewargs; + args_normalize_least(vargs, 3); - if (nva > 3) - goto excargs; - - if (nva == 2) { - args_normalize(vargs, 2); + switch (vargs->fill) { + case 2: (void) sethash(seq, vargs->arg[0], vargs->arg[1]); - } else { - args_normalize(vargs, 3); + break; + case 3: + if (vargs->list) + goto excargs; (void) sethash(seq, vargs->arg[0], vargs->arg[2]); + break; + default: + goto fewargs; } return seq; @@ -1297,7 +1297,7 @@ static val method_args_fun(val env, varg args) args_decl(args_call, max(args->fill + 1 + ca_len, ARGS_MIN)); args_add(args_call, strct); args_add_list(args_call, curried_args); - args_normalize(args_call, ca_len + 1); + args_normalize_exact(args_call, ca_len + 1); args_cat_zap(args_call, args); return generic_funcall(fun, args_call); } @@ -1379,7 +1379,7 @@ static val umethod_args_fun(val env, struct args *args) args_decl(args_call, max(args->fill + ca_len, ARGS_MIN)); args_add(args_call, strct); args_add_list(args_call, curried_args); - args_normalize(args_call, ca_len + 1); + args_normalize_exact(args_call, ca_len + 1); args_cat_zap_from(args_call, args, index); struct struct_inst *si = struct_handle(strct, self); |