Imported Debian patch 21-11
[debian/pforth] / member.fth
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
9 \ Copyright 1994 3DO, Phil Burk, Larry Polansky, Devid Rosenboom
10 \
11 \ The pForth software code is dedicated to the public domain,
12 \ and any third party may reproduce, distribute and modify
13 \ the pForth software code or any derivative works thereof
14 \ without any compensation or license.  The pForth software
15 \ code is provided on an "as is" basis without any warranty
16 \ of any kind, including, without limitation, the implied
17 \ warranties of merchantability and fitness for a particular
18 \ purpose and their equivalents under the laws of any jurisdiction.
19 \
20 \ MOD: PLB 1/16/87 Use abort" instead of er.report.
21 \ MOD: PLB 2/19/87 Made OB.MEMBER immediate, use literal.
22 \ MOD: PLB/MDH 6/7/88 Use 16 bit values in member defs.
23 \ MOD: PLB 7/31/88 Add USHORT and UBYTE.
24 \ MOD: PLB 1/20/89 Treat LITERAL as state sensitive.
25 \ MOD: RDG 9/19/90 Add floating point member support.
26 \ MOD: PLB 6/10/91 Add RPTR
27 \ 00001 PLB 8/3/92 Make RPTR a -4 for S@ and S!
28 \ 941102 RDG port to pforth
29 \ 941108 PLB more porting to pforth. Use ?LITERAL instead os smart literal.
30 \ 960710 PLB align long members for SUN
31
32 ANEW TASK-MEMBER.FTH
33 decimal
34
35 : FIND.BODY   ( -- , pfa true | $name false , look for word in dict. )
36 \ Return address of parameter data.
37      32 word find
38      IF  >body true
39      ELSE false
40      THEN
41 ;
42
43 \ Variables shared with object oriented code.
44     VARIABLE OB-STATE  ( Compilation state. )
45     VARIABLE OB-CURRENT-CLASS  ( ABS_CLASS_BASE of current class )
46     1 constant OB_DEF_CLASS   ( defining a class )
47     2 constant OB_DEF_STRUCT  ( defining a structure )
48
49 4 constant OB_OFFSET_SIZE
50
51 : OB.OFFSET@ ( member_def -- offset ) @ ;
52 : OB.OFFSET, ( value -- ) , ;
53 : OB.SIZE@ ( member_def -- offset )
54         ob_offset_size + @ ;
55 : OB.SIZE, ( value -- ) , ;
56
57 ( Members are associated with an offset from the base of a structure. )
58 : OB.MAKE.MEMBER ( +-bytes -- , make room in an object at compile time)
59         dup >r  ( -- +-b , save #bytes )
60         ABS     ( -- |+-b| )
61         ob-current-class @ ( -- b addr-space)
62         tuck @          ( as #b c , current space needed )
63         over 3 and 0=        ( multiple of four? )
64         IF
65                 aligned
66         ELSE
67                 over 1 and 0=   ( multiple of two? )
68                 IF
69                         even-up
70                 THEN
71         THEN
72         swap over + rot !    ( update space needed )
73 \ Save data in member definition. %M
74         ob.offset,    ( save old offset for ivar )
75         r> ob.size,   ( store size in bytes for ..! and ..@ )
76 ;
77
78 \ Unions allow one to address the same memory as different members.
79 \ Unions work by saving the current offset for members on
80 \ the stack and then reusing it for different members.
81 : UNION{  ( -- offset , Start union definition. )
82     ob-current-class @ @
83 ;
84
85 : }UNION{ ( old-offset -- new-offset , Middle of union )
86     union{     ( Get current for }UNION to compare )
87     swap ob-current-class @ !  ( Set back to old )
88 ;
89
90 : }UNION ( offset -- , Terminate union definition, check lengths. )
91     union{ = NOT
92     abort" }UNION - Two parts of UNION are not the same size!"
93 ;
94
95 \ Make members compile their offset, for "disposable includes".
96 : OB.MEMBER  ( #bytes -- , make room in an object at compile time)
97            ( -- offset , run time for structure )
98     CREATE ob.make.member immediate
99     DOES> ob.offset@  ( get offset ) ?literal
100 ;
101
102 : OB.FINDIT  ( <thing> -- pfa , get pfa of thing or error )
103     find.body not
104     IF cr count type ."    ???"
105        true abort" OB.FINDIT - Word not found!"
106     THEN
107 ;
108
109 : OB.STATS ( member_pfa --  offset #bytes )
110     dup ob.offset@ swap
111     ob.size@
112 ;
113
114 : OB.STATS? ( <member> -- offset #bytes )
115     ob.findit ob.stats
116 ;
117
118 : SIZEOF() ( <struct>OR<class> -- #bytes , lookup size of object )
119     ob.findit @
120     ?literal
121 ; immediate
122
123 \ Basic word for defining structure members.
124 : BYTES ( #bytes -- , error check for structure only )
125     ob-state @ ob_def_struct = not
126     abort" BYTES - Only valid in :STRUCT definitions."
127     ob.member
128 ;
129
130 \ Declare various types of structure members.
131 \ Negative size indicates a signed member.
132 : BYTE ( <name> -- , declare space for a byte )
133     -1 bytes ;
134
135 : SHORT ( <name> -- , declare space for a 16 bit value )
136     -2 bytes ;
137
138 : LONG ( <name> -- )
139     cell bytes ;
140
141 : UBYTE ( <name> -- , declare space for signed  byte )
142     1 bytes ;
143
144 : USHORT ( <name> -- , declare space for signed 16 bit value )
145     2 bytes ;
146
147
148 \ Aliases
149 : APTR    ( <name> -- ) long ;
150 : RPTR    ( <name> -- ) -4 bytes ; \ relative relocatable pointer 00001
151 : ULONG   ( <name> -- ) long ;
152
153 : STRUCT ( <struct> <new_ivar> -- , define a structure as an ivar )
154     [compile] sizeof() bytes
155 ;