Curious bug with (accumulate $)

This code seems like it should work:

(two puzzles solved)
    (accumulate 1)
        *(puzzle $Obj)
        (solved $Obj)
    (into 2)

Unfortunately, it does not (on Å-machine specifically).

1
dialogc: backend_aa.c:745: encode_dest: Assertion `0' failed.
Aborted (core dumped)

This is the offending code:

static aaoper_t encode_dest(value_t v, struct program *prg, int unify) {
	if(v.tag == OPER_VAR) {
		assert(v.value < 64);
		return (aaoper_t) {unify? AAO_VAR : AAO_STORE_VAR, v.value};
	} else if(v.tag == OPER_ARG) {
		return (aaoper_t) {unify? AAO_REG : AAO_STORE_REG, REG_A + v.value};
	} else if(v.tag == OPER_TEMP) {
		assert(v.value < AA_MAX_TEMP);
		return (aaoper_t) {unify? AAO_REG : AAO_STORE_REG, REG_X + v.value};
	} else if(v.tag == VAL_NIL && unify) {
		return (aaoper_t) {AAO_REG, REG_NIL};
	} else {
		printf("%d\n", v.tag);
		assert(0); exit(1);
	}
}

And a tag of 1 means VAL_NUM—that is, a numeric constant. It looks like the Å-machine compiler isn’t able to unify the results of certain operations with a non-nil constant value (only with a global, local, temp, or constant nil), and crashes.

Unfortunately my knowledge of the Å-machine isn’t good enough to know how to fix this any time soon. For now, this works:

(two puzzles solved)
    (accumulate 1)
        *(puzzle $Obj)
        (solved $Obj)
    (into $N)
    ($N = 2)
1 Like

Does it work on z-machine and in dgdebug?

For what it’s worth, the second form is somewhat clearer anyway, although I did get a brief thrill of Dialogic mastery when I realised what accumulate ... into 2 was doing (and of course the compiler dumping core is never great).