summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--args.c12
-rw-r--r--args.h12
-rw-r--r--eval.c4
-rw-r--r--ffi.c2
-rw-r--r--lib.c39
-rw-r--r--struct.c4
6 files changed, 39 insertions, 34 deletions
diff --git a/args.c b/args.c
index 4fe46f67..aa2139a7 100644
--- a/args.c
+++ b/args.c
@@ -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)
diff --git a/args.h b/args.h
index 3ea94186..76aa10a1 100644
--- a/args.h
+++ b/args.h
@@ -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));
diff --git a/eval.c b/eval.c
index ac023eef..1d70f953 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
diff --git a/ffi.c b/ffi.c
index 329291ea..70d4bb6d 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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"),
diff --git a/lib.c b/lib.c
index c1329346..881df208 100644
--- a/lib.c
+++ b/lib.c
@@ -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;
diff --git a/struct.c b/struct.c
index 35af3136..8c104d08 100644
--- a/struct.c
+++ b/struct.c
@@ -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);