From 0f544070713a7dd93aa759dd71cf02fadd05814c Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Sat, 31 Dec 2016 20:37:37 -0800
Subject: Bugfix: repeated expansion of catch unstable.

It turns out we have a silly problem: catch is a special
operator, which undergoes a macro-like expansion which alters
its syntax, but uses the same operator symbol.

We turn catch into a macro which expands to a sys:catch
operator.

* eval.c (sys_catch_s): New symbol variable.
(expand_catch): Function now expands sys:catch forms
without altering any syntax.
(do_expand): Check for sys:catch rather than catch.
Call expand_catch differently: it takes the form now
instead of just the arguments, so it can return the
original form if no expansion takes place.
(eval_init): Initialize sys_catch_s variable. Change
registration of op_catch to sys:catch symbol.

* lisplib.c (except_set_entries): Add catch to the
list of autoload symbols for except.tl.

* share/txr/stdlib/except.tl (catch): New macro for
transforming catch to sys:catch.

* txr.1: Reclassify catch operator as a macro.
---
 share/txr/stdlib/except.tl | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'share')

diff --git a/share/txr/stdlib/except.tl b/share/txr/stdlib/except.tl
index dee1bb6f..f7f87b0a 100644
--- a/share/txr/stdlib/except.tl
+++ b/share/txr/stdlib/except.tl
@@ -27,6 +27,10 @@
 (defun sys:handle-bad-syntax (item)
   (throwf 'eval-error "~s: bad clause syntax: ~s" 'handle item))
 
+(defmacro catch (try-form . handle-clauses)
+  (let ((catch-syms [mapcar car handle-clauses]))
+    ^(sys:catch ,catch-syms ,try-form ,*handle-clauses)))
+
 (defmacro handle (:whole form try-form . handle-clauses)
   (let* ((exc-sym (gensym))
          (exc-args (gensym))
-- 
cgit v1.2.3