summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c317
1 files changed, 118 insertions, 199 deletions
diff --git a/eval.c b/eval.c
index d7c7c16a..28456b85 100644
--- a/eval.c
+++ b/eval.c
@@ -24,6 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -34,8 +35,10 @@
#include <signal.h>
#include <time.h>
#include "config.h"
+#include ALLOCA_H
#include "lib.h"
#include "gc.h"
+#include "args.h"
#include "arith.h"
#include "signal.h"
#include "unwind.h"
@@ -51,8 +54,6 @@
#include "lisplib.h"
#include "eval.h"
-#define APPLY_ARGS 32
-
typedef val (*opfun_t)(val, val);
typedef val (*mefun_t)(val, val);
@@ -437,14 +438,16 @@ static val env_vbind_special(val env, val sym, val obj,
}
}
-static val bind_args(val env, val params, val args, val ctx_form)
+static val bind_args(val env, val params, struct args *args, val ctx_form)
{
val new_env = make_env(nil, nil, env);
val optargs = nil;
val special_list = nil;
+ cnum index = 0;
- for (; args && consp(params); params = cdr(params)) {
+ for (; args_more(args, index) && consp(params); params = cdr(params)) {
val param = car(params);
+ val arg;
val initform = nil;
val presentsym = nil;
@@ -478,8 +481,9 @@ static val bind_args(val env, val params, val args, val ctx_form)
eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
car(ctx_form), presentsym, nao);
+ arg = args_get_checked(ctx_form, args, &index);
+
if (optargs) {
- val arg = car(args);
val initval = nil;
val present = nil;
@@ -496,14 +500,13 @@ static val bind_args(val env, val params, val args, val ctx_form)
if (presentsym)
env_vbind_special(new_env, presentsym, present, special_list, ctx_form);
} else {
- env_vbind_special(new_env, param, car(args), special_list, ctx_form);
+ env_vbind_special(new_env, param, arg, special_list, ctx_form);
}
-
- args = cdr(args);
}
if (bindable(params)) {
- env_vbind_special(new_env, params, args, special_list, ctx_form);
+ env_vbind_special(new_env, params, args_get_rest(args, index),
+ special_list, ctx_form);
} else if (consp(params)) {
if (car(params) == colon_k) {
if (optargs)
@@ -545,7 +548,7 @@ static val bind_args(val env, val params, val args, val ctx_form)
} else if (params) {
eval_error(ctx_form, lit("~s: ~s is not a bindable symbol"),
car(ctx_form), params, nao);
- } else if (args) {
+ } else if (args_more(args, index)) {
eval_error(ctx_form, lit("~s: too many arguments for ~!~s"),
car(ctx_form), ctx_form, nao);
}
@@ -664,133 +667,9 @@ static val get_param_syms(val params)
val apply(val fun, val arglist, val ctx_form)
{
- val arg[APPLY_ARGS], *p = arg;
- int fixparam, reqargs, nargs;
- val ctx = if3(ctx_form, car(ctx_form), apply_s);
-
- if (fun && symbolp(fun)) {
- val binding = gethash(top_fb, fun);
- if (!binding)
- eval_error(ctx_form, lit("~s: no such function ~s"), ctx, fun, nao);
- fun = cdr(binding);
- }
-
- if (!functionp(fun)) {
- for (nargs = 0;
- (p < arg + APPLY_ARGS) && consp(arglist);
- nargs++, p++, arglist = cdr(arglist))
- {
- *p = car(arglist);
- }
- return generic_funcall(fun, arg, nargs);
- }
-
- type_check (fun, FUN);
-
- if (!listp(arglist)) {
- val arglist_conv = tolist(arglist);
- type_assert (listp(arglist_conv),
- (lit("~s: arglist ~s is not a list"), ctx,
- arglist, nao));
- arglist = arglist_conv;
- }
-
- fixparam = fun->f.fixparam;
- reqargs = fixparam - fun->f.optargs;
-
- if (!fun->f.variadic) {
- for (; arglist && p < arg + APPLY_ARGS; arglist = cdr(arglist))
- *p++ = car(arglist);
-
- nargs = p - arg;
-
- if (nargs < reqargs)
- eval_error(ctx_form, lit("~s: missing required arguments for ~!~s"),
- ctx, func_get_name(fun, nil), nao);
-
- if (nargs > fixparam)
- eval_error(ctx_form, lit("~s: too many arguments for ~!~s"),
- ctx, func_get_name(fun, nil), nao);
-
- for (; nargs < fixparam; nargs++)
- *p++ = colon_k;
-
- switch (fun->f.functype) {
- case F0:
- return fun->f.f.f0(fun->f.env);
- case F1:
- return fun->f.f.f1(fun->f.env, z(arg[0]));
- case F2:
- return fun->f.f.f2(fun->f.env, z(arg[0]), z(arg[1]));
- case F3:
- return fun->f.f.f3(fun->f.env, z(arg[0]), z(arg[1]), z(arg[2]));
- case F4:
- return fun->f.f.f4(fun->f.env, z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]));
- case N0:
- return fun->f.f.n0();
- case N1:
- return fun->f.f.n1(z(arg[0]));
- case N2:
- return fun->f.f.n2(z(arg[0]), z(arg[1]));
- case N3:
- return fun->f.f.n3(z(arg[0]), z(arg[1]), z(arg[2]));
- case N4:
- return fun->f.f.n4(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]));
- case N5:
- return fun->f.f.n5(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]));
- case N6:
- return fun->f.f.n6(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]), z(arg[5]));
- case N7:
- return fun->f.f.n7(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]), z(arg[5]), z(arg[6]));
- case FINTERP:
- internal_error("unsupported function type");
- }
- } else {
- for (; arglist && p - arg < fixparam; arglist = cdr(arglist))
- *p++ = car(arglist);
-
- nargs = p - arg;
-
- if (nargs < reqargs)
- eval_error(ctx_form, lit("~s: missing required arguments for ~!~s"),
- ctx, func_get_name(fun, nil), nao);
-
- for (; nargs < fixparam; nargs++)
- *p++ = colon_k;
-
- switch (fun->f.functype) {
- case FINTERP:
- return interp_fun(fun->f.env, fun->f.f.interp_fun, z(arglist));
- case F0:
- return fun->f.f.f0v(fun->f.env, z(arglist));
- case F1:
- return fun->f.f.f1v(fun->f.env, z(arg[0]), z(arglist));
- case F2:
- return fun->f.f.f2v(fun->f.env, z(arg[0]), z(arg[1]), z(arglist));
- case F3:
- return fun->f.f.f3v(fun->f.env, z(arg[0]), z(arg[1]), z(arg[2]), z(arglist));
- case F4:
- return fun->f.f.f4v(fun->f.env, z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arglist));
- case N0:
- return fun->f.f.n0v(z(arglist));
- case N1:
- return fun->f.f.n1v(z(arg[0]), z(arglist));
- case N2:
- return fun->f.f.n2v(z(arg[0]), z(arg[1]), z(arglist));
- case N3:
- return fun->f.f.n3v(z(arg[0]), z(arg[1]), z(arg[2]), z(arglist));
- case N4:
- return fun->f.f.n4v(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arglist));
- case N5:
- return fun->f.f.n5v(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]), z(arglist));
- case N6:
- return fun->f.f.n6v(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]), z(arg[5]), z(arglist));
- case N7:
- return fun->f.f.n7v(z(arg[0]), z(arg[1]), z(arg[2]), z(arg[3]), z(arg[4]), z(arg[5]), z(arg[6]), z(arglist));
- }
- }
-
- internal_error("corrupt function type field");
+ struct args *args = args_alloc(ARGS_MAX);
+ args_init_list(args, ARGS_MAX, arglist);
+ return generic_funcall(fun, args);
}
static val apply_frob_args(val args)
@@ -813,17 +692,27 @@ val apply_intrinsic(val fun, val args)
return apply(fun, apply_frob_args(z(args)), nil);
}
-static val iapply(val fun, val args)
+static val applyv(val fun, struct args *args)
+{
+ return apply_intrinsic(fun, args_get_list(args));
+}
+
+static val iapply(val fun, struct args *args)
{
+ cnum index = 0;
list_collect_decl (mod_args, ptail);
loc saved_ptail;
+ val last_arg = nil;
- for (; cdr(args); args = cdr(args))
- ptail = list_collect(ptail, car(args));
+ while (args_two_more(args, index))
+ ptail = list_collect(ptail, args_get(args, &index));
saved_ptail = ptail;
- ptail = list_collect_nconc(ptail, car(args));
+ if (args_more(args, index)) {
+ last_arg = args_get(args, &index);
+ ptail = list_collect_nconc(ptail, last_arg);
+ }
{
loc pterm = term(ptail);
@@ -831,7 +720,7 @@ static val iapply(val fun, val args)
if (tatom) {
deref(ptail) = nil;
- ptail = list_collect_nconc(saved_ptail, copy_list(car(args)));
+ ptail = list_collect_nconc(saved_ptail, copy_list(last_arg));
set(term(ptail), cons(tatom, nil));
}
}
@@ -839,14 +728,9 @@ static val iapply(val fun, val args)
return apply(fun, z(mod_args), nil);
}
-static val call(val fun, val args)
-{
- return apply(fun, z(args), cons(apply_s, nil));
-}
-
-static val list_star_intrinsic(val args)
+static val list_star_intrinsic(struct args *args)
{
- return apply_frob_args(args);
+ return apply_frob_args(args_get_list(args));
}
static val bind_macro_params(val env, val menv, val params, val form,
@@ -1037,7 +921,7 @@ static val set_dyn_env(val de)
return old;
}
-val interp_fun(val env, val fun, val args)
+val interp_fun(val env, val fun, struct args *args)
{
val def = cdr(fun);
val params = car(def);
@@ -1948,9 +1832,12 @@ static val op_catch(val form, val env)
result = eval(try_form, env, try_form);
uw_catch(exsym, exvals) {
+ struct args *args = args_alloc(ARGS_MIN);
val catches = rest(rest(rest(form)));
val iter;
+ args_init_list(args, ARGS_MIN, exvals);
+
for (iter = catches; iter; iter = cdr(iter)) {
val clause = car(iter);
val type = first(clause);
@@ -1958,7 +1845,7 @@ static val op_catch(val form, val env)
if (uw_exception_subtype_p(exsym, type)) {
val params = second(clause);
val saved_de = set_dyn_env(make_env(nil, nil, dyn_env));
- val clause_env = bind_args(env, params, exvals, clause);
+ val clause_env = bind_args(env, params, args, clause);
result = eval_progn(rest(rest(clause)), clause_env, clause);
set_dyn_env(saved_de);
break;
@@ -2600,8 +2487,8 @@ static val me_op(val form, val menv)
cons_bind (syms, body_trans, transform_op(body_ex, nil, rest_gensym));
val ssyms = sort(syms, func_n2(lt), car_f);
val nums = mapcar(car_f, ssyms);
- val max = if3(nums, maxv(car(nums), cdr(nums)), zero);
- val min = if3(nums, minv(car(nums), cdr(nums)), zero);
+ val max = if3(nums, maxl(car(nums), cdr(nums)), zero);
+ val min = if3(nums, minl(car(nums), cdr(nums)), zero);
val has_rest = cons_find(rest_gensym, body_trans, eq_f);
val is_op = and3(sym == do_s, consp(body_trans),
gethash(op_table, car(body_trans)));
@@ -3335,11 +3222,14 @@ static val constantp(val form, val env_in)
}
}
-val mapcarv(val fun, val list_of_lists)
+val mapcarv(val fun, struct args *lists)
{
- if (!cdr(list_of_lists)) {
- return mapcar(fun, nullify(car(list_of_lists)));
+ if (!args_more(lists, 0)) {
+ return nil;
+ } else if (!args_two_more(lists, 0)) {
+ return mapcar(fun, nullify(args_atz(lists, 0)));
} else {
+ val list_of_lists = args_get_list(lists);
val lofl = mapcar_listout(func_n1(nullify), list_of_lists);
val list_orig = car(list_of_lists);
list_collect_decl (out, otail);
@@ -3361,11 +3251,21 @@ val mapcarv(val fun, val list_of_lists)
}
}
-static val mappendv(val fun, val list_of_lists)
+val mapcarl(val fun, val list_of_lists)
+{
+ struct args *args = args_alloc(ARGS_MIN);
+ args_init_list(args, ARGS_MIN, list_of_lists);
+ return mapcarv(fun, args);
+}
+
+static val mappendv(val fun, struct args *lists)
{
- if (!cdr(list_of_lists)) {
- return mappend(fun, car(list_of_lists));
+ if (!args_more(lists, 0)) {
+ return nil;
+ } else if (!args_two_more(lists, 0)) {
+ return mappend(fun, args_atz(lists, 0));
} else {
+ val list_of_lists = args_get_list(lists);
val lofl = mapcar(func_n1(nullify), list_of_lists);
val list_orig = car(list_of_lists);
list_collect_decl (out, otail);
@@ -3425,28 +3325,43 @@ static val lazy_mapcarv_func(val env, val lcons)
return nil;
}
-static val lazy_mapcarv(val fun, val list_of_lists)
+static val lazy_mapcarv(val fun, struct args *lists)
{
- if (!cdr(list_of_lists)) {
- return lazy_mapcar(fun, car(list_of_lists));
- } else if (some_satisfy(list_of_lists, null_f, identity_f)) {
+ if (!args_more(lists, 0)) {
return nil;
+ } else if (!args_two_more(lists, 0)) {
+ return lazy_mapcar(fun, args_atz(lists, 0));
} else {
- val lofl = mapcar(func_n1(nullify), list_of_lists);
- return make_lazy_cons(func_f1(cons(fun, lofl), lazy_mapcarv_func));
+ val list_of_lists = args_get_list(lists);
+ if (some_satisfy(list_of_lists, null_f, identity_f)) {
+ return nil;
+ } else {
+ val lofl = mapcar(func_n1(nullify), list_of_lists);
+ return make_lazy_cons(func_f1(cons(fun, lofl), lazy_mapcarv_func));
+ }
}
}
-static val lazy_mappendv(val fun, val list_of_lists)
+static val lazy_mapcarl(val fun, val list_of_lists)
{
- return lazy_appendv(lazy_mapcarv(fun, list_of_lists));
+ struct args *args = args_alloc(ARGS_MIN);
+ args_init_list(args, ARGS_MIN, list_of_lists);
+ return lazy_mapcarv(fun, args);
}
-static val mapdov(val fun, val list_of_lists)
+static val lazy_mappendv(val fun, struct args *lists)
{
- if (!cdr(list_of_lists)) {
- return mapdo(fun, car(list_of_lists));
+ return lazy_appendl(lazy_mapcarv(fun, lists));
+}
+
+static val mapdov(val fun, struct args *lists)
+{
+ if (!args_more(lists, 0)) {
+ return nil;
+ } else if (!args_two_more(lists, 0)) {
+ return mapdo(fun, args_atz(lists, 0));
} else {
+ val list_of_lists = args_get_list(lists);
val lofl = mapcar_listout(func_n1(nullify), list_of_lists);
for (;;) {
@@ -3753,15 +3668,16 @@ static val weave_gen(val env)
return ret;
}
-static val weavev(val lists)
+static val weavev(struct args *args)
{
+ val lists = args_get_list(args);
val uniq = cons(nil, nil);
val padded_lists = mapcar(curry_123_1(func_n3(pad), uniq, colon_k), lists);
- val tuples = lazy_mapcarv(list_f, padded_lists);
+ val tuples = lazy_mapcarl(list_f, padded_lists);
val env = cons(uniq, tuples);
val whil = func_f0(env, weave_while);
val gen = func_f0(env, weave_gen);
- return lazy_appendv(generate(whil, gen));
+ return lazy_appendl(generate(whil, gen));
}
static val force(val promise)
@@ -3827,22 +3743,25 @@ static val if_fun(val cond, val then, val alt)
return if3(cond, then, default_bool_arg(alt));
}
-static val or_fun(val vals)
+static val or_fun(struct args *vals)
{
- for (; vals != nil; vals = cdr(vals)) {
- val item = car(vals);
+ cnum index = 0;
+
+ while (args_more(vals, index)) {
+ val item = args_get(vals, &index);
if (item)
return item;
}
return nil;
}
-static val and_fun(val vals)
+static val and_fun(struct args *vals)
{
val item = t;
+ cnum index = 0;
- for (; vals != nil; vals = cdr(vals)) {
- item = car(vals);
+ while (args_more(vals, index)) {
+ item = args_get(vals, &index);
if (!item)
return nil;
}
@@ -3855,19 +3774,19 @@ static val not_null(val obj)
return if3(nilp(obj), nil, t);
}
-static val tf(val args)
+static val tf(struct args *args)
{
(void) args;
return t;
}
-static val nilf(val args)
+static val nilf(struct args *args)
{
(void) args;
return nil;
}
-static val do_retf(val ret, val args)
+static val do_retf(val ret, struct args *args)
{
(void) args;
return ret;
@@ -3878,9 +3797,9 @@ static val retf(val ret)
return func_f0v(ret, do_retf);
}
-static val do_apf(val fun, val args)
+static val do_apf(val fun, struct args *args)
{
- return apply_intrinsic(fun, z(args));
+ return apply_intrinsic(fun, args_get_list(args));
}
static val apf(val fun)
@@ -3888,9 +3807,9 @@ static val apf(val fun)
return func_f0v(fun, do_apf);
}
-static val do_ipf(val fun, val args)
+static val do_ipf(val fun, struct args *args)
{
- return iapply(fun, z(args));
+ return iapply(fun, args);
}
static val ipf(val fun)
@@ -3898,23 +3817,23 @@ static val ipf(val fun)
return func_f0v(fun, do_ipf);
}
-static val callf(val func, val funlist)
+static val callf(val func, struct args *funlist)
{
val juxt_fun = juxtv(funlist);
val apf_fun = apf(func);
return chain(juxt_fun, apf_fun, nao);
}
-static val do_mapf(val env, val args)
+static val do_mapf(val env, struct args *args)
{
cons_bind (fun, funlist, env);
- val mapped_args = mapcarv(call_f, cons(funlist, cons(z(args), nil)));
+ val mapped_args = mapcarl(call_f, cons(funlist, cons(args_get_list(args), nil)));
return apply(fun, z(mapped_args), nil);
}
-static val mapf(val fun, val funlist)
+static val mapf(val fun, struct args *funlist)
{
- return func_f0v(cons(fun, funlist), do_mapf);
+ return func_f0v(cons(fun, args_get_list(funlist)), do_mapf);
}
val prinl(val obj, val stream)
@@ -3992,7 +3911,7 @@ void eval_init(void)
eval_initing = t;
- call_f = func_n1v(call);
+ call_f = func_n1v(generic_funcall);
dwim_s = intern(lit("dwim"), user_package);
progn_s = intern(lit("progn"), user_package);
@@ -4225,13 +4144,13 @@ void eval_init(void)
reg_fun(intern(lit("mappend"), user_package), func_n1v(mappendv));
reg_fun(intern(lit("mappend*"), user_package), func_n1v(lazy_mappendv));
reg_fun(intern(lit("mapdo"), user_package), func_n1v(mapdov));
- reg_fun(apply_s, func_n1v(apply_intrinsic));
+ reg_fun(apply_s, func_n1v(applyv));
reg_fun(iapply_s, func_n1v(iapply));
reg_fun(call_s, call_f);
reg_fun(intern(lit("reduce-left"), user_package), func_n4o(reduce_left, 2));
reg_fun(intern(lit("reduce-right"), user_package), func_n4o(reduce_right, 2));
reg_fun(intern(lit("transpose"), user_package), func_n1(transpose));
- reg_fun(intern(lit("zip"), user_package), func_n0v(transpose));
+ reg_fun(intern(lit("zip"), user_package), func_n0v(transposev));
reg_fun(intern(lit("interpose"), user_package), func_n2(interpose));
reg_fun(intern(lit("second"), user_package), func_n1(second));
@@ -4383,7 +4302,7 @@ void eval_init(void)
reg_fun(intern(lit("copy-hash"), user_package), func_n1(copy_hash));
reg_fun(intern(lit("hash"), user_package), func_n0v(hashv));
reg_fun(intern(lit("hash-construct"), user_package), func_n2(hash_construct));
- reg_fun(intern(lit("hash-from-pairs"), user_package), func_n1v(hash_from_pairs));
+ reg_fun(intern(lit("hash-from-pairs"), user_package), func_n1v(hash_from_pairs_v));
reg_fun(intern(lit("hash-list"), user_package), func_n1v(hash_list));
reg_fun(gethash_s, func_n3o(gethash_n, 2));
reg_fun(intern(lit("inhash"), user_package), func_n3o(inhash, 2));
@@ -4567,7 +4486,7 @@ void eval_init(void)
reg_fun(intern(lit("length-str-<="), user_package), func_n2(length_str_le));
reg_fun(intern(lit("vector"), user_package), func_n2o(vector, 1));
- reg_fun(intern(lit("vec"), user_package), func_n0v(vector_list));
+ reg_fun(intern(lit("vec"), user_package), func_n0v(vectorv));
reg_fun(intern(lit("vectorp"), user_package), func_n1(vectorp));
reg_fun(intern(lit("vec-set-length"), user_package), func_n2(vec_set_length));
reg_fun(vecref_s, func_n2(vecref));
@@ -4586,8 +4505,8 @@ void eval_init(void)
reg_fun(intern(lit("acons"), user_package), func_n3(acons));
reg_fun(intern(lit("acons-new"), user_package), func_n3(acons_new));
reg_fun(intern(lit("aconsql-new"), user_package), func_n3(aconsql_new));
- reg_fun(intern(lit("alist-remove"), user_package), func_n1v(alist_remove));
- reg_fun(intern(lit("alist-nremove"), user_package), func_n1v(alist_nremove));
+ reg_fun(intern(lit("alist-remove"), user_package), func_n1v(alist_removev));
+ reg_fun(intern(lit("alist-nremove"), user_package), func_n1v(alist_nremovev));
reg_fun(intern(lit("copy-cons"), user_package), func_n1(copy_cons));
reg_fun(intern(lit("copy-alist"), user_package), func_n1(copy_alist));
reg_fun(intern(lit("prop"), user_package), func_n2(getplist));
@@ -4655,7 +4574,7 @@ void eval_init(void)
reg_fun(intern(lit("comb"), user_package), func_n2(comb));
reg_fun(intern(lit("rcomb"), user_package), func_n2(rcomb));
- reg_fun(throw_s, func_n1v(uw_throw));
+ reg_fun(throw_s, func_n1v(uw_throwv));
reg_fun(intern(lit("throwf"), user_package), func_n2v(uw_throwfv));
reg_fun(error_s, func_n1v(uw_errorfv));