1 \ @(#) c_struct.fth 98/01/26 1.2
2 \ STRUCTUREs are for interfacing with 'C' programs.
3 \ Structures are created using :STRUCT and ;STRUCT
5 \ This file must be loaded before loading any .J files.
8 \ Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
10 \ Permission to use, copy, modify, and/or distribute this
11 \ software for any purpose with or without fee is hereby granted.
13 \ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
14 \ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
15 \ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
16 \ THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
17 \ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
18 \ FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 \ CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 \ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 \ MOD: PLB 1/16/87 Use abort" instead of er.report
23 \ MDH 4/14/87 Added sign-extend words to ..@
24 \ MOD: PLB 9/1/87 Add pointer to last member for debug.
25 \ MOD: MDH 4/30/88 Use fast addressing for ..@ and ..!
26 \ MOD: PLB/MDH 9/30/88 Fixed offsets for 16@+long and 8@+long
27 \ fixed OB.COMPILE.+@/! for 0 offset
28 \ MOD: PLB 1/11/89 Added EVEN-UP in case of last member BYTE
29 \ MOD: RDG 9/19/90 Added floating point member support
30 \ MOD: PLB 12/21/90 Optimized ..@ and ..!
31 \ 00001 PLB 11/20/91 Make structures IMMEDIATE with ALITERAL for speed
32 \ Don't need MOVEQ.L #0,D0 for 16@+WORD and 8@+WORD
33 \ 00002 PLB 8/3/92 Added S@ and S!, and support for RPTR
34 \ 951112 PLB Added FS@ and FS!
35 \ This version for the pForth system.
40 \ STRUCT ======================================================
41 : <:STRUCT> ( pfa -- , run time action for a structure)
43 @ even-up here swap dup ( -- here # # )
44 allot ( make room for ivars )
45 0 fill ( initialize to zero )
47 \ DOES> [compile] aliteral \ 00001
50 \ Contents of a structure definition.
51 \ CELL 0 = size of instantiated structures
52 \ CELL 1 = #bytes to last member name in dictionary.
53 \ this is relative so it will work with structure
54 \ relocation schemes like MODULE
56 : :STRUCT ( -- , Create a 'C' structure )
59 warning" :STRUCT - Previous :STRUCT or :CLASS unfinished!"
60 ob_def_struct ob-state ! ( set pair flags )
62 \ Create new struct defining word.
64 here ob-current-class ! ( set current )
65 0 , ( initial ivar offset )
66 0 , ( location for #byte to last )
70 : ;STRUCT ( -- , terminate structure )
71 ob-state @ ob_def_struct = NOT
72 abort" ;STRUCT - Missing :STRUCT above!"
75 \ Point to last member.
76 latest ob-current-class @ body> >name - ( byte difference of NFAs )
77 ob-current-class @ cell+ !
79 \ Even up byte offset in case last member was BYTE.
80 ob-current-class @ dup @ even-up swap !
83 \ Member reference words.
84 : .. ( object <member> -- member_address , calc addr of member )
85 ob.stats? drop state @
87 IF [compile] literal compile +
94 : (S+C!) ( val addr offset -- ) + c! ;
95 : (S+W!) ( val addr offset -- ) + w! ;
96 : (S+!) ( val addr offset -- ) + ! ;
97 : (S+REL!) ( ptr addr offset -- ) + >r if.use->rel r> ! ;
99 : compile+!bytes ( offset size -- )
100 \ ." compile+!bytes ( " over . dup . ." )" cr
101 swap [compile] literal \ compile offset into word
103 cell OF compile (s+!) ENDOF
104 2 OF compile (s+w!) ENDOF
105 1 OF compile (s+c!) ENDOF
106 -cell OF compile (s+rel!) ENDOF \ 00002
107 -2 OF compile (s+w!) ENDOF
108 -1 OF compile (s+c!) ENDOF
109 true abort" s! - illegal size!"
113 : !BYTES ( value address size -- )
116 -cell OF ( aptr addr ) swap if.use->rel swap ! ENDOF \ 00002
120 true abort" s! - illegal size!"
124 \ These provide ways of setting and reading members values
125 \ without knowing their size in bytes.
126 : (S!) ( offset size -- , compile proper fetch )
129 ELSE ( -- value addr off size )
133 : S! ( value object <member> -- , store value in member )
138 : @BYTES ( addr +/-size -- value )
143 -cell OF @ if.rel->use ENDOF \ 00002
146 true abort" s@ - illegal size!"
150 : (S+UC@) ( addr offset -- val ) + c@ ;
151 : (S+UW@) ( addr offset -- val ) + w@ ;
152 : (S+@) ( addr offset -- val ) + @ ;
153 : (S+REL@) ( addr offset -- val ) + @ if.rel->use ;
154 : (S+C@) ( addr offset -- val ) + c@ b->s ;
155 : (S+W@) ( addr offset -- val ) + w@ w->s ;
157 : compile+@bytes ( offset size -- )
158 \ ." compile+@bytes ( " over . dup . ." )" cr
159 swap [compile] literal \ compile offset into word
161 cell OF compile (s+@) ENDOF
162 2 OF compile (s+uw@) ENDOF
163 1 OF compile (s+uc@) ENDOF
164 -cell OF compile (s+rel@) ENDOF \ 00002
165 -2 OF compile (s+w@) ENDOF
166 -1 OF compile (s+c@) ENDOF
167 true abort" s@ - illegal size!"
171 : (S@) ( offset size -- , compile proper fetch )
178 : S@ ( object <member> -- value , fetch value from member )
184 \ 951112 Floating Point support
185 : FLPT ( <name> -- , declare space for a floating point value. )
188 : (S+F!) ( val addr offset -- ) + f! ;
189 : (S+F@) ( addr offset -- val ) + f@ ;
191 : FS! ( value object <member> -- , fetch value from member )
193 1 floats <> abort" FS@ with non-float!"
201 : FS@ ( object <member> -- value , fetch value from member )
203 1 floats <> abort" FS@ with non-float!"
229 123456 map1 s! map_l1
230 map1 s@ map_l1 123456 - abort" map_l1 failed!"
231 987654 map1 s! map_l2
232 map1 s@ map_l2 987654 - abort" map_l2 failed!"
235 map1 s@ map_s1 dup . cr -500 - abort" map_s1 failed!"
237 map1 s@ map_s2 -500 $ FFFF and - abort" map_s2 failed!"
240 map1 s@ map_b1 -89 - abort" map_s1 failed!"
242 map1 s@ map_r1 here - abort" map_r1 failed!"
244 map1 s@ map_b2 -89 $ FF and - abort" map_s2 failed!"
245 23.45 map1 fs! map_f1
246 map1 fs@ map_f1 f. ." =?= 23.45" cr
248 ." Testing c_struct.fth" cr