clasp
clasp copied to clipboard
LET doesn't bind specials in parallel (again)
Describe the bug
Same issue as #69
STAK
from famous gabriel benchmarks:
;;; STAK -- The TAKeuchi function with special variables instead of parameter
;;; passing.
(defvar *stak-x*)
(defvar *stak-y*)
(defvar *stak-z*)
(defun stak-aux ()
(if (not (< (the fixnum *stak-y*) (the fixnum *stak-x*)))
*stak-z*
(let ((*stak-x* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-x*))))
(*stak-y* *stak-y*)
(*stak-z* *stak-z*))
(stak-aux)))
(*stak-y* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-y*))))
(*stak-y* *stak-z*)
(*stak-z* *stak-x*))
(stak-aux)))
(*stak-z* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-z*))))
(*stak-y* *stak-x*)
(*stak-z* *stak-y*))
(stak-aux))))
(stak-aux))))
(defun stak (*stak-x* *stak-y* *stak-z*)
(stak-aux))
(lisp-implementation-type)
→ "clasp"
(lisp-implementation-version)
→ "cclasp-boehmprecise-2.3.0-120-gbbe2d9d57-cst"
;;; `stak-aux` decriments special variable infinitely...
(stak 18 12 6) >>> illegal hardware instruction
Expected behavior
(stak 18 12 6) → 7
cf. lambda
binds special variable in parallel properly.
(defun stak-aux ()
(if (not (< (the fixnum *stak-y*) (the fixnum *stak-x*)))
*stak-z*
((lambda (*stak-x* *stak-y* *stak-z*)
(stak-aux))
((lambda (*stak-x* *stak-y* *stak-z*)
(stak-aux))
(the fixnum (1- (the fixnum *stak-x*)))
*stak-y*
*stak-z*)
((lambda (*stak-x* *stak-y* *stak-z*)
(stak-aux))
(the fixnum (1- (the fixnum *stak-y*)))
*stak-z*
*stak-x*)
((lambda (*stak-x* *stak-y* *stak-z*)
(stak-aux))
(the fixnum (1- (the fixnum *stak-z*)))
*stak-x*
*stak-y*))))
(defun stak (*stak-x* *stak-y* *stak-z*)
(stak-aux))
(stak 18 12 6) → 7
No idea how this broke in clasp-cleavir but the bytecode problem is at least fairly obvious. I'll also put in a test so we catch this earlier next time.