From b1685e72fab5291ef2755d1e89ca729c05dc443e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 23 Jan 2014 06:51:19 -0800 Subject: * eval.c (expand_op): Takes sym argument to distinguish op and do. The dwim operator is deleted when the symbol is do. (expand): Expand do_s form with expand_op, not only op_s. Pass down symbol. * txr.1: Document do operator. --- ChangeLog | 9 +++++++++ eval.c | 9 ++++++--- txr.1 | 24 +++++++++++++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b9b1b53..508a3a4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-01-23 Kaz Kylheku + + * eval.c (expand_op): Takes sym argument to distinguish op and do. + The dwim operator is deleted when the symbol is do. + (expand): Expand do_s form with expand_op, not only op_s. Pass down + symbol. + + * txr.1: Document do operator. + 2014-01-23 Kaz Kylheku * eval.c (do_eval): Fix incorrect, recently introduced code diff --git a/eval.c b/eval.c index 63c56a62..3e2d9821 100644 --- a/eval.c +++ b/eval.c @@ -1611,7 +1611,7 @@ static val supplement_op_syms(val ssyms, val max) return outsyms; } -static val expand_op(val body) +static val expand_op(val sym, val body) { val body_ex = expand_forms(body); val rest_gensym = gensym(lit("rest-")); @@ -1637,6 +1637,9 @@ static val expand_op(val body) append2(body_trans, rest_gensym))), body_trans); + if (sym == do_s) + dwim_body = rlcp(cdr(dwim_body), dwim_body); + return cons(lambda_s, cons(append2(mapcar(cdr_f, ssyms), rest_gensym), cons(dwim_body, nil))); @@ -1793,8 +1796,8 @@ val expand(val form) return expand(expand_gen(rest(form))); } else if (sym == delay_s) { return expand(expand_delay(rest(form))); - } else if (sym == op_s) { - return expand_op(rest(form)); + } else if (sym == op_s || sym == do_s) { + return expand_op(sym, rest(form)); } else if (sym == catch_s) { return expand_catch(rest(form)); } else if (sym == regex_s || regexp(sym)) { diff --git a/txr.1 b/txr.1 index ed33cfae..3430bd6a 100644 --- a/txr.1 +++ b/txr.1 @@ -10065,16 +10065,19 @@ for these common keys are those from . .SH PARTIAL EVALUATION AND COMBINATORS -.SS Operator op +.SS Operators op and do .TP Syntax: (op {
}+) + (do {}+) .TP Description: +The op and do operators are similar. + Like the lambda operator, the op operator creates an anonymous function. The difference is that the arguments of the function are implicit, or optionally specified within the function body. @@ -10083,6 +10086,18 @@ Also, the arguments of op are implicitly turned into a DWIM expression, which means that argument evaluation follows Lisp-1 rules. (See the dwim operator below). +The do operator is like the op operator with the following difference: +the arguments of op are not implicitly treated as a DWIM expression, +but as an ordinary expression. In particular, this means that operator +syntax is permitted. Note that the syntax (op @1) makes sense, since +the argument can be a function, which will be invoked, but (do @1) doesn't +make sense because it will produce a Lisp-2 form like (#:arg1 ...) referring +to nonexistent function #:arg1. This is why the operator is called "do": it +requires some operation. Moreover, it can be used with imperative constructs +which are not functions, like set: like set: for instance (do set x) produces +an anonymous function which, if called with one argument, stores that argument +into x. + The argument forms are arbitrary expressions, within which a special convention is permitted: @@ -10127,12 +10142,19 @@ symbols in the program. (op foo @rest @1) -> (lambda (arg1 . rest) [foo rest arg1]) + (do + foo) -> (lambda rest (+ foo . rest)) + + (do @1 @2) -> (lambda (arg1 arg2 . rest) (arg1 arg2)) + + (do foo @rest @1) -> (lambda (arg1 . rest) (foo rest arg1)) + Note that if argument @ appears, it is not necessary for arguments @1 through @ to appear. The function will have n arguments: (op @3) -> (lambda (arg1 arg2 arg3 . rest) [arg3]) + .PP .TP -- cgit v1.2.3