Inverted syntax: Difference between revisions

Line 68:
`(progn ,@(mapcar #'unrev-syntax forms)))</lang>
 
TestInteractive test run:
 
<pre>$ clisp -q -i reverse.lisp
Line 83:
T
</pre>
 
Now here is a slightly more complicated version which more closely conforms to the idea given in this task. The operator is assumed to be the second-last element of a form. The last element of the form is the first argument, and the forms prior to the operator are the remaining arguments (in reverse order). These rules are recursively applied to each of the arguments, but not to the operator. A two element form is assumed to be (argument operator), and is rewritten to
(operator argument*) where argument* is the result of applying the unreversal to the argument:
 
<lang lisp>(eval-when (:compile-toplevel :load-toplevel :execute)
(defun unrev-syntax (form)
(cond
((atom form) form) ;; atom: leave alone
((null (cdr form)) form) ;; one-element form, leave alone
((null (cddr form)) ;; two-element form, swap
(destructuring-bind (arg oper) form
`(,oper ,(unrev-syntax arg))))
(t ;; two or more args, swap and reverse whole thing
(destructuring-bind (arg1 oper &rest args) (reverse form)
`(,oper ,(unrev-syntax arg1) ,@(mapcar #'unrev-syntax args)))))))
 
(defmacro rprogn (&body forms)
`(progn ,@(mapcar #'unrev-syntax forms)))</lang>
 
<pre>[1]> (rprogn ((1 + 2) * (3 + 4)))
21
[2]> (rprogn (("not equal" print) ("equal" print) if (1 = 2)))
 
"not equal"
"not equal"
[3]> (rprogn (("not equal" print) ("equal" print) if (1 = 1)))
 
"equal"
"equal"
[4]> (macroexpand '(rprogn (("not equal" print) ("equal" print) if (1 = 1))))
(PROGN (IF (= 1 1) (PRINT "equal") (PRINT "not equal"))) ;
T
[5]> (macroexpand '(rprogn ((1 + 2) * (3 + 4))))
(PROGN (* (+ 4 3) (+ 2 1))) ;
T</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
Anonymous user