parser-annotate.c
1 //! @file parser-annotate.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-2025 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 //! Annotate syntax tree.
25
26 #include "a68g.h"
27 #include "a68g-defines.h"
28 #include "a68g-parser.h"
29 #include "a68g-prelude.h"
30
31 // The A68G GC cannot walk the expression stack, which holds no mode info.
32 // En lieu, all units yielding a value with mode that needs colouring
33 // copy the top-of-stack to an anonymous variable in the frame stack.
34 //
35 // TODO: Optimize this code as some tags are placed without need.
36 // For instance, not all REFs point to the heap.
37
38 //! @brief Test whether unit is an identifier (primary).
39
40 BOOL_T identifier_gc (NODE_T *p)
41 {
42 switch (ATTRIBUTE (p))
43 {
44 case UNIT:
45 case TERTIARY:
46 case SECONDARY:
47 case PRIMARY:
48 return identifier_gc (SUB (p));
49 case IDENTIFIER:
50 return TAX (p) != NO_TAG;
51 default:
52 return A68G_FALSE;
53 }
54 }
55
56 //! @brief Annotate syntax tree for GC.
57
58 void annotate_gc_identity_declaration (NODE_T *p)
59 {
60 if (p != NO_NODE) {
61 switch (ATTRIBUTE (p)) {
62 case DECLARER: {
63 annotate_gc (SUB (p));
64 annotate_gc_identity_declaration (NEXT (p));
65 return;
66 }
67 case DEFINING_IDENTIFIER: {
68 // Do not tag the unit, value will already be in the frame stack.
69 annotate_gc (SUB (NEXT_NEXT (p)));
70 return;
71 }
72 }
73 }
74 }
75
76 //! @brief Annotate syntax tree for GC.
77
78 void annotate_gc_variable_declaration (NODE_T * p)
79 {
80 if (p != NO_NODE) {
81 switch (ATTRIBUTE (p)) {
82 case DECLARER: {
83 annotate_gc (SUB (p));
84 annotate_gc_variable_declaration (NEXT (p));
85 return;
86 }
87 case DEFINING_IDENTIFIER: {
88 if (whether (p, DEFINING_IDENTIFIER, ASSIGN_SYMBOL, UNIT, STOP)) {
89 // Do not tag the unit, value will already be in the frame stack.
90 annotate_gc (SUB (NEXT_NEXT (p)));
91 return;
92 }
93 }
94 }
95 }
96 }
97
98 //! @brief Annotate syntax tree for GC.
99
100 void annotate_gc (NODE_T *p)
101 {
102 for (; p != NO_NODE; FORWARD (p)) {
103 if (ATTRIBUTE (p) == UNIT) {
104 MOID_T *m = MOID (p);
105 if (identifier_gc (p)) {
106 /* Value already in the frame stack */;
107 } else if (moid_needs_colouring (m)) {
108 TAG_T *z = add_tag (TABLE (p), ANONYMOUS, p, MOID (p), UNIT);
109 TAX_GC (p) = z;
110 HEAP (z) = LOC_SYMBOL;
111 USE (z) = A68G_TRUE;
112 }
113 annotate_gc (SUB (p));
114 } else if (ATTRIBUTE (p) == IDENTITY_DECLARATION) {
115 annotate_gc_identity_declaration (SUB (p));
116 } else if (ATTRIBUTE (p) == VARIABLE_DECLARATION) {
117 annotate_gc_variable_declaration (SUB (p));
118 } else if (SUB (p) != NO_NODE) {
119 annotate_gc (SUB (p));
120 }
121 }
122 }
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|