genie-denotation.c
1 //! @file genie-denotation.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-2024 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 //! Interpreter routines for denotations.
25
26 #include "a68g.h"
27 #include "a68g-genie.h"
28 #include "a68g-frames.h"
29 #include "a68g-prelude.h"
30 #include "a68g-mp.h"
31 #include "a68g-transput.h"
32
33 //! @brief Push routine text.
34
35 PROP_T genie_routine_text (NODE_T * p)
36 {
37 static PROP_T self;
38 A68_PROCEDURE z = *(A68_PROCEDURE *) (FRAME_OBJECT (OFFSET (TAX (p))));
39 PUSH_PROCEDURE (p, z);
40 UNIT (&self) = genie_routine_text;
41 SOURCE (&self) = p;
42 return self;
43 }
44
45 //! @brief Push format text.
46
47 PROP_T genie_format_text (NODE_T * p)
48 {
49 static PROP_T self;
50 A68_FORMAT z = *(A68_FORMAT *) (FRAME_OBJECT (OFFSET (TAX (p))));
51 PUSH_FORMAT (p, z);
52 UNIT (&self) = genie_format_text;
53 SOURCE (&self) = p;
54 return self;
55 }
56
57 //! @brief Push NIL.
58
59 PROP_T genie_nihil (NODE_T * p)
60 {
61 PROP_T self;
62 PUSH_REF (p, nil_ref);
63 UNIT (&self) = genie_nihil;
64 SOURCE (&self) = p;
65 return self;
66 }
67
68 //! @brief Push constant stored in the tree.
69
70 PROP_T genie_constant (NODE_T * p)
71 {
72 PUSH (p, CONSTANT (GINFO (p)), SIZE (GINFO (p)));
73 return GPROP (p);
74 }
75
76 //! @brief Push value of denotation.
77
78 PROP_T genie_denotation (NODE_T * p)
79 {
80 MOID_T *moid = MOID (p);
81 PROP_T self;
82 UNIT (&self) = genie_denotation;
83 SOURCE (&self) = p;
84 if (moid == M_INT) {
85 // INT denotation.
86 A68_INT z;
87 NODE_T *s = IS (SUB (p), SHORTETY) ? NEXT_SUB (p) : SUB (p);
88 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
89 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
90 exit_genie (p, A68_RUNTIME_ERROR);
91 }
92 UNIT (&self) = genie_constant;
93 STATUS (&z) = INIT_MASK;
94 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) SIZE (M_INT));
95 SIZE (GINFO (p)) = SIZE (M_INT);
96 COPY (CONSTANT (GINFO (p)), &z, SIZE (M_INT));
97 PUSH_VALUE (p, VALUE ((A68_INT *) (CONSTANT (GINFO (p)))), A68_INT);
98 return self;
99 }
100 if (moid == M_REAL) {
101 // REAL denotation.
102 A68_REAL z;
103 NODE_T *s = IS (SUB (p), SHORTETY) ? NEXT_SUB (p) : SUB (p);
104 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
105 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
106 exit_genie (p, A68_RUNTIME_ERROR);
107 }
108 STATUS (&z) = INIT_MASK;
109 UNIT (&self) = genie_constant;
110 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) SIZE_ALIGNED (A68_REAL));
111 SIZE (GINFO (p)) = SIZE_ALIGNED (A68_REAL);
112 COPY (CONSTANT (GINFO (p)), &z, SIZE_ALIGNED (A68_REAL));
113 PUSH_VALUE (p, VALUE ((A68_REAL *) (CONSTANT (GINFO (p)))), A68_REAL);
114 return self;
115 }
116 #if (A68_LEVEL >= 3)
117 if (moid == M_LONG_INT) {
118 // LONG INT denotation.
119 A68_LONG_INT z;
120 size_t len = (size_t) SIZE_ALIGNED (A68_LONG_INT);
121 NODE_T *s = IS (SUB (p), LONGETY) ? NEXT_SUB (p) : SUB (p);
122 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
123 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
124 exit_genie (p, A68_RUNTIME_ERROR);
125 }
126 UNIT (&self) = genie_constant;
127 STATUS (&z) = INIT_MASK;
128 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) len);
129 SIZE (GINFO (p)) = len;
130 COPY (CONSTANT (GINFO (p)), &z, len);
131 PUSH_VALUE (p, VALUE ((A68_LONG_INT *) (CONSTANT (GINFO (p)))), A68_LONG_INT);
132 return self;
133 }
134 if (moid == M_LONG_REAL) {
135 // LONG REAL denotation.
136 A68_LONG_REAL z;
137 NODE_T *s = IS (SUB (p), LONGETY) ? NEXT_SUB (p) : SUB (p);
138 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
139 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
140 exit_genie (p, A68_RUNTIME_ERROR);
141 }
142 STATUS (&z) = INIT_MASK;
143 UNIT (&self) = genie_constant;
144 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) SIZE_ALIGNED (A68_LONG_REAL));
145 SIZE (GINFO (p)) = SIZE_ALIGNED (A68_LONG_REAL);
146 COPY (CONSTANT (GINFO (p)), &z, SIZE_ALIGNED (A68_LONG_REAL));
147 PUSH_VALUE (p, VALUE ((A68_LONG_REAL *) (CONSTANT (GINFO (p)))), A68_LONG_REAL);
148 return self;
149 }
150 // LONG BITS denotation.
151 if (moid == M_LONG_BITS) {
152 A68_LONG_BITS z;
153 NODE_T *s = IS (SUB (p), LONGETY) ? NEXT_SUB (p) : SUB (p);
154 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
155 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
156 exit_genie (p, A68_RUNTIME_ERROR);
157 }
158 UNIT (&self) = genie_constant;
159 STATUS (&z) = INIT_MASK;
160 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) SIZE_ALIGNED (A68_LONG_BITS));
161 SIZE (GINFO (p)) = SIZE_ALIGNED (A68_LONG_BITS);
162 COPY (CONSTANT (GINFO (p)), &z, SIZE_ALIGNED (A68_LONG_BITS));
163 PUSH_VALUE (p, VALUE ((A68_LONG_BITS *) (CONSTANT (GINFO (p)))), A68_LONG_BITS);
164 return self;
165 }
166 #endif
167 if (moid == M_LONG_INT || moid == M_LONG_LONG_INT) {
168 // [LONG] LONG INT denotation.
169 int digits = DIGITS (moid);
170 int size = SIZE (moid);
171 NODE_T *number;
172 if (IS (SUB (p), SHORTETY) || IS (SUB (p), LONGETY)) {
173 number = NEXT_SUB (p);
174 } else {
175 number = SUB (p);
176 }
177 MP_T *z = nil_mp (p, digits);
178 if (genie_string_to_value_internal (p, moid, NSYMBOL (number), (BYTE_T *) z) == A68_FALSE) {
179 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
180 exit_genie (p, A68_RUNTIME_ERROR);
181 }
182 MP_STATUS (z) = (MP_T) INIT_MASK;
183 UNIT (&self) = genie_constant;
184 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) size);
185 SIZE (GINFO (p)) = size;
186 COPY (CONSTANT (GINFO (p)), z, size);
187 return self;
188 }
189 if (moid == M_LONG_REAL || moid == M_LONG_LONG_REAL) {
190 // [LONG] LONG REAL denotation.
191 int digits = DIGITS (moid);
192 int size = SIZE (moid);
193 NODE_T *number;
194 if (IS (SUB (p), SHORTETY) || IS (SUB (p), LONGETY)) {
195 number = NEXT_SUB (p);
196 } else {
197 number = SUB (p);
198 }
199 MP_T *z = nil_mp (p, digits);
200 if (genie_string_to_value_internal (p, moid, NSYMBOL (number), (BYTE_T *) z) == A68_FALSE) {
201 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
202 exit_genie (p, A68_RUNTIME_ERROR);
203 }
204 MP_STATUS (z) = (MP_T) INIT_MASK;
205 UNIT (&self) = genie_constant;
206 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) size);
207 SIZE (GINFO (p)) = size;
208 COPY (CONSTANT (GINFO (p)), z, size);
209 return self;
210 }
211 if (moid == M_BITS) {
212 // BITS denotation.
213 A68_BITS z;
214 NODE_T *s = IS (SUB (p), SHORTETY) ? NEXT_SUB (p) : SUB (p);
215 if (genie_string_to_value_internal (p, moid, NSYMBOL (s), (BYTE_T *) & z) == A68_FALSE) {
216 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
217 exit_genie (p, A68_RUNTIME_ERROR);
218 }
219 UNIT (&self) = genie_constant;
220 STATUS (&z) = INIT_MASK;
221 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) SIZE_ALIGNED (A68_BITS));
222 SIZE (GINFO (p)) = SIZE_ALIGNED (A68_BITS);
223 COPY (CONSTANT (GINFO (p)), &z, SIZE_ALIGNED (A68_BITS));
224 PUSH_VALUE (p, VALUE ((A68_BITS *) (CONSTANT (GINFO (p)))), A68_BITS);
225 }
226 if (moid == M_LONG_BITS || moid == M_LONG_LONG_BITS) {
227 // [LONG] LONG BITS denotation.
228 int digits = DIGITS (moid);
229 int size = SIZE (moid);
230 NODE_T *number;
231 if (IS (SUB (p), SHORTETY) || IS (SUB (p), LONGETY)) {
232 number = NEXT_SUB (p);
233 } else {
234 number = SUB (p);
235 }
236 MP_T *z = nil_mp (p, digits);
237 if (genie_string_to_value_internal (p, moid, NSYMBOL (number), (BYTE_T *) z) == A68_FALSE) {
238 diagnostic (A68_RUNTIME_ERROR, p, ERROR_IN_DENOTATION, moid);
239 exit_genie (p, A68_RUNTIME_ERROR);
240 }
241 MP_STATUS (z) = (MP_T) INIT_MASK;
242 UNIT (&self) = genie_constant;
243 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) size);
244 SIZE (GINFO (p)) = size;
245 COPY (CONSTANT (GINFO (p)), z, size);
246 return self;
247 }
248 if (moid == M_BOOL) {
249 // BOOL denotation.
250 A68_BOOL z;
251 ASSERT (genie_string_to_value_internal (p, M_BOOL, NSYMBOL (p), (BYTE_T *) & z) == A68_TRUE);
252 PUSH_VALUE (p, VALUE (&z), A68_BOOL);
253 return self;
254 } else if (moid == M_CHAR) {
255 // CHAR denotation.
256 PUSH_VALUE (p, TO_UCHAR (NSYMBOL (p)[0]), A68_CHAR);
257 return self;
258 } else if (moid == M_ROW_CHAR) {
259 // [] CHAR denotation - permanent string in the heap.
260 A68_REF z;
261 A68_ARRAY *arr;
262 A68_TUPLE *tup;
263 z = c_to_a_string (p, NSYMBOL (p), DEFAULT_WIDTH);
264 GET_DESCRIPTOR (arr, tup, &z);
265 BLOCK_GC_HANDLE (&z);
266 BLOCK_GC_HANDLE (&(ARRAY (arr)));
267 UNIT (&self) = genie_constant;
268 CONSTANT (GINFO (p)) = (void *) get_heap_space ((size_t) A68_REF_SIZE);
269 SIZE (GINFO (p)) = A68_REF_SIZE;
270 COPY (CONSTANT (GINFO (p)), &z, A68_REF_SIZE);
271 PUSH_REF (p, *(A68_REF *) (CONSTANT (GINFO (p))));
272 (void) tup;
273 return self;
274 }
275 if (moid == M_VOID) {
276 // VOID denotation: EMPTY.
277 return self;
278 }
279 return self;
280 }
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|