In article <
46519f18ba08e088b940ee517313db099de97788@i2pn2.org>,
dxf <
dxforth@gmail.com> wrote:
On 4/10/2024 2:32 am, Anton Ertl wrote:
minforth@gmx.net (minforth) writes:
Introduce variant data-types, as some BASIC compilers have,
you really have to invent a new 'Forthish' dialect. Probably
useless for embedded applications.
>
Joerg Voelker works on embedded projects and found value-flavoured
fields useful already in 2017
>
<https://wiki.forth-ev.de/doku.php/events:tagung-2017:forth-in-grossen-projekten>.
Nick Nelson works on (bigger) embedded projects and also finds
value-flavoured fields useful. See
<http://www.euroforth.org/ef22/papers/nelson-values.pdf>
<http://www.euroforth.org/ef22/papers/nelson-values-slides.pdf>
<https://www.youtube.com/watch?v=UHcLqxG7UI4>
>
I wonder whether classic structures fit the forth paradigm? Whether by
chance or lack of schooling they seem to have passed me by.
>
According to Moore:
>
"Forth is definitions. If you have a lot of small definitions you are
writing Forth."
>
Structures claim to avoid 'magic numbers'. But are numbers 'magic' when
the name of the definition containing them identifies what they are?
>
Example:
>
\ copy memory data (ofs) to target (a)
: SET.S ( a ofs -- ) dbuf + count rot >target place ;
: SET.W ( a ofs -- ) dbuf + @ swap >target ! ;
: SET.B ( a ofs -- ) dbuf + c@ swap >target c! ;
>
hex
: THIL ( -- ) 1C2 5B set.s ; \ hilight video
: TNOR ( -- ) 1C8 61 set.s ; \ normal video
: TEOL ( -- ) 1BC 69 set.s ; \ clear to end-of-line
: TINS ( -- ) 1AE 6F set.s ; \ insert line
: TDEL ( -- ) 1B4 75 set.s ; \ delete line
: TCR ( -- ) 168 7B set.w ; \ # cols rows
decimal
>
\ modify data
: SET$ ( ofs size -- )
over .str change? if cr ." : " get$ rot !str end 2drop ;
>
: SET# ( ofs -- )
dup @byt . change? if ." : " get# swap !byt end drop ;
>
: ?DEL ( -- ) cr ." DELETE LINE command: " $75 5 set$ ;
: ?INS ( -- ) cr ." INSERT LINE command: " $6F 5 set$ ;
: ?EOL ( -- ) cr ." ERASE TO EOL command: " $69 5 set$ ;
: ?BOLD ( -- ) cr ." BOLD VIDEO command: " $5B 5 set$ ;
: ?NORM ( -- ) cr ." NORMAL VIDEO command: " $61 5 set$ ;
: ?ROWS ( -- ) cr ." Number of screen rows: " $7C set# ;
: ?COLS ( -- ) cr ." Number of screen cols: " $7B set# ;
>
I agree with this approach. The following example follows the
same principle.
My view of class is fields with DOER words that can do anything.
So no getters and setters, but methods that work 0n an offset
in the class data buffer.
The advantages come on the fore handling the pesky
termios structures. The methods could be replaced by bit savvy
setters and getters but I don't even see how that is done.
Note that tcget works on the whole data buffer, ixon works on the
4 byte first part, but the address c.q. offset is the same.
WANT class
\ In behalf of this program, this is a supposedly general purpose setup
\ for serial communication.
WANT BAG
WANT BAG-WHERE
<SNIP>
\ Set bits into ADDRESS according to MASK.
: set-bits OVER @ OR SWAP ! ;
\ Clear bits into ADDRESS according to MASK.
: clear-bits INVERT OVER @ AND SWAP ! ;
\ The infamous termios struct from c. See termios.h.
\ Size must be 0x3c.
class TERMIOS
\ Method working on the whole struct
\ Get and set this struct for file DESCRIPTOR.
M: tcget TCGETS SWAP __NR_ioctl XOS ?ERRUR M;
M: tcset TCSETSF SWAP __NR_ioctl XOS ?ERRUR M;
\ All these methods working on the c_iflags field.
M: ixon $0400 set-bits M;
M: no-ixon $0400 clear-bits M;
M: ixoff $1000 set-bits M;
M: no-ixoff $1000 clear-bits M;
M: ixany $0800 set-bits M;
M: no-ixany $0800 clear-bits M;
M: no-ix $1C00 clear-bits M;
M: iraw $FFFF clear-bits M;
M: c_iflag M; 4 ALLOT
M: opost $1 set-bits M;
M: oraw $FFFF clear-bits M;
M: c_oflag M; 4 ALLOT
\ All these methods working on the c_cflags field.
M: parity $100 set-bits M;
M: no-parity $100 clear-bits M;
M: doublestop $40 set-bits M;
M: no-doublestop $40 clear-bits M;
M: size8 $30 set-bits M;
M: size7 $30 clear-bits $10 set-bits M;
M: set-speed-low DUP $F clear-bits SWAP get-code set-bits M;
M: c_cflag M; 4 ALLOT
\ All these methods working on the c_lflags field.
M: icanon $02 set-bits M;
M: no-icanon $02 clear-bits M;
M: echo $08 set-bits M;
M: no-echo $08 clear-bits M;
M: echoe $10 set-bits M;
M: no-echoe $10 clear-bits M;
M: isig $01 set-bits M;
M: no-isig $01 clear-bits M;
M: lraw $FF clear-bits M;
M: c_lflag M; 4 ALLOT
M: c_line M; 1 ( !) ALLOT \ We are now at offset $11
M: set-timeout no-icanon 5 + C! M; \ `VTIME' Timeout in DECISECONDS.
M: set-min no-icanon 6 + C! M; \ `VMIN' Minimal AMOUNT to recieve.
M: c_cc M;
$34 $11 - ALLOT \ to make speeds at an offset of $34
\ The offsets of the c_ispeed and c_ospeed are $34 $38
\ Stolen from c in 32 and 64 bits on a 64 bits system.
\ Set SPEED, for input and output the same.
\ In 64 bits those don't fit, needs an extra "1 CELLS ALLOT".
M: set-speed-high 2DUP ! 4 + ! M;
\ ALIGN \ To 32 bits intended but unaligned word better!
M: c_ispeed M; 4 ALLOT
M: c_ospeed M; 4 ALLOT
M: termios-size ^TERMIOS @ - M;
M: termios-erase >R ^TERMIOS @ R> OVER - ERASE M;
M: termios-compare >R ^TERMIOS @ R> OVER - CORA 1004 ?ERROR M;
1 CELLS ALLOT
endclass
TERMIOS serial-port
serial-port \ Make current
<SNIP>
Note that the sheer amount of bits that has to be handled is the reason
to like its compactness. Compare it to the serial routines of gforth.
Groetjes Albert
-- Temu exploits Christians: (Disclaimer, only 10 apostles)Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style WallArt For Home, Office And Garden Decor - Perfect For Windows, Bars,And Gifts For Friends Family And Colleagues.