parser-moids-coerce.c
1 //! @file parser-moids-coerce.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 //! Mode coercion driver.
25
26 #include "a68g.h"
27 #include "a68g-parser.h"
28 #include "a68g-moids.h"
29
30 //! @brief Coerce bounds.
31
32 void coerce_bounds (NODE_T * p)
33 {
34 for (; p != NO_NODE; FORWARD (p)) {
35 if (IS (p, UNIT)) {
36 SOID_T q;
37 make_soid (&q, MEEK, M_INT, 0);
38 coerce_unit (p, &q);
39 } else {
40 coerce_bounds (SUB (p));
41 }
42 }
43 }
44
45 //! @brief Coerce declarer.
46
47 void coerce_declarer (NODE_T * p)
48 {
49 for (; p != NO_NODE; FORWARD (p)) {
50 if (IS (p, BOUNDS)) {
51 coerce_bounds (SUB (p));
52 } else {
53 coerce_declarer (SUB (p));
54 }
55 }
56 }
57
58 //! @brief Coerce identity declaration.
59
60 void coerce_identity_declaration (NODE_T * p)
61 {
62 if (p != NO_NODE) {
63 switch (ATTRIBUTE (p)) {
64 case DECLARER: {
65 coerce_declarer (SUB (p));
66 coerce_identity_declaration (NEXT (p));
67 break;
68 }
69 case DEFINING_IDENTIFIER: {
70 SOID_T q;
71 make_soid (&q, STRONG, MOID (p), 0);
72 coerce_unit (NEXT_NEXT (p), &q);
73 break;
74 }
75 default: {
76 coerce_identity_declaration (SUB (p));
77 coerce_identity_declaration (NEXT (p));
78 break;
79 }
80 }
81 }
82 }
83
84 //! @brief Coerce variable declaration.
85
86 void coerce_variable_declaration (NODE_T * p)
87 {
88 if (p != NO_NODE) {
89 switch (ATTRIBUTE (p)) {
90 case DECLARER: {
91 coerce_declarer (SUB (p));
92 coerce_variable_declaration (NEXT (p));
93 break;
94 }
95 case DEFINING_IDENTIFIER: {
96 if (whether (p, DEFINING_IDENTIFIER, ASSIGN_SYMBOL, UNIT, STOP)) {
97 SOID_T q;
98 make_soid (&q, STRONG, SUB_MOID (p), 0);
99 coerce_unit (NEXT_NEXT (p), &q);
100 break;
101 }
102 }
103 default: {
104 coerce_variable_declaration (SUB (p));
105 coerce_variable_declaration (NEXT (p));
106 break;
107 }
108 }
109 }
110 }
111
112 //! @brief Coerce routine text.
113
114 void coerce_routine_text (NODE_T * p)
115 {
116 if (IS (p, PARAMETER_PACK)) {
117 FORWARD (p);
118 }
119 SOID_T w;
120 make_soid (&w, STRONG, MOID (p), 0);
121 coerce_unit (NEXT_NEXT (p), &w);
122 }
123
124 //! @brief Coerce proc declaration.
125
126 void coerce_proc_declaration (NODE_T * p)
127 {
128 if (p == NO_NODE) {
129 return;
130 } else if (IS (p, ROUTINE_TEXT)) {
131 coerce_routine_text (SUB (p));
132 } else {
133 coerce_proc_declaration (SUB (p));
134 coerce_proc_declaration (NEXT (p));
135 }
136 }
137
138 //! @brief Coerce_op_declaration.
139
140 void coerce_op_declaration (NODE_T * p)
141 {
142 if (p == NO_NODE) {
143 return;
144 } else if (IS (p, DEFINING_OPERATOR)) {
145 SOID_T q;
146 make_soid (&q, STRONG, MOID (p), 0);
147 coerce_unit (NEXT_NEXT (p), &q);
148 } else {
149 coerce_op_declaration (SUB (p));
150 coerce_op_declaration (NEXT (p));
151 }
152 }
153
154 //! @brief Coerce brief op declaration.
155
156 void coerce_brief_op_declaration (NODE_T * p)
157 {
158 if (p == NO_NODE) {
159 return;
160 } else if (IS (p, DEFINING_OPERATOR)) {
161 coerce_routine_text (SUB (NEXT_NEXT (p)));
162 } else {
163 coerce_brief_op_declaration (SUB (p));
164 coerce_brief_op_declaration (NEXT (p));
165 }
166 }
167
168 //! @brief Coerce declaration list.
169
170 void coerce_declaration_list (NODE_T * p)
171 {
172 if (p != NO_NODE) {
173 switch (ATTRIBUTE (p)) {
174 case IDENTITY_DECLARATION: {
175 coerce_identity_declaration (SUB (p));
176 break;
177 }
178 case VARIABLE_DECLARATION: {
179 coerce_variable_declaration (SUB (p));
180 break;
181 }
182 case MODE_DECLARATION: {
183 coerce_declarer (SUB (p));
184 break;
185 }
186 case PROCEDURE_DECLARATION:
187 case PROCEDURE_VARIABLE_DECLARATION: {
188 coerce_proc_declaration (SUB (p));
189 break;
190 }
191 case BRIEF_OPERATOR_DECLARATION: {
192 coerce_brief_op_declaration (SUB (p));
193 break;
194 }
195 case OPERATOR_DECLARATION: {
196 coerce_op_declaration (SUB (p));
197 break;
198 }
199 default: {
200 coerce_declaration_list (SUB (p));
201 coerce_declaration_list (NEXT (p));
202 break;
203 }
204 }
205 }
206 }
207
208 //! @brief Coerce serial.
209
210 void coerce_serial (NODE_T * p, SOID_T * q, BOOL_T k)
211 {
212 if (p == NO_NODE) {
213 return;
214 } else if (IS (p, INITIALISER_SERIES)) {
215 coerce_serial (SUB (p), q, A68_FALSE);
216 coerce_serial (NEXT (p), q, k);
217 } else if (IS (p, DECLARATION_LIST)) {
218 coerce_declaration_list (SUB (p));
219 } else if (is_one_of (p, LABEL, SEMI_SYMBOL, EXIT_SYMBOL, STOP)) {
220 coerce_serial (NEXT (p), q, k);
221 } else if (is_one_of (p, SERIAL_CLAUSE, ENQUIRY_CLAUSE, STOP)) {
222 NODE_T *z = NEXT (p);
223 if (z != NO_NODE) {
224 if (IS (z, EXIT_SYMBOL) || IS (z, END_SYMBOL) || IS (z, CLOSE_SYMBOL) || IS (z, OCCA_SYMBOL)) {
225 coerce_serial (SUB (p), q, A68_TRUE);
226 } else {
227 coerce_serial (SUB (p), q, A68_FALSE);
228 }
229 } else {
230 coerce_serial (SUB (p), q, A68_TRUE);
231 }
232 coerce_serial (NEXT (p), q, k);
233 } else if (IS (p, LABELED_UNIT)) {
234 coerce_serial (SUB (p), q, k);
235 } else if (IS (p, UNIT)) {
236 if (k) {
237 coerce_unit (p, q);
238 } else {
239 SOID_T strongvoid;
240 make_soid (&strongvoid, STRONG, M_VOID, 0);
241 coerce_unit (p, &strongvoid);
242 }
243 }
244 }
245
246 //! @brief Coerce closed.
247
248 void coerce_closed (NODE_T * p, SOID_T * q)
249 {
250 if (IS (p, SERIAL_CLAUSE)) {
251 coerce_serial (p, q, A68_TRUE);
252 } else if (is_one_of (p, OPEN_SYMBOL, BEGIN_SYMBOL, STOP)) {
253 coerce_closed (NEXT (p), q);
254 }
255 }
256
257 //! @brief Coerce conditional.
258
259 void coerce_conditional (NODE_T * p, SOID_T * q)
260 {
261 SOID_T w;
262 make_soid (&w, MEEK, M_BOOL, 0);
263 coerce_serial (NEXT_SUB (p), &w, A68_TRUE);
264 FORWARD (p);
265 coerce_serial (NEXT_SUB (p), q, A68_TRUE);
266 if ((FORWARD (p)) != NO_NODE) {
267 if (is_one_of (p, ELSE_PART, CHOICE, STOP)) {
268 coerce_serial (NEXT_SUB (p), q, A68_TRUE);
269 } else if (is_one_of (p, ELIF_PART, BRIEF_ELIF_PART, STOP)) {
270 coerce_conditional (SUB (p), q);
271 }
272 }
273 }
274
275 //! @brief Coerce unit list.
276
277 void coerce_unit_list (NODE_T * p, SOID_T * q)
278 {
279 if (p == NO_NODE) {
280 return;
281 } else if (IS (p, UNIT_LIST)) {
282 coerce_unit_list (SUB (p), q);
283 coerce_unit_list (NEXT (p), q);
284 } else if (is_one_of (p, OPEN_SYMBOL, BEGIN_SYMBOL, COMMA_SYMBOL, STOP)) {
285 coerce_unit_list (NEXT (p), q);
286 } else if (IS (p, UNIT)) {
287 coerce_unit (p, q);
288 coerce_unit_list (NEXT (p), q);
289 }
290 }
291
292 //! @brief Coerce int case.
293
294 void coerce_int_case (NODE_T * p, SOID_T * q)
295 {
296 SOID_T w;
297 make_soid (&w, MEEK, M_INT, 0);
298 coerce_serial (NEXT_SUB (p), &w, A68_TRUE);
299 FORWARD (p);
300 coerce_unit_list (NEXT_SUB (p), q);
301 if ((FORWARD (p)) != NO_NODE) {
302 if (is_one_of (p, OUT_PART, CHOICE, STOP)) {
303 coerce_serial (NEXT_SUB (p), q, A68_TRUE);
304 } else if (is_one_of (p, CASE_OUSE_PART, BRIEF_OUSE_PART, STOP)) {
305 coerce_int_case (SUB (p), q);
306 }
307 }
308 }
309
310 //! @brief Coerce spec unit list.
311
312 void coerce_spec_unit_list (NODE_T * p, SOID_T * q)
313 {
314 for (; p != NO_NODE; FORWARD (p)) {
315 if (is_one_of (p, SPECIFIED_UNIT_LIST, SPECIFIED_UNIT, STOP)) {
316 coerce_spec_unit_list (SUB (p), q);
317 } else if (IS (p, UNIT)) {
318 coerce_unit (p, q);
319 }
320 }
321 }
322
323 //! @brief Coerce united case.
324
325 void coerce_united_case (NODE_T * p, SOID_T * q)
326 {
327 SOID_T w;
328 make_soid (&w, MEEK, MOID (SUB (p)), 0);
329 coerce_serial (NEXT_SUB (p), &w, A68_TRUE);
330 FORWARD (p);
331 coerce_spec_unit_list (NEXT_SUB (p), q);
332 if ((FORWARD (p)) != NO_NODE) {
333 if (is_one_of (p, OUT_PART, CHOICE, STOP)) {
334 coerce_serial (NEXT_SUB (p), q, A68_TRUE);
335 } else if (is_one_of (p, CONFORMITY_OUSE_PART, BRIEF_CONFORMITY_OUSE_PART, STOP)) {
336 coerce_united_case (SUB (p), q);
337 }
338 }
339 }
340
341 //! @brief Coerce loop.
342
343 void coerce_loop (NODE_T * p)
344 {
345 if (IS (p, FOR_PART)) {
346 coerce_loop (NEXT (p));
347 } else if (is_one_of (p, FROM_PART, BY_PART, TO_PART, STOP)) {
348 SOID_T w;
349 make_soid (&w, MEEK, M_INT, 0);
350 coerce_unit (NEXT_SUB (p), &w);
351 coerce_loop (NEXT (p));
352 } else if (IS (p, WHILE_PART)) {
353 SOID_T w;
354 make_soid (&w, MEEK, M_BOOL, 0);
355 coerce_serial (NEXT_SUB (p), &w, A68_TRUE);
356 coerce_loop (NEXT (p));
357 } else if (is_one_of (p, DO_PART, ALT_DO_PART, STOP)) {
358 SOID_T w;
359 NODE_T *do_p = NEXT_SUB (p), *un_p;
360 make_soid (&w, STRONG, M_VOID, 0);
361 coerce_serial (do_p, &w, A68_TRUE);
362 if (IS (do_p, SERIAL_CLAUSE)) {
363 un_p = NEXT (do_p);
364 } else {
365 un_p = do_p;
366 }
367 if (un_p != NO_NODE && IS (un_p, UNTIL_PART)) {
368 SOID_T sw;
369 make_soid (&sw, MEEK, M_BOOL, 0);
370 coerce_serial (NEXT_SUB (un_p), &sw, A68_TRUE);
371 }
372 }
373 }
374
375 //! @brief Coerce struct display.
376
377 void coerce_struct_display (PACK_T ** r, NODE_T * p)
378 {
379 if (p == NO_NODE) {
380 return;
381 } else if (IS (p, UNIT_LIST)) {
382 coerce_struct_display (r, SUB (p));
383 coerce_struct_display (r, NEXT (p));
384 } else if (is_one_of (p, OPEN_SYMBOL, BEGIN_SYMBOL, COMMA_SYMBOL, STOP)) {
385 coerce_struct_display (r, NEXT (p));
386 } else if (IS (p, UNIT)) {
387 SOID_T s;
388 make_soid (&s, STRONG, MOID (*r), 0);
389 coerce_unit (p, &s);
390 FORWARD (*r);
391 coerce_struct_display (r, NEXT (p));
392 }
393 }
394
395 //! @brief Coerce collateral.
396
397 void coerce_collateral (NODE_T * p, SOID_T * q)
398 {
399 if (!(whether (p, BEGIN_SYMBOL, END_SYMBOL, STOP) || whether (p, OPEN_SYMBOL, CLOSE_SYMBOL, STOP))) {
400 if (IS (MOID (q), STRUCT_SYMBOL)) {
401 PACK_T *t = PACK (MOID (q));
402 coerce_struct_display (&t, p);
403 } else if (IS_FLEX (MOID (q))) {
404 SOID_T w;
405 make_soid (&w, STRONG, SLICE (SUB_MOID (q)), 0);
406 coerce_unit_list (p, &w);
407 } else if (IS_ROW (MOID (q))) {
408 SOID_T w;
409 make_soid (&w, STRONG, SLICE (MOID (q)), 0);
410 coerce_unit_list (p, &w);
411 } else {
412 // if (MOID (q) != M_VOID).
413 coerce_unit_list (p, q);
414 }
415 }
416 }
417
418 //! @brief Coerce_enclosed.
419
420 void coerce_enclosed (NODE_T * p, SOID_T * q)
421 {
422 if (IS (p, ENCLOSED_CLAUSE)) {
423 coerce_enclosed (SUB (p), q);
424 } else if (IS (p, CLOSED_CLAUSE)) {
425 coerce_closed (SUB (p), q);
426 } else if (IS (p, COLLATERAL_CLAUSE)) {
427 coerce_collateral (SUB (p), q);
428 } else if (IS (p, PARALLEL_CLAUSE)) {
429 coerce_collateral (SUB (NEXT_SUB (p)), q);
430 } else if (IS (p, CONDITIONAL_CLAUSE)) {
431 coerce_conditional (SUB (p), q);
432 } else if (IS (p, CASE_CLAUSE)) {
433 coerce_int_case (SUB (p), q);
434 } else if (IS (p, CONFORMITY_CLAUSE)) {
435 coerce_united_case (SUB (p), q);
436 } else if (IS (p, LOOP_CLAUSE)) {
437 coerce_loop (SUB (p));
438 }
439 MOID (p) = depref_rows (MOID (p), MOID (q));
440 }
441
442 //! @brief Get monad moid.
443
444 MOID_T *get_monad_moid (NODE_T * p)
445 {
446 if (TAX (p) != NO_TAG && TAX (p) != A68_PARSER (error_tag)) {
447 MOID (p) = MOID (TAX (p));
448 return MOID (PACK (MOID (p)));
449 } else {
450 return M_ERROR;
451 }
452 }
453
454 //! @brief Coerce monad oper.
455
456 void coerce_monad_oper (NODE_T * p, SOID_T * q)
457 {
458 if (p != NO_NODE) {
459 SOID_T z;
460 make_soid (&z, FIRM, MOID (PACK (MOID (TAX (p)))), 0);
461 INSERT_COERCIONS (NEXT (p), MOID (q), &z);
462 }
463 }
464
465 //! @brief Coerce monad formula.
466
467 void coerce_monad_formula (NODE_T * p)
468 {
469 SOID_T e;
470 make_soid (&e, STRONG, get_monad_moid (p), 0);
471 coerce_operand (NEXT (p), &e);
472 coerce_monad_oper (p, &e);
473 }
474
475 //! @brief Coerce operand.
476
477 void coerce_operand (NODE_T * p, SOID_T * q)
478 {
479 if (IS (p, MONADIC_FORMULA)) {
480 coerce_monad_formula (SUB (p));
481 if (MOID (p) != MOID (q)) {
482 make_sub (p, p, FORMULA);
483 INSERT_COERCIONS (p, MOID (p), q);
484 make_sub (p, p, TERTIARY);
485 }
486 MOID (p) = depref_rows (MOID (p), MOID (q));
487 } else if (IS (p, FORMULA)) {
488 coerce_formula (SUB (p), q);
489 INSERT_COERCIONS (p, MOID (p), q);
490 MOID (p) = depref_rows (MOID (p), MOID (q));
491 } else if (IS (p, SECONDARY)) {
492 coerce_unit (SUB (p), q);
493 MOID (p) = MOID (SUB (p));
494 }
495 }
496
497 //! @brief Coerce formula.
498
499 void coerce_formula (NODE_T * p, SOID_T * q)
500 {
501 (void) q;
502 if (IS (p, MONADIC_FORMULA) && NEXT (p) == NO_NODE) {
503 coerce_monad_formula (SUB (p));
504 } else {
505 if (TAX (NEXT (p)) != NO_TAG && TAX (NEXT (p)) != A68_PARSER (error_tag)) {
506 SOID_T s;
507 NODE_T *op = NEXT (p), *nq = NEXT_NEXT (p);
508 MOID_T *w = MOID (op);
509 MOID_T *u = MOID (PACK (w)), *v = MOID (NEXT (PACK (w)));
510 make_soid (&s, STRONG, u, 0);
511 coerce_operand (p, &s);
512 make_soid (&s, STRONG, v, 0);
513 coerce_operand (nq, &s);
514 }
515 }
516 }
517
518 //! @brief Coerce assignation.
519
520 void coerce_assignation (NODE_T * p)
521 {
522 SOID_T w;
523 make_soid (&w, SOFT, MOID (p), 0);
524 coerce_unit (SUB (p), &w);
525 make_soid (&w, STRONG, SUB_MOID (p), 0);
526 coerce_unit (NEXT_NEXT (p), &w);
527 }
528
529 //! @brief Coerce relation.
530
531 void coerce_relation (NODE_T * p)
532 {
533 SOID_T w;
534 make_soid (&w, STRONG, MOID (p), 0);
535 coerce_unit (SUB (p), &w);
536 make_soid (&w, STRONG, MOID (NEXT_NEXT (p)), 0);
537 coerce_unit (SUB (NEXT_NEXT (p)), &w);
538 }
539
540 //! @brief Coerce bool function.
541
542 void coerce_bool_function (NODE_T * p)
543 {
544 SOID_T w;
545 make_soid (&w, STRONG, M_BOOL, 0);
546 coerce_unit (SUB (p), &w);
547 coerce_unit (SUB (NEXT_NEXT (p)), &w);
548 }
549
550 //! @brief Coerce assertion.
551
552 void coerce_assertion (NODE_T * p)
553 {
554 SOID_T w;
555 make_soid (&w, MEEK, M_BOOL, 0);
556 coerce_enclosed (SUB_NEXT (p), &w);
557 }
558
559 //! @brief Coerce selection.
560
561 void coerce_selection (NODE_T * p)
562 {
563 SOID_T w;
564 make_soid (&w, STRONG, MOID (NEXT (p)), 0);
565 coerce_unit (SUB_NEXT (p), &w);
566 }
567
568 //! @brief Coerce cast.
569
570 void coerce_cast (NODE_T * p)
571 {
572 coerce_declarer (p);
573 SOID_T w;
574 make_soid (&w, STRONG, MOID (p), 0);
575 coerce_enclosed (NEXT (p), &w);
576 }
577
578 //! @brief Coerce argument list.
579
580 void coerce_argument_list (PACK_T ** r, NODE_T * p)
581 {
582 for (; p != NO_NODE; FORWARD (p)) {
583 if (IS (p, ARGUMENT_LIST)) {
584 coerce_argument_list (r, SUB (p));
585 } else if (IS (p, UNIT)) {
586 SOID_T s;
587 make_soid (&s, STRONG, MOID (*r), 0);
588 coerce_unit (p, &s);
589 FORWARD (*r);
590 } else if (IS (p, TRIMMER)) {
591 FORWARD (*r);
592 }
593 }
594 }
595
596 //! @brief Coerce call.
597
598 void coerce_call (NODE_T * p)
599 {
600 MOID_T *proc = MOID (p);
601 SOID_T w;
602 make_soid (&w, MEEK, proc, 0);
603 coerce_unit (SUB (p), &w);
604 FORWARD (p);
605 PACK_T *t = PACK (proc);
606 coerce_argument_list (&t, SUB (p));
607 }
608
609 //! @brief Coerce meek int.
610
611 void coerce_meek_int (NODE_T * p)
612 {
613 SOID_T x;
614 make_soid (&x, MEEK, M_INT, 0);
615 coerce_unit (p, &x);
616 }
617
618 //! @brief Coerce trimmer.
619
620 void coerce_trimmer (NODE_T * p)
621 {
622 if (p != NO_NODE) {
623 if (IS (p, UNIT)) {
624 coerce_meek_int (p);
625 coerce_trimmer (NEXT (p));
626 } else {
627 coerce_trimmer (NEXT (p));
628 }
629 }
630 }
631
632 //! @brief Coerce indexer.
633
634 void coerce_indexer (NODE_T * p)
635 {
636 if (p != NO_NODE) {
637 if (IS (p, TRIMMER)) {
638 coerce_trimmer (SUB (p));
639 } else if (IS (p, UNIT)) {
640 coerce_meek_int (p);
641 } else {
642 coerce_indexer (SUB (p));
643 coerce_indexer (NEXT (p));
644 }
645 }
646 }
647
648 //! @brief Coerce_slice.
649
650 void coerce_slice (NODE_T * p)
651 {
652 SOID_T w;
653 MOID_T *row = MOID (p);
654 make_soid (&w, STRONG, row, 0);
655 coerce_unit (SUB (p), &w);
656 coerce_indexer (SUB_NEXT (p));
657 }
658
659 //! @brief Mode coerce diagonal.
660
661 void coerce_diagonal (NODE_T * p)
662 {
663 SOID_T w;
664 if (IS (p, TERTIARY)) {
665 make_soid (&w, MEEK, M_INT, 0);
666 coerce_unit (SUB (p), &w);
667 FORWARD (p);
668 }
669 make_soid (&w, STRONG, MOID (NEXT (p)), 0);
670 coerce_unit (SUB_NEXT (p), &w);
671 }
672
673 //! @brief Mode coerce transpose.
674
675 void coerce_transpose (NODE_T * p)
676 {
677 SOID_T w;
678 make_soid (&w, STRONG, MOID (NEXT (p)), 0);
679 coerce_unit (SUB_NEXT (p), &w);
680 }
681
682 //! @brief Mode coerce row or column function.
683
684 void coerce_row_column_function (NODE_T * p)
685 {
686 SOID_T w;
687 if (IS (p, TERTIARY)) {
688 make_soid (&w, MEEK, M_INT, 0);
689 coerce_unit (SUB (p), &w);
690 FORWARD (p);
691 }
692 make_soid (&w, STRONG, MOID (NEXT (p)), 0);
693 coerce_unit (SUB_NEXT (p), &w);
694 }
695
696 //! @brief Coerce format text.
697
698 void coerce_format_text (NODE_T * p)
699 {
700 for (; p != NO_NODE; FORWARD (p)) {
701 coerce_format_text (SUB (p));
702 if (IS (p, FORMAT_PATTERN)) {
703 SOID_T x;
704 make_soid (&x, STRONG, M_FORMAT, 0);
705 coerce_enclosed (SUB (NEXT_SUB (p)), &x);
706 } else if (IS (p, GENERAL_PATTERN) && NEXT_SUB (p) != NO_NODE) {
707 SOID_T x;
708 make_soid (&x, STRONG, M_ROW_INT, 0);
709 coerce_enclosed (SUB (NEXT_SUB (p)), &x);
710 } else if (IS (p, DYNAMIC_REPLICATOR)) {
711 SOID_T x;
712 make_soid (&x, STRONG, M_INT, 0);
713 coerce_enclosed (SUB (NEXT_SUB (p)), &x);
714 }
715 }
716 }
717
718 //! @brief Coerce unit.
719
720 void coerce_unit (NODE_T * p, SOID_T * q)
721 {
722 if (p == NO_NODE) {
723 return;
724 } else if (is_one_of (p, UNIT, TERTIARY, SECONDARY, PRIMARY, STOP)) {
725 coerce_unit (SUB (p), q);
726 MOID (p) = MOID (SUB (p));
727 // Ex primary.
728 } else if (IS (p, CALL)) {
729 coerce_call (SUB (p));
730 INSERT_COERCIONS (p, MOID (p), q);
731 } else if (IS (p, SLICE)) {
732 coerce_slice (SUB (p));
733 INSERT_COERCIONS (p, MOID (p), q);
734 } else if (IS (p, CAST)) {
735 coerce_cast (SUB (p));
736 INSERT_COERCIONS (p, MOID (p), q);
737 } else if (is_one_of (p, DENOTATION, IDENTIFIER, STOP)) {
738 INSERT_COERCIONS (p, MOID (p), q);
739 } else if (IS (p, FORMAT_TEXT)) {
740 coerce_format_text (SUB (p));
741 INSERT_COERCIONS (p, MOID (p), q);
742 } else if (IS (p, ENCLOSED_CLAUSE)) {
743 coerce_enclosed (p, q);
744 // Ex secondary.
745 } else if (IS (p, SELECTION)) {
746 coerce_selection (SUB (p));
747 INSERT_COERCIONS (p, MOID (p), q);
748 } else if (IS (p, GENERATOR)) {
749 coerce_declarer (SUB (p));
750 INSERT_COERCIONS (p, MOID (p), q);
751 // Ex tertiary.
752 } else if (IS (p, NIHIL)) {
753 if (ATTRIBUTE (MOID (q)) != REF_SYMBOL && MOID (q) != M_VOID) {
754 diagnostic (A68_ERROR, p, ERROR_NO_NAME_REQUIRED);
755 }
756 MOID (p) = depref_rows (MOID (p), MOID (q));
757 } else if (IS (p, FORMULA)) {
758 coerce_formula (SUB (p), q);
759 INSERT_COERCIONS (p, MOID (p), q);
760 } else if (IS (p, DIAGONAL_FUNCTION)) {
761 coerce_diagonal (SUB (p));
762 INSERT_COERCIONS (p, MOID (p), q);
763 } else if (IS (p, TRANSPOSE_FUNCTION)) {
764 coerce_transpose (SUB (p));
765 INSERT_COERCIONS (p, MOID (p), q);
766 } else if (IS (p, ROW_FUNCTION)) {
767 coerce_row_column_function (SUB (p));
768 INSERT_COERCIONS (p, MOID (p), q);
769 } else if (IS (p, COLUMN_FUNCTION)) {
770 coerce_row_column_function (SUB (p));
771 INSERT_COERCIONS (p, MOID (p), q);
772 // Ex unit.
773 } else if (IS (p, JUMP)) {
774 if (MOID (q) == M_PROC_VOID) {
775 make_sub (p, p, PROCEDURING);
776 }
777 MOID (p) = depref_rows (MOID (p), MOID (q));
778 } else if (IS (p, SKIP)) {
779 MOID (p) = depref_rows (MOID (p), MOID (q));
780 } else if (IS (p, ASSIGNATION)) {
781 coerce_assignation (SUB (p));
782 INSERT_COERCIONS (p, MOID (p), q);
783 MOID (p) = depref_rows (MOID (p), MOID (q));
784 } else if (IS (p, IDENTITY_RELATION)) {
785 coerce_relation (SUB (p));
786 INSERT_COERCIONS (p, MOID (p), q);
787 } else if (IS (p, ROUTINE_TEXT)) {
788 coerce_routine_text (SUB (p));
789 INSERT_COERCIONS (p, MOID (p), q);
790 } else if (is_one_of (p, AND_FUNCTION, OR_FUNCTION, STOP)) {
791 coerce_bool_function (SUB (p));
792 INSERT_COERCIONS (p, MOID (p), q);
793 } else if (IS (p, ASSERTION)) {
794 coerce_assertion (SUB (p));
795 INSERT_COERCIONS (p, MOID (p), q);
796 }
797 }
798
799 //! @brief Widen denotation depending on mode required, this is an extension to A68.
800
801 void widen_denotation (NODE_T * p)
802 {
803 #define WIDEN {\
804 *q = *(SUB (q));\
805 ATTRIBUTE (q) = DENOTATION;\
806 MOID (q) = lm;\
807 STATUS_SET (q, OPTIMAL_MASK);\
808 }
809 #define WARN_WIDENING\
810 if (OPTION_PORTCHECK (&A68_JOB) && !(STATUS_TEST (SUB (q), OPTIMAL_MASK))) {\
811 diagnostic (A68_WARNING | A68_FORCE_DIAGNOSTICS, q, WARNING_WIDENING_NOT_PORTABLE);\
812 }
813 for (NODE_T *q = p; q != NO_NODE; FORWARD (q)) {
814 widen_denotation (SUB (q));
815 if (IS (q, WIDENING) && IS (SUB (q), DENOTATION)) {
816 MOID_T *lm = MOID (q), *m = MOID (SUB (q));
817 if (lm == M_LONG_LONG_INT && m == M_LONG_INT) {
818 WARN_WIDENING;
819 WIDEN;
820 }
821 if (lm == M_LONG_INT && m == M_INT) {
822 WARN_WIDENING;
823 WIDEN;
824 }
825 if (lm == M_LONG_LONG_REAL && m == M_LONG_REAL) {
826 WARN_WIDENING;
827 WIDEN;
828 }
829 if (lm == M_LONG_REAL && m == M_REAL) {
830 WARN_WIDENING;
831 WIDEN;
832 }
833 if (lm == M_LONG_REAL && m == M_LONG_INT) {
834 WIDEN;
835 }
836 if (lm == M_REAL && m == M_INT) {
837 WIDEN;
838 }
839 if (lm == M_LONG_LONG_BITS && m == M_LONG_BITS) {
840 WARN_WIDENING;
841 WIDEN;
842 }
843 if (lm == M_LONG_BITS && m == M_BITS) {
844 WARN_WIDENING;
845 WIDEN;
846 }
847 return;
848 }
849 }
850 #undef WIDEN
851 #undef WARN_WIDENING
852 }
853
854 //! @brief Driver for coercion inserions.
855
856 void coercion_inserter (NODE_T * p)
857 {
858 if (IS (p, PARTICULAR_PROGRAM)) {
859 SOID_T q;
860 make_soid (&q, STRONG, M_VOID, 0);
861 coerce_enclosed (SUB (p), &q);
862 }
863 }
864
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|