moids-size.c
1 //! @file moids-size.c
2 //! @author J. Marcel van der Veer
3 //!
4 //! @section Copyright
5 //!
6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
7 //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
8 //!
9 //! @section License
10 //!
11 //! This program is free software; you can redistribute it and/or modify it
12 //! under the terms of the GNU General Public License as published by the
13 //! Free Software Foundation; either version 3 of the License, or
14 //! (at your option) any later version.
15 //!
16 //! This program is distributed in the hope that it will be useful, but
17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 //! more details. You should have received a copy of the GNU General Public
20 //! License along with this program. If not, see [http://www.gnu.org/licenses/].
21
22 //! @section Synopsis
23 //!
24 //! Memory footprint (size) of a mode.
25
26 #include "a68g.h"
27 #include "a68g-prelude.h"
28 #include "a68g-mp.h"
29 #include "a68g-genie.h"
30 #include "a68g-postulates.h"
31 #include "a68g-parser.h"
32 #include "a68g-options.h"
33 #include "a68g-optimiser.h"
34 #include "a68g-listing.h"
35
36 // Next are routines to calculate the size of a mode.
37
38 //! @brief Max unitings to simplout.
39
40 void max_unitings_to_simplout (NODE_T * p, int *max)
41 {
42 for (; p != NO_NODE; FORWARD (p)) {
43 if (IS (p, UNITING) && MOID (p) == M_SIMPLOUT) {
44 MOID_T *q = MOID (SUB (p));
45 if (q != M_SIMPLOUT) {
46 int size = moid_size (q);
47 MAXIMISE (*max, size);
48 }
49 }
50 max_unitings_to_simplout (SUB (p), max);
51 }
52 }
53
54 //! @brief Get max simplout size.
55
56 void get_max_simplout_size (NODE_T * p)
57 {
58 A68 (max_simplout_size) = A68_REF_SIZE; // For anonymous SKIP
59 max_unitings_to_simplout (p, &A68 (max_simplout_size));
60 }
61
62 //! @brief Set moid sizes.
63
64 void set_moid_sizes (MOID_T * z)
65 {
66 for (; z != NO_MOID; FORWARD (z)) {
67 SIZE (z) = moid_size (z);
68 DIGITS (z) = moid_digits (z);
69 }
70 // Next is guaranteed.
71 #if (A68_LEVEL >= 3)
72 SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
73 DIGITS (M_LONG_REAL) = 0;
74 #else
75 SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
76 DIGITS (M_LONG_REAL) = moid_digits (M_LONG_REAL);
77 #endif
78 SIZE (M_LONG_LONG_REAL) = moid_size (M_LONG_LONG_REAL);
79 DIGITS (M_LONG_LONG_REAL) = moid_digits (M_LONG_LONG_REAL);
80 SIZEC (M_LONG_COMPLEX) = SIZE (M_LONG_REAL);
81 SIZEC (M_REF_LONG_COMPLEX) = SIZE (M_LONG_REAL);
82 DIGITSC (M_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
83 DIGITSC (M_REF_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
84 SIZEC (M_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
85 SIZEC (M_REF_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
86 DIGITSC (M_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
87 DIGITSC (M_REF_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
88 }
89
90 //! @brief Moid size 2.
91
92 int moid_size_2 (MOID_T * p)
93 {
94 if (p == NO_MOID) {
95 return 0;
96 } else if (EQUIVALENT (p) != NO_MOID) {
97 return moid_size_2 (EQUIVALENT (p));
98 } else if (p == M_HIP) {
99 return 0;
100 } else if (p == M_VOID) {
101 return 0;
102 } else if (p == M_INT) {
103 return SIZE_ALIGNED (A68_INT);
104 } else if (p == M_LONG_LONG_INT) {
105 return (int) size_long_mp ();
106 } else if (p == M_REAL) {
107 return SIZE_ALIGNED (A68_REAL);
108 } else if (p == M_LONG_INT) {
109 #if (A68_LEVEL >= 3)
110 return SIZE_ALIGNED (A68_LONG_INT);
111 #else
112 return (int) size_mp ();
113 #endif
114 } else if (p == M_LONG_REAL) {
115 #if (A68_LEVEL >= 3)
116 return SIZE_ALIGNED (A68_LONG_REAL);
117 #else
118 return (int) size_mp ();
119 #endif
120 } else if (p == M_LONG_BITS) {
121 #if (A68_LEVEL >= 3)
122 return SIZE_ALIGNED (A68_LONG_BITS);
123 #else
124 return (int) size_mp ();
125 #endif
126 } else if (p == M_LONG_LONG_REAL) {
127 return (int) size_long_mp ();
128 } else if (p == M_BOOL) {
129 return SIZE_ALIGNED (A68_BOOL);
130 } else if (p == M_CHAR) {
131 return SIZE_ALIGNED (A68_CHAR);
132 } else if (p == M_ROW_CHAR) {
133 return A68_REF_SIZE;
134 } else if (p == M_BITS) {
135 return SIZE_ALIGNED (A68_BITS);
136 } else if (p == M_LONG_LONG_BITS) {
137 return (int) size_long_mp ();
138 } else if (p == M_BYTES) {
139 return SIZE_ALIGNED (A68_BYTES);
140 } else if (p == M_LONG_BYTES) {
141 return SIZE_ALIGNED (A68_LONG_BYTES);
142 } else if (p == M_FILE) {
143 return SIZE_ALIGNED (A68_FILE);
144 } else if (p == M_CHANNEL) {
145 return SIZE_ALIGNED (A68_CHANNEL);
146 } else if (p == M_FORMAT) {
147 return SIZE_ALIGNED (A68_FORMAT);
148 } else if (p == M_SEMA) {
149 return A68_REF_SIZE;
150 } else if (p == M_SOUND) {
151 return SIZE_ALIGNED (A68_SOUND);
152 } else if (p == M_COLLITEM) {
153 return SIZE_ALIGNED (A68_COLLITEM);
154 } else if (p == M_HEX_NUMBER) {
155 int k = 0;
156 MAXIMISE (k, SIZE_ALIGNED (A68_BOOL));
157 MAXIMISE (k, SIZE_ALIGNED (A68_CHAR));
158 MAXIMISE (k, SIZE_ALIGNED (A68_INT));
159 MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
160 MAXIMISE (k, SIZE_ALIGNED (A68_BITS));
161 #if (A68_LEVEL >= 3)
162 MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
163 MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
164 MAXIMISE (k, SIZE_ALIGNED (A68_LONG_BITS));
165 #endif
166 return SIZE_ALIGNED (A68_UNION) + k;
167 } else if (p == M_NUMBER) {
168 int k = 0;
169 MAXIMISE (k, A68_REF_SIZE);
170 MAXIMISE (k, SIZE_ALIGNED (A68_INT));
171 MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
172 MAXIMISE (k, (int) size_long_mp ());
173 #if (A68_LEVEL >= 3)
174 MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
175 MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
176 #else
177 MAXIMISE (k, (int) size_mp ());
178 #endif
179 return SIZE_ALIGNED (A68_UNION) + k;
180 } else if (p == M_SIMPLIN) {
181 int k = 0;
182 MAXIMISE (k, A68_REF_SIZE);
183 MAXIMISE (k, SIZE_ALIGNED (A68_FORMAT));
184 MAXIMISE (k, SIZE_ALIGNED (A68_PROCEDURE));
185 MAXIMISE (k, SIZE_ALIGNED (A68_SOUND));
186 return SIZE_ALIGNED (A68_UNION) + k;
187 } else if (p == M_SIMPLOUT) {
188 return SIZE_ALIGNED (A68_UNION) + A68 (max_simplout_size);
189 } else if (IS_REF (p)) {
190 return A68_REF_SIZE;
191 } else if (IS (p, PROC_SYMBOL)) {
192 return SIZE_ALIGNED (A68_PROCEDURE);
193 } else if (IS_ROW (p) && p != M_ROWS) {
194 return A68_REF_SIZE;
195 } else if (p == M_ROWS) {
196 return SIZE_ALIGNED (A68_UNION) + A68_REF_SIZE;
197 } else if (IS_FLEX (p)) {
198 return moid_size (SUB (p));
199 } else if (IS_STRUCT (p)) {
200 PACK_T *z = PACK (p);
201 int size = 0;
202 for (; z != NO_PACK; FORWARD (z)) {
203 size += moid_size (MOID (z));
204 }
205 return size;
206 } else if (IS_UNION (p)) {
207 PACK_T *z = PACK (p);
208 int size = 0;
209 for (; z != NO_PACK; FORWARD (z)) {
210 if (moid_size (MOID (z)) > size) {
211 size = moid_size (MOID (z));
212 }
213 }
214 return SIZE_ALIGNED (A68_UNION) + size;
215 } else if (PACK (p) != NO_PACK) {
216 PACK_T *z = PACK (p);
217 int size = 0;
218 for (; z != NO_PACK; FORWARD (z)) {
219 size += moid_size (MOID (z));
220 }
221 return size;
222 } else {
223 // ?
224 return 0;
225 }
226 }
227
228 //! @brief Moid digits 2.
229
230 int moid_digits_2 (MOID_T * p)
231 {
232 if (p == NO_MOID) {
233 return 0;
234 }
235 if (EQUIVALENT (p) != NO_MOID) {
236 return moid_digits_2 (EQUIVALENT (p));
237 }
238 if (p == M_LONG_INT) {
239 #if (A68_LEVEL >= 3)
240 return 0;
241 #else
242 return (int) mp_digits ();
243 #endif
244 }
245 if (p == M_LONG_LONG_INT) {
246 return (int) long_mp_digits ();
247 }
248 if (p == M_LONG_REAL) {
249 return (int) mp_digits ();
250 }
251 if (p == M_LONG_LONG_REAL) {
252 return (int) long_mp_digits ();
253 }
254 if (p == M_LONG_BITS) {
255 #if (A68_LEVEL >= 3)
256 return 0;
257 #else
258 return (int) mp_digits ();
259 #endif
260 }
261 if (p == M_LONG_LONG_BITS) {
262 return (int) long_mp_digits ();
263 } else {
264 return 0;
265 }
266 }
267
268 //! @brief Moid size.
269
270 int moid_size (MOID_T * p)
271 {
272 SIZE (p) = A68_ALIGN (moid_size_2 (p));
273 return SIZE (p);
274 }
275
276 //! @brief Moid digits.
277
278 int moid_digits (MOID_T * p)
279 {
280 DIGITS (p) = moid_digits_2 (p);
281 return DIGITS (p);
282 }