Merge pull request #70 from philburk/ignoreds
[pforth] / fth / c_struct.fth
CommitLineData
8e9db35f
PB
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
4\
5\ This file must be loaded before loading any .J files.
6\
7\ Author: Phil Burk
1a088514 8\ Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
8e9db35f
PB
9\
10\ The pForth software code is dedicated to the public domain,
11\ and any third party may reproduce, distribute and modify
12\ the pForth software code or any derivative works thereof
13\ without any compensation or license. The pForth software
14\ code is provided on an "as is" basis without any warranty
15\ of any kind, including, without limitation, the implied
16\ warranties of merchantability and fitness for a particular
17\ purpose and their equivalents under the laws of any jurisdiction.
18\
19\ MOD: PLB 1/16/87 Use abort" instead of er.report
20\ MDH 4/14/87 Added sign-extend words to ..@
21\ MOD: PLB 9/1/87 Add pointer to last member for debug.
22\ MOD: MDH 4/30/88 Use fast addressing for ..@ and ..!
23\ MOD: PLB/MDH 9/30/88 Fixed offsets for 16@+long and 8@+long
24\ fixed OB.COMPILE.+@/! for 0 offset
25\ MOD: PLB 1/11/89 Added EVEN-UP in case of last member BYTE
26\ MOD: RDG 9/19/90 Added floating point member support
27\ MOD: PLB 12/21/90 Optimized ..@ and ..!
28\ 00001 PLB 11/20/91 Make structures IMMEDIATE with ALITERAL for speed
29\ Don't need MOVEQ.L #0,D0 for 16@+WORD and 8@+WORD
30\ 00002 PLB 8/3/92 Added S@ and S!, and support for RPTR
31\ 951112 PLB Added FS@ and FS!
32\ This version for the pForth system.
33
34ANEW TASK-C_STRUCT
35
36decimal
37\ STRUCT ======================================================
38: <:STRUCT> ( pfa -- , run time action for a structure)
39 [COMPILE] CREATE
40 @ even-up here swap dup ( -- here # # )
41 allot ( make room for ivars )
42 0 fill ( initialize to zero )
43\ immediate \ 00001
44\ DOES> [compile] aliteral \ 00001
45;
46
47\ Contents of a structure definition.
48\ CELL 0 = size of instantiated structures
49\ CELL 1 = #bytes to last member name in dictionary.
50\ this is relative so it will work with structure
51\ relocation schemes like MODULE
52
53: :STRUCT ( -- , Create a 'C' structure )
54\ Check pairs
55 ob-state @
56 warning" :STRUCT - Previous :STRUCT or :CLASS unfinished!"
57 ob_def_struct ob-state ! ( set pair flags )
58\
59\ Create new struct defining word.
60 CREATE
61 here ob-current-class ! ( set current )
62 0 , ( initial ivar offset )
63 0 , ( location for #byte to last )
64 DOES> <:STRUCT>
65;
66
67: ;STRUCT ( -- , terminate structure )
68 ob-state @ ob_def_struct = NOT
69 abort" ;STRUCT - Missing :STRUCT above!"
70 false ob-state !
71
72\ Point to last member.
73 latest ob-current-class @ body> >name - ( byte difference of NFAs )
74 ob-current-class @ cell+ !
75\
76\ Even up byte offset in case last member was BYTE.
77 ob-current-class @ dup @ even-up swap !
78;
79
80\ Member reference words.
81: .. ( object <member> -- member_address , calc addr of member )
82 ob.stats? drop state @
83 IF ?dup
84 IF [compile] literal compile +
85 THEN
86 ELSE +
87 THEN
88; immediate
89
90
91: (S+C!) ( val addr offset -- ) + c! ;
92: (S+W!) ( val addr offset -- ) + w! ;
93: (S+!) ( val addr offset -- ) + ! ;
94: (S+REL!) ( ptr addr offset -- ) + >r if.use->rel r> ! ;
95
96: compile+!bytes ( offset size -- )
cf39ac97 97 \ ." compile+!bytes ( " over . dup . ." )" cr
8e9db35f
PB
98 swap [compile] literal \ compile offset into word
99 CASE
100 cell OF compile (s+!) ENDOF
101 2 OF compile (s+w!) ENDOF
102 1 OF compile (s+c!) ENDOF
e14f2533 103 -cell OF compile (s+rel!) ENDOF \ 00002
8e9db35f
PB
104 -2 OF compile (s+w!) ENDOF
105 -1 OF compile (s+c!) ENDOF
106 true abort" s! - illegal size!"
107 ENDCASE
108;
109
110: !BYTES ( value address size -- )
111 CASE
112 cell OF ! ENDOF
e14f2533 113 -cell OF ( aptr addr ) swap if.use->rel swap ! ENDOF \ 00002
8e9db35f
PB
114 ABS
115 2 OF w! ENDOF
116 1 OF c! ENDOF
117 true abort" s! - illegal size!"
118 ENDCASE
119;
120
121\ These provide ways of setting and reading members values
122\ without knowing their size in bytes.
123: (S!) ( offset size -- , compile proper fetch )
124 state @
125 IF compile+!bytes
126 ELSE ( -- value addr off size )
127 >r + r> !bytes
128 THEN
129;
130: S! ( value object <member> -- , store value in member )
131 ob.stats?
132 (s!)
133; immediate
134
135: @BYTES ( addr +/-size -- value )
136 CASE
137 cell OF @ ENDOF
138 2 OF w@ ENDOF
139 1 OF c@ ENDOF
e14f2533 140 -cell OF @ if.rel->use ENDOF \ 00002
8e9db35f
PB
141 -2 OF w@ w->s ENDOF
142 -1 OF c@ b->s ENDOF
143 true abort" s@ - illegal size!"
144 ENDCASE
145;
146
147: (S+UC@) ( addr offset -- val ) + c@ ;
148: (S+UW@) ( addr offset -- val ) + w@ ;
149: (S+@) ( addr offset -- val ) + @ ;
150: (S+REL@) ( addr offset -- val ) + @ if.rel->use ;
151: (S+C@) ( addr offset -- val ) + c@ b->s ;
152: (S+W@) ( addr offset -- val ) + w@ w->s ;
153
154: compile+@bytes ( offset size -- )
cf39ac97 155 \ ." compile+@bytes ( " over . dup . ." )" cr
8e9db35f
PB
156 swap [compile] literal \ compile offset into word
157 CASE
158 cell OF compile (s+@) ENDOF
159 2 OF compile (s+uw@) ENDOF
160 1 OF compile (s+uc@) ENDOF
e14f2533 161 -cell OF compile (s+rel@) ENDOF \ 00002
8e9db35f
PB
162 -2 OF compile (s+w@) ENDOF
163 -1 OF compile (s+c@) ENDOF
164 true abort" s@ - illegal size!"
165 ENDCASE
166;
167
168: (S@) ( offset size -- , compile proper fetch )
169 state @
170 IF compile+@bytes
171 ELSE >r + r> @bytes
172 THEN
173;
174
175: S@ ( object <member> -- value , fetch value from member )
176 ob.stats?
177 (s@)
178; immediate
179
8e9db35f
PB
180exists? F* [IF]
181\ 951112 Floating Point support
182: FLPT ( <name> -- , declare space for a floating point value. )
183 1 floats bytes
184;
185: (S+F!) ( val addr offset -- ) + f! ;
186: (S+F@) ( addr offset -- val ) + f@ ;
187
188: FS! ( value object <member> -- , fetch value from member )
189 ob.stats?
190 1 floats <> abort" FS@ with non-float!"
191 state @
192 IF
193 [compile] literal
194 compile (s+f!)
195 ELSE (s+f!)
196 THEN
197; immediate
198: FS@ ( object <member> -- value , fetch value from member )
199 ob.stats?
200 1 floats <> abort" FS@ with non-float!"
201 state @
202 IF
203 [compile] literal
204 compile (s+f@)
205 ELSE (s+f@)
206 THEN
207; immediate
208[THEN]
209
2100 [IF]
211:struct mapper
212 long map_l1
213 long map_l2
8e9db35f
PB
214 short map_s1
215 ushort map_s2
216 byte map_b1
217 ubyte map_b2
e14f2533
PB
218 aptr map_a1
219 rptr map_r1
220 flpt map_f1
8e9db35f
PB
221;struct
222mapper map1
223
e14f2533 224." compiling TT" cr
8e9db35f 225: TT
e14f2533
PB
226 123456 map1 s! map_l1
227 map1 s@ map_l1 123456 - abort" map_l1 failed!"
228 987654 map1 s! map_l2
229 map1 s@ map_l2 987654 - abort" map_l2 failed!"
230
8e9db35f 231 -500 map1 s! map_s1
e14f2533 232 map1 s@ map_s1 dup . cr -500 - abort" map_s1 failed!"
8e9db35f
PB
233 -500 map1 s! map_s2
234 map1 s@ map_s2 -500 $ FFFF and - abort" map_s2 failed!"
e14f2533 235
8e9db35f
PB
236 -89 map1 s! map_b1
237 map1 s@ map_b1 -89 - abort" map_s1 failed!"
238 here map1 s! map_r1
239 map1 s@ map_r1 here - abort" map_r1 failed!"
240 -89 map1 s! map_b2
241 map1 s@ map_b2 -89 $ FF and - abort" map_s2 failed!"
242 23.45 map1 fs! map_f1
243 map1 fs@ map_f1 f. ." =?= 23.45" cr
244;
245." Testing c_struct.fth" cr
246TT
247[THEN]