Post #1493692
2026-04-21 02:39 UTC
turns out that even if you're using an 8080 / Z80, CDR-coding might be worth it. granted, the reduced form of CDR-coding where you only get NEXT and FWD, but again, you can either not allow forwarders into registers, or start by resolving any forwarders in registers. but the forwarder resolver is short enough to be stuffed into a rst. sort of:
org $1E
mov e,m
xchg
reify mov a,l ; rst 4
rar
rnc
mov d,m
dcr l
jmp $1E
cadr inr l
inx h
rst 4
car mov e,m
inr l
mov d,m
jmp $1E
cddr inr l
inx h
rst 4
cdr inr l
inx h
jmp $20
atom push h ; atom if car X=X
call car
xchg
pop d
mov a,l
xra e
mov e,a
mov a,h
xra d
or e
jnz untrue
lxi h,TRUE
ret
untrue lxi h,FALSE
ret
it turns out that resolving forwarders before allowing them into registers is quicker. specifically, 21 cycles quicker on a Z80: the difference between JMP x and RST x / RET ... RET. CONS is almost certainly something you want in a register too.
this form of CDR-coding doesn't save us from having to terminate lists with NIL - quite a big deal when the average length of a Lisp list is 4 items! and possibly the wrong optimisation when only 1% of CDRs don't point at the next memory address after linearisation. but a signficant limitation of using a a scheme where a set bit means END rather than FWD is that it becomes impossible to represent a zero-length list (without a hack), or to represent the 1% of CONSes whose CDRs don't point to the next cell in memory (without a different hack).
Replies (0)
No replies.