This bug is now fixed.
The first time a local variable appears in a routine, the compiler allocates some memory for it. The problem is, when it’s compiling a list literal like [$X $X]
, the list gets compiled from back to front: the last values are compiled first. (This comes down to how lists are represented as LISP-style cons cells. When compiling [$X $X]
, it first compiles [$X | [] ]
, and then compiles [$X | that thing]
.)
As a result, when the same unbound variable appears twice in a row in a list literal, and it hasn’t been used for anything before that list literal, it gets used before the memory is allocated, and the result is undefined! On the Z-machine, it accesses whatever happens to be sitting around in memory. In the debugger, it fails an assert and crashes.
For now, you can work around this in a few different ways. If you use the variable for anything before that, it works fine:
(do nothing $)
(program entry point)
(do nothing $X)
([$X $X] = $Y)
$Y
Or if you avoid having the same unbound variable twice in a row, that’s also fine:
(program entry point)
([$X 0 $X] = $Y)
$Y
Or, I’ve just submitted a pull request that should fix this once and for all! It also fixes this bug, which has the same root cause.