Then some comments upon how to implement it:
Jim Blandy <jimb@cyclic.com> writes:
> - The Emacs Lisp end-of-list values are: nil, '(), #f
> - The Emacs Lisp false values are: nil, '(), #f (same as above)
> - The Scheme end-of-list values are: '(), nil
> - The Scheme false values are: #f, nil
This will inevitably slow down Guile (also for the scheme side).
That is really sad. Here comes a suggestion which tries to minimize
the damage:
It is possible to arrange it so that the three values only differ in
one bit with respect to eachother.
First allocate four IFLAG:s which are identical except for two bits B1
and B2. This can be made for example by starting with an IFLAG number
which is divisible by four and then allocating sequentially.
Call the IFLAG where B1 and B2 are zero ANTI_NIL.
Let M1 = 1 << B1, M2 = 1 << B2.
Then we have ANTI_NIL & (M1 | M2) == 0.
By selecting values according to the following table it will be fairly
efficient to do the scheme SCM_FALSEP and SCM_EOLP tests. It will
also be easy to do the emacs NILP and EQ tests:
Language value Name (only here) Implementation value B2 b1
============== ================ ==================== =====
#f SCM_FALSE ANTI_NIL | M1 0 1
() SCM_EOL ANTI_NIL | M2 1 0
nil NIL ANTI_NIL | M1 | M2 1 1
Below follows the resulting test expressions:
Test Expression Number of operations
==== ========== ====================
For the scheme side:
SCM_FALSEP (x) x & ~M2 == SCM_FALSE 2 (&, ==)
SCM_EOLP (x) x & ~M1 == SCM_EOL 2 (&, ==)
SCM_EQ (x, y) x == y 1 (==)
For the emacs side:
NILP (x) x & ~(M1 | M2) == ANTI_NIL 2 (&, ==)
/mdj