I've realized '+place' is defined in two different files and ways. 'see
+place' shows the actual definition is that of <cross.fs>; the second
definition is in <other.fs>:
: +place ( adr len adr )
2dup c@ + over c!
dup c@ char+ + swap move ;
I discovered it doesn't work fine. In order to find the problem, I
dissected it:
: +place ( ca1 len1 ca2 )
\ Version defined in Gforth's <other.fs>, buggy.
\ len3 = length of the final string
\ ca4 = address after the string at ca2
2dup c@ ( ca1 len1 ca2 len1 len2 )
+ ( ca1 len1 ca2 len3 )
over c! ( ca1 len1 ca2 )
\ xxx fixme len2 is still needed, but it has been overriden with len3
dup c@ ( ca1 len1 ca2 len3 )
char+ + ( ca1 len1 ca4 )
swap move
;
The length of the second string has to be saved to calculate the
destination address:
: +place ( ca1 len1 ca2 )
\ Version defined in Gforth's <other.fs>, fixed.
\ len3 = length of the final string
\ ca4 = address after the string at ca2
2dup c@ ( ca1 len1 ca2 len1 len2 )
dup >r ( ca1 len1 ca2 len1 len2 ) ( R: len2 )
+ ( ca1 len1 ca2 len3 )
over c! ( ca1 len1 ca2 )
r> ( ca1 len1 ca2 len2 ) ( R: )
char+ + ( ca1 len1 ca4 )
swap move
;
The definition in <cross.fs> works fine. I dissected it too:
: +place ( ca1 len1 ca2 )
\ Version defined in Gforth's <cross.fs>.
\ len3 = length of the final string
\ ca4 = address after the string at ca2
2dup >r >r ( ca1 len1 ca2 ) ( R: ca2 len1 )
dup c@ ( ca1 len1 ca2 len2 )
char+ + ( ca1 len1 ca4 )
swap move
r> r> ( len1 ca2 ) ( R: )
dup c@ ( len1 ca2 len2 )
rot + ( ca2 len3 )
swap c!
;
At first sight the fixed definition of <other.fs> seems faster, with
less stack operations:
: +place ( ca1 len1 ca2 )
2dup c@ dup >r + over c! r> char+ + swap move
;
--
Marcos Cruz
http://programandala.net