summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--eval.c31
-rw-r--r--txr.121
3 files changed, 47 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index e988caa8..7ea404c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2014-07-03 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (apf_s, ipf_s): New symbol variables.
+ (me_ap, me_ip): Generate a much simpler macro-expansion:
+ a call to apf or ipf, rather than lambda syntax.
+ (me_ado, me_ido): New static functions.
+ (eval_init): Initialize apf_s and ipf_s variables.
+ Use them in the registration calls for apf and ipf.
+ Register ado and ido macros.
+
+ * txr.1: Streamlined documentation for ap and ip,
+ and added ado and ido.
+
+2014-07-03 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (apf, ipf): Bugfix: do_apf and do_ipf
should be registered as variadic functions.
diff --git a/eval.c b/eval.c
index 55cda3cf..6f059468 100644
--- a/eval.c
+++ b/eval.c
@@ -80,7 +80,7 @@ val dohash_s;
val uw_protect_s, return_s, return_from_s;
val list_s, append_s, apply_s, iapply_s;
val gen_s, gun_s, generate_s, rest_s, plus_s;
-val promise_s, op_s, identity_s;
+val promise_s, op_s, identity_s, apf_s, ipf_s;
val hash_lit_s, hash_construct_s;
val vector_lit_s, vector_list_s;
val macro_time_s, with_saved_vars_s, macrolet_s;
@@ -2437,19 +2437,22 @@ static val me_op(val form, val menv)
static val me_ap(val form, val menv)
{
- /* We do not use an op to generate the outer lambda, because
- it wouldn't be hygienic; this hidden op would capture @@n
- references from the body of the ap form. */
- val args = gensym(lit("args-"));
- return list(lambda_s, cons(args, nil),
- list(apply_s, cons(op_s, rest(form)), args, nao), nao);
+ return list(apf_s, cons(op_s, rest(form)), nao);
}
static val me_ip(val form, val menv)
{
- val args = gensym(lit("args-"));
- return list(lambda_s, cons(args, nil),
- list(iapply_s, cons(op_s, rest(form)), args, nao), nao);
+ return list(ipf_s, cons(op_s, rest(form)), nao);
+}
+
+static val me_ado(val form, val menv)
+{
+ return list(apf_s, cons(do_s, rest(form)), nao);
+}
+
+static val me_ido(val form, val menv)
+{
+ return list(ipf_s, cons(do_s, rest(form)), nao);
}
static val me_ret(val form, val menv)
@@ -3268,6 +3271,8 @@ void eval_init(void)
promise_s = intern(lit("promise"), system_package);
op_s = intern(lit("op"), user_package);
do_s = intern(lit("do"), user_package);
+ apf_s = intern(lit("apf"), user_package);
+ ipf_s = intern(lit("ipf"), user_package);
identity_s = intern(lit("identity"), user_package);
rest_s = intern(lit("rest"), user_package);
hash_lit_s = intern(lit("hash-construct"), system_package);
@@ -3338,6 +3343,8 @@ void eval_init(void)
reg_mac(do_s, me_op);
reg_mac(intern(lit("ap"), user_package), me_ap);
reg_mac(intern(lit("ip"), user_package), me_ip);
+ reg_mac(intern(lit("ado"), user_package), me_ado);
+ reg_mac(intern(lit("ido"), user_package), me_ido);
reg_mac(intern(lit("ret"), user_package), me_ret);
reg_mac(qquote_s, me_qquote);
reg_mac(sys_qquote_s, me_qquote);
@@ -3554,8 +3561,8 @@ void eval_init(void)
reg_fun(intern(lit("or"), user_package), func_n0v(or_fun));
reg_fun(intern(lit("and"), user_package), func_n0v(and_fun));
reg_fun(intern(lit("retf"), user_package), func_n1(retf));
- reg_fun(intern(lit("apf"), user_package), func_n1(apf));
- reg_fun(intern(lit("ipf"), user_package), func_n1(ipf));
+ reg_fun(apf_s, func_n1(apf));
+ reg_fun(ipf_s, func_n1(ipf));
reg_fun(intern(lit("tf"), user_package), func_n0v(tf));
reg_fun(intern(lit("nilf"), user_package), func_n0v(nilf));
diff --git a/txr.1 b/txr.1
index c64a9a63..b7fe8b98 100644
--- a/txr.1
+++ b/txr.1
@@ -12099,13 +12099,15 @@ is the first argument of the inner function. Of course, if there
are three levels of nesting, then three metas are needed to insert
a parameter from the outermost op, into the innermost op.
-.SS Macros ap and ip
+.SS Macros ap, ip, ado and ido.
.TP
Syntax:
(ap <form>+)
(ip <form>+)
+ (ado <form>+)
+ (ido <form>+)
.TP
Description:
@@ -12120,9 +12122,7 @@ list as arguments.
In other words, the following equivalence holds:
- (ap form ...) <--> (lambda (args) (apply (op form ...)))
-
-except that the symbol args is to be understood as a generated symbol (gensym).
+ (ap form ...) <--> (apf (op form ...))
The ap macro nests properly with op and do, in any combination, in regard
to the @@n notation.
@@ -12131,9 +12131,18 @@ The ip macro is very similar to the ap macro, except that it is based
on the semantics of the function iapply rather than apply, according
to the following equivalence:
- (ap form ...) <--> (lambda (args) (iapply (op form ...)))
+ (ip form ...) <--> (ipf (op form ...))
+
+The ado and ido macros is related to do macro in the same way that ap and ip
+are related to op. They produce a one-argument function is produced which works
+as if by applying its arguments to the function generated by do,
+according ot the following equivalence:
+
+ (ado form ...) <--> (apf (do form ...))
+
+ (ido form ...) <--> (ipf (do form ...))
-See also: the apf function
+See also: the apf and ipf functions.
.SS Macro ret