[PicForth] Re: ?dup

Samuel Tardieu sam at rfc1149.net
Sun Nov 14 18:20:21 CET 2004


>>>>> "David" == David McNab <david at rebirthing.co.nz> writes:

David> Here's a ?dup implementation, based on a subroutine rather
David> than inlined code.

I rarely use ?dup in my Forth code. In PicForth, one can often find
more optimized constructs.

For example, in your libi2c.fs, you use:

  ?dup if exit then

which translates into:

0x0073  2004    call    0x004   ; ?dup
0x0074  0800    movf    0x00,w
0x0075  0A84    incf    0x04,f
0x0076  3800    iorlw   0x00
0x0077  1D03    btfss   0x03,2
0x0078  0008    return  

If you write the equivalent expression:

  dup if exit then drop

you get:

0x0073  0800    movf    0x00,w
0x0074  1D03    btfss   0x03,2
0x0075  0008    return  
0x0076  0A84    incf    0x04,f

which is faster and smaller.

Moreover, the "drop" is not needed here as you will return "0" from
this word if you don't exit there. Which leads to:

  dup if exit then

0x0073  0800    movf    0x00,w
0x0074  1D03    btfss   0x03,2
0x0075  0008    return  

and since you remove the "0" at the end of the word, it now becomes:

: i2c.read-begin
  i2c.tx-2byte-addr dup if exit then
  i2c.tx-restart i2c.tx-ctrl-out ;

which neatly compiles as:

0x0072  206B    call    0x06B   ; i2c.tx-2byte-addr
0x0073  0800    movf    0x00,w
0x0074  1D03    btfss   0x03,2
0x0075  0008    return  
0x0076  203A    call    0x03A   ; i2c.tx-restart
0x0077  2848    goto    0x048   ; i2c.tx-ctrl-out

Due to PicForth optimizations, it is unnecessary to provide a "-if"
word as designed by Chuck Moore. "-if" is "dup if" without consuming
an extra token in stack -- PicForth doesn't use any extra stack token
as it recognizes the "dup if" idiom.

  Sam
-- 
Samuel Tardieu -- sam at rfc1149.net -- http://www.rfc1149.net/sam



More information about the PicForth mailing list