summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-08-23 19:23:07 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-08-23 19:23:07 -0700
commita6fa35d2877745ba0b285093c40c1a3aad82a0e8 (patch)
treec198bb2deaa979417dbabc184dadf2061da86731 /eval.c
parent6d0af6ae2af0003716581ed23b486f26ac809e0c (diff)
downloadtxr-a6fa35d2877745ba0b285093c40c1a3aad82a0e8.tar.gz
txr-a6fa35d2877745ba0b285093c40c1a3aad82a0e8.tar.bz2
txr-a6fa35d2877745ba0b285093c40c1a3aad82a0e8.zip
Use of new args for function calls in interpreter.
* args.c (args_copy_to_list): New function. * args.h (ARGS_MIN): New preprocessor symbol. (args_add_list): New inline function. (args_copy_to_list): Declared. * debug.c (debug): Args in debug frame are now struct args *. Pull them out nondestructively for printing using args_copy_to_list. * eval.c (do_eval_args): Fill struct args argument list rather than returning evaluated list. Dot position evaluation is handled by installing the dot position value as args->list. (do_eval): Allocate args of at least ARGS_MAX for the call to do_eval_args. Then use generic_funcall to invoke the function rather than apply. (eval_args_lisp1): Modified similarly to do_eval_args. (eval_lisp1): New static function. (expand_macro): Construct struct args argument list for the sake of debug_frame. (op_dwim): Allocate args which are filled by eval_args_lisp1, and applied to the function/object with generic_funcall. The object expression is separately evaluated with eval_lisp1. * match.c (h_fun, v_fun): Construct struct args arglist for the sake of debug_frame call. * unwind.c (uw_push_debug): args argument becomes struct args *. * unwind.h (struct uw_debug): args member becomes struct args *. (uw_push_debug): Declaration updated. * txr.1: Update documentation about dot position argument in function calls. (list . a) now works, which previously didn't.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/eval.c b/eval.c
index 28456b85..47e3285c 100644
--- a/eval.c
+++ b/eval.c
@@ -54,6 +54,9 @@
#include "lisplib.h"
#include "eval.h"
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
typedef val (*opfun_t)(val, val);
typedef val (*mefun_t)(val, val);
@@ -900,18 +903,17 @@ twocol:
static val do_eval(val form, val env, val ctx_form,
val (*lookup)(val env, val sym));
-static val do_eval_args(val form, val env, val ctx_form,
- val (*lookup)(val env, val sym))
+static void do_eval_args(val form, val env, val ctx_form,
+ val (*lookup)(val env, val sym),
+ struct args *args)
{
- list_collect_decl (values, ptail);
for (; consp(form); form = cdr(form))
- ptail = list_collect(ptail, do_eval(car(form), env, ctx_form, lookup));
+ args_add(args, do_eval(car(form), env, ctx_form, lookup));
+
if (form) {
val dotpos = do_eval(form, env, ctx_form, lookup);
- ptail = list_collect_append(ptail, if3(listp(dotpos),
- dotpos, tolist(dotpos)));
+ args_add_list(args, if3(listp(dotpos), dotpos, tolist(dotpos)));
}
- return values;
}
static val set_dyn_env(val de)
@@ -984,11 +986,22 @@ static val do_eval(val form, val env, val ctx_form,
eval_error(form, lit("no such function or operator: ~s"), oper, nao);
abort();
} else {
- val args = do_eval_args(rest(form), env, form, &lookup_var);
+ val arglist = rest(form);
+ cnum alen = if3(consp(arglist), c_num(length(arglist)), 0);
+ cnum argc = max(alen, ARGS_MAX);
val ret, lfe_save = last_form_evaled;
- debug_frame(oper, args, nil, env, nil, nil, nil);
+ struct args *args = args_alloc(argc);
+
+ args_init(args, argc);
+
+ do_eval_args(rest(form), env, form, &lookup_var, args);
+
last_form_evaled = form;
- ret = apply(cdr(fbinding), z(args), form);
+
+ debug_frame(oper, args, nil, env, nil, nil, nil);
+
+ ret = generic_funcall(cdr(fbinding), args);
+
last_form_evaled = lfe_save;
debug_end;
debug_return (ret);
@@ -1006,9 +1019,14 @@ val eval(val form, val env, val ctx_form)
return do_eval(form, env, ctx_form, &lookup_var);
}
-static val eval_args_lisp1(val form, val env, val ctx_form)
+static void eval_args_lisp1(val form, val env, val ctx_form, struct args *args)
{
- return do_eval_args(form, env, ctx_form, &lookup_sym_lisp1);
+ do_eval_args(form, env, ctx_form, &lookup_sym_lisp1, args);
+}
+
+static val eval_lisp1(val form, val env, val ctx_form)
+{
+ return do_eval(form, env, ctx_form, &lookup_sym_lisp1);
}
val bindable(val obj)
@@ -1399,13 +1417,15 @@ static val expand_macro(val form, val expander, val menv)
} else {
debug_enter;
val name = car(form);
- val args = rest(form);
+ val arglist = rest(form);
val env = car(cdr(expander));
val params = car(cdr(cdr(expander)));
val body = cdr(cdr(cdr(expander)));
val saved_de = set_dyn_env(make_env(nil, nil, dyn_env));
- val exp_env = bind_macro_params(env, menv, params, args, nil, form);
+ val exp_env = bind_macro_params(env, menv, params, arglist, nil, form);
val result;
+ struct args *args = args_alloc(ARGS_MIN);
+ args_init_list(args, ARGS_MIN, arglist);
debug_frame(name, args, nil, env, nil, nil, nil);
result = eval_progn(body, exp_env, body);
debug_end;
@@ -1815,10 +1835,21 @@ static val op_return_from(val form, val env)
static val op_dwim(val form, val env)
{
- val args = eval_args_lisp1(cdr(form), env, form);
- val fi = car(args);
- val re = cdr(z(args));
- return apply(z(fi), z(re), form);
+ val argexps = rest(form);
+ val objexpr = pop(&argexps);
+ cnum alen = if3(consp(argexps), c_num(length(argexps)), 0);
+ cnum argc = max(alen, ARGS_MIN);
+ struct args *args = args_alloc(argc);
+ args_init(args, argc);
+
+ if (!consp(cdr(form)))
+ eval_error(form, lit("~s: missing argument"), car(form), nao);
+
+ {
+ val func = eval_lisp1(objexpr, env, form);
+ eval_args_lisp1(argexps, env, form, args);
+ return generic_funcall(func, args);
+ }
}
static val op_catch(val form, val env)