relicense to 0BSD
[pforth] / fth / member.fth
CommitLineData
8e9db35f
PB
1\ @(#) member.fth 98/01/26 1.2
2\ This files, along with c_struct.fth, supports the definition of
3\ structure members similar to those used in 'C'.
4\
5\ Some of this same code is also used by ODE,
6\ the Object Development Environment.
7\
8\ Author: Phil Burk
1a088514 9\ Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
8e9db35f 10\
1f99f95d
S
11\ Permission to use, copy, modify, and/or distribute this
12\ software for any purpose with or without fee is hereby granted.
13\
14\ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
15\ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
16\ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
17\ THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
18\ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
19\ FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20\ CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21\ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8e9db35f
PB
22\
23\ MOD: PLB 1/16/87 Use abort" instead of er.report.
24\ MOD: PLB 2/19/87 Made OB.MEMBER immediate, use literal.
25\ MOD: PLB/MDH 6/7/88 Use 16 bit values in member defs.
26\ MOD: PLB 7/31/88 Add USHORT and UBYTE.
27\ MOD: PLB 1/20/89 Treat LITERAL as state sensitive.
28\ MOD: RDG 9/19/90 Add floating point member support.
29\ MOD: PLB 6/10/91 Add RPTR
30\ 00001 PLB 8/3/92 Make RPTR a -4 for S@ and S!
31\ 941102 RDG port to pforth
32\ 941108 PLB more porting to pforth. Use ?LITERAL instead os smart literal.
33\ 960710 PLB align long members for SUN
34
35ANEW TASK-MEMBER.FTH
36decimal
37
38: FIND.BODY ( -- , pfa true | $name false , look for word in dict. )
39\ Return address of parameter data.
40 bl word find
41 IF >body true
42 ELSE false
43 THEN
44;
45
46\ Variables shared with object oriented code.
e14f2533
PB
47VARIABLE OB-STATE ( Compilation state. )
48VARIABLE OB-CURRENT-CLASS ( ABS_CLASS_BASE of current class )
491 constant OB_DEF_CLASS ( defining a class )
502 constant OB_DEF_STRUCT ( defining a structure )
8e9db35f 51
e14f2533
PB
52\ A member contains:
53\ cell size of data in bytes (1, 2, cell)
54\ cell offset within structure
55
56cell 1- constant CELL_MASK
57cell negate constant -CELL
58cell constant OB_OFFSET_SIZE
8e9db35f
PB
59
60: OB.OFFSET@ ( member_def -- offset ) @ ;
61: OB.OFFSET, ( value -- ) , ;
62: OB.SIZE@ ( member_def -- offset )
63 ob_offset_size + @ ;
64: OB.SIZE, ( value -- ) , ;
65
66( Members are associated with an offset from the base of a structure. )
67: OB.MAKE.MEMBER ( +-bytes -- , make room in an object at compile time)
68 dup >r ( -- +-b , save #bytes )
69 ABS ( -- |+-b| )
70 ob-current-class @ ( -- b addr-space)
71 tuck @ ( as #b c , current space needed )
e14f2533 72 over CELL_MASK and 0= ( multiple of cell? )
8e9db35f
PB
73 IF
74 aligned
75 ELSE
76 over 1 and 0= ( multiple of two? )
77 IF
78 even-up
79 THEN
80 THEN
81 swap over + rot ! ( update space needed )
82\ Save data in member definition. %M
83 ob.offset, ( save old offset for ivar )
84 r> ob.size, ( store size in bytes for ..! and ..@ )
85;
86
87\ Unions allow one to address the same memory as different members.
88\ Unions work by saving the current offset for members on
89\ the stack and then reusing it for different members.
90: UNION{ ( -- offset , Start union definition. )
91 ob-current-class @ @
92;
93
94: }UNION{ ( old-offset -- new-offset , Middle of union )
95 union{ ( Get current for }UNION to compare )
96 swap ob-current-class @ ! ( Set back to old )
97;
98
99: }UNION ( offset -- , Terminate union definition, check lengths. )
100 union{ = NOT
101 abort" }UNION - Two parts of UNION are not the same size!"
102;
103
104\ Make members compile their offset, for "disposable includes".
105: OB.MEMBER ( #bytes -- , make room in an object at compile time)
106 ( -- offset , run time for structure )
107 CREATE ob.make.member immediate
108 DOES> ob.offset@ ( get offset ) ?literal
109;
110
111: OB.FINDIT ( <thing> -- pfa , get pfa of thing or error )
112 find.body not
113 IF cr count type ." ???"
114 true abort" OB.FINDIT - Word not found!"
115 THEN
116;
117
118: OB.STATS ( member_pfa -- offset #bytes )
119 dup ob.offset@ swap
120 ob.size@
121;
122
123: OB.STATS? ( <member> -- offset #bytes )
124 ob.findit ob.stats
125;
126
127: SIZEOF() ( <struct>OR<class> -- #bytes , lookup size of object )
128 ob.findit @
129 ?literal
130; immediate
131
132\ Basic word for defining structure members.
133: BYTES ( #bytes -- , error check for structure only )
134 ob-state @ ob_def_struct = not
135 abort" BYTES - Only valid in :STRUCT definitions."
136 ob.member
137;
138
139\ Declare various types of structure members.
140\ Negative size indicates a signed member.
141: BYTE ( <name> -- , declare space for a byte )
142 -1 bytes ;
143
144: SHORT ( <name> -- , declare space for a 16 bit value )
145 -2 bytes ;
146
147: LONG ( <name> -- )
148 cell bytes ;
149
150: UBYTE ( <name> -- , declare space for signed byte )
151 1 bytes ;
152
153: USHORT ( <name> -- , declare space for signed 16 bit value )
154 2 bytes ;
155
156
157\ Aliases
158: APTR ( <name> -- ) long ;
e14f2533 159: RPTR ( <name> -- ) -cell bytes ; \ relative relocatable pointer 00001
8e9db35f
PB
160: ULONG ( <name> -- ) long ;
161
162: STRUCT ( <struct> <new_ivar> -- , define a structure as an ivar )
163 [compile] sizeof() bytes
164;