Re: ?dup
Samuel Tardieu <[email protected]> 14 Nov 2004 18:20:21 +0100
| Newsgroups | gmane.comp.lang.forth.picforth |
|---|---|
| Organization | RFC 1149 (see http://www.rfc1149.net/) |
| Message-ID | <[email protected]> |
>>>>> "David" == David McNab <[email protected]> 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 -- [email protected] -- http://www.rfc1149.net/sam