Hi Edwin,

> came across these macros in pico.h:
> 
> #define isSym(x)        (num(x)&WORD)
> #define isSymb(x)       ((num(x)&(WORD+2))==WORD)
> 
> what is the intent of isSymb()? as compared to isSym()?

as ever, the files "doc64/structures", "doc/structures" and
"mini/doc/structures" are the absolute key to the understanding of the
working of the different PicoLisp interpreters. They are the "bible" for
the internals of PicoLisp.


The 64-bit version has separate tag bits for each data type:

   cnt   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxS010
   big   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxS100
   sym   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1000
   cell  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0000

That is, if you AND a pointer with 2, you can test for a short number,
with 4 for a bignum, with 6 for a number in general (cnt or big), and
with 8 for a symbol.


A similar case for the 32-bit version:

      xxxxxxxxxxxxxxxxxxxxxxxxxxxxx010 Number
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxx100 Symbol
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxx000 Cell

It has no short numbers, so 2 checks for a number, and 4 for a symbol.


In MiniPicoLisp, however, things are a little different. It has no bignums,
so the patterns

      num      xxxxxx10
      sym      xxxxx100
      cell     xxxxx000

indicate that 2 also tests for a number, but because of the lack of
bignums, we want a number range as big as possible. For that reason, all
remaining bits (the 'x'es) can be used for a number (e.g. 30 bits if you
compile Mini on a 32-bit architecture).

However, just testing for 4 does not guarantee that you indeed have a
symbol. It might also be an odd number (which happens to have a least
significant bit set to one).

Now look at

   #define isSym(x)        (num(x)&WORD)

It is the "naive" form. WORD is 4 on a 32-bit system, so this macro just
tests for 4. You can use it when you already know that you _don't_ have
a number. This is quite often the case, when the arguments of a function
are analyzed, and you first test for a number.

If you want to immediately test for a symbol (without first checking for
a number), you shoule use

   #define isSymb(x)       ((num(x)&(WORD+2))==WORD)

This effectively does an AND with 6, then compares to 4. This is more
expensive that just the AND with 4 above, because for an odd number the
AND with 4 will return 6 (and not 4).

In summary, having these two macros is a matter of efficiency.


BTW, this potential conflict also exists in the 64-bit version. The two
number types have their sign bit (the 'S' in the patterns above) in the
position of the symbol tag. A simple 'AND 4' shows the same problem, in
that a symbol cannot be distingished from a negative number. Therefore,
the 64-bit code always checks for a number before it checks for a
symbol.

The 32-bit version is clean in that regard. You can test for any type at
any time, without worrying for conflicts.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to