|
|
1 //! @file genie-declaration.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-2026 J. Marcel van der Veer [algol68g@algol68genie.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 declarations. 25 26 #include "a68g.h" 27 #include "a68g-genie.h" 28 #include "a68g-frames.h" 29 #include "a68g-prelude.h" 30 31 //! @brief Execute identity declaration. 32 33 void genie_identity_dec (NODE_T * p) 34 { 35 for (; p != NO_NODE; FORWARD (p)) { 36 if (ISNT (p, DEFINING_IDENTIFIER)) { 37 genie_identity_dec (SUB (p)); 38 } else { 39 A68G_REF loc; 40 NODE_T *src = NEXT_NEXT (p); 41 MOID_T *src_mode = MOID (p); 42 size_t size = SIZE (src_mode); 43 BYTE_T *tos = STACK_TOP; 44 ADDR_T pop_sp = A68G_SP; 45 ADDR_T pop_dns = FRAME_DNS (A68G_FP); 46 FRAME_DNS (A68G_FP) = A68G_FP; 47 GENIE_UNIT_TRACE (src); 48 genie_check_initialisation (src, tos, src_mode); 49 STACK_DNS (src, src_mode, A68G_FP); 50 FRAME_DNS (A68G_FP) = pop_dns; 51 // Make a temporary REF to the object in the frame. 52 STATUS (&loc) = (STATUS_MASK_T) (INIT_MASK | IN_FRAME_MASK); 53 REF_HANDLE (&loc) = (A68G_HANDLE *) & nil_handle; 54 OFFSET (&loc) = A68G_FP + FRAME_INFO_SIZE + OFFSET (TAX (p)); 55 REF_SCOPE (&loc) = A68G_FP; 56 ABEND (ADDRESS (&loc) != FRAME_OBJECT (OFFSET (TAX (p))), ERROR_INTERNAL_CONSISTENCY, NO_TEXT); 57 // Initialise the tag, value is in the stack. 58 if (HAS_ROWS (src_mode)) { 59 A68G_SP = pop_sp; 60 genie_clone_stack (p, src_mode, &loc, (A68G_REF *) & nil_ref); 61 } else if (UNIT (&GPROP (src)) == genie_constant) { 62 STATUS_SET (TAX (p), CONSTANT_MASK); 63 POP_ALIGNED (p, ADDRESS (&loc), size); 64 } else { 65 POP_ALIGNED (p, ADDRESS (&loc), size); 66 } 67 return; 68 } 69 } 70 } 71 72 //! @brief Execute variable declaration. 73 74 void genie_variable_dec (NODE_T * p, NODE_T ** declarer, ADDR_T sp) 75 { 76 for (; p != NO_NODE; FORWARD (p)) { 77 if (IS (p, VARIABLE_DECLARATION)) { 78 genie_variable_dec (SUB (p), declarer, sp); 79 } else { 80 if (IS (p, DECLARER)) { 81 (*declarer) = SUB (p); 82 genie_generator_bounds (*declarer); 83 FORWARD (p); 84 } 85 if (IS (p, DEFINING_IDENTIFIER)) { 86 MOID_T *ref_mode = MOID (p); 87 TAG_T *tag = TAX (p); 88 LEAP_T leap = (HEAP (tag) == LOC_SYMBOL ? LOC_SYMBOL : HEAP_SYMBOL); 89 A68G_REF *z; 90 MOID_T *src_mode = SUB_MOID (p); 91 z = (A68G_REF *) (FRAME_OBJECT (OFFSET (TAX (p)))); 92 genie_generator_internal (*declarer, ref_mode, BODY (tag), leap, sp); 93 POP_REF (p, z); 94 if (NEXT (p) != NO_NODE && IS (NEXT (p), ASSIGN_SYMBOL)) { 95 NODE_T *src = NEXT_NEXT (p); 96 ADDR_T pop_sp = A68G_SP; 97 ADDR_T pop_dns = FRAME_DNS (A68G_FP); 98 FRAME_DNS (A68G_FP) = A68G_FP; 99 GENIE_UNIT_TRACE (src); 100 STACK_DNS (src, src_mode, A68G_FP); 101 FRAME_DNS (A68G_FP) = pop_dns; 102 A68G_SP = pop_sp; 103 if (HAS_ROWS (src_mode)) { 104 genie_clone_stack (p, src_mode, z, z); 105 } else { 106 MOVE (ADDRESS (z), STACK_TOP, (unt) SIZE (src_mode)); 107 } 108 } 109 } 110 } 111 } 112 } 113 114 //! @brief Execute PROC variable declaration. 115 116 void genie_proc_variable_dec (NODE_T * p) 117 { 118 for (; p != NO_NODE; FORWARD (p)) { 119 switch (ATTRIBUTE (p)) { 120 case DEFINING_IDENTIFIER: { 121 ADDR_T sp_for_voiding = A68G_SP; 122 MOID_T *ref_mode = MOID (p); 123 TAG_T *tag = TAX (p); 124 LEAP_T leap = (HEAP (tag) == LOC_SYMBOL ? LOC_SYMBOL : HEAP_SYMBOL); 125 A68G_REF *z = (A68G_REF *) (FRAME_OBJECT (OFFSET (TAX (p)))); 126 genie_generator_internal (p, ref_mode, BODY (tag), leap, A68G_SP); 127 POP_REF (p, z); 128 if (NEXT (p) != NO_NODE && IS (NEXT (p), ASSIGN_SYMBOL)) { 129 MOID_T *src_mode = SUB_MOID (p); 130 ADDR_T pop_sp = A68G_SP; 131 ADDR_T pop_dns = FRAME_DNS (A68G_FP); 132 FRAME_DNS (A68G_FP) = A68G_FP; 133 GENIE_UNIT_TRACE (NEXT_NEXT (p)); 134 STACK_DNS (p, SUB (ref_mode), A68G_FP); 135 FRAME_DNS (A68G_FP) = pop_dns; 136 A68G_SP = pop_sp; 137 MOVE (ADDRESS (z), STACK_TOP, (unt) SIZE (src_mode)); 138 } 139 A68G_SP = sp_for_voiding; // Voiding 140 return; 141 } 142 default: { 143 genie_proc_variable_dec (SUB (p)); 144 break; 145 } 146 } 147 } 148 } 149 150 //! @brief Execute operator declaration. 151 152 void genie_operator_dec (NODE_T * p) 153 { 154 for (; p != NO_NODE; FORWARD (p)) { 155 switch (ATTRIBUTE (p)) { 156 case DEFINING_OPERATOR: { 157 A68G_PROCEDURE *z = (A68G_PROCEDURE *) (FRAME_OBJECT (OFFSET (TAX (p)))); 158 ADDR_T pop_dns = FRAME_DNS (A68G_FP); 159 FRAME_DNS (A68G_FP) = A68G_FP; 160 GENIE_UNIT_TRACE (NEXT_NEXT (p)); 161 STACK_DNS (p, MOID (p), A68G_FP); 162 FRAME_DNS (A68G_FP) = pop_dns; 163 POP_PROCEDURE (p, z); 164 return; 165 } 166 default: { 167 genie_operator_dec (SUB (p)); 168 break; 169 } 170 } 171 } 172 } 173 174 //! @brief Execute declaration. 175 176 void genie_declaration (NODE_T * p) 177 { 178 for (; p != NO_NODE; FORWARD (p)) { 179 switch (ATTRIBUTE (p)) { 180 case MODE_DECLARATION: 181 case PROCEDURE_DECLARATION: 182 case BRIEF_OPERATOR_DECLARATION: 183 case PRIORITY_DECLARATION: { 184 // Already resolved. 185 return; 186 } 187 case IDENTITY_DECLARATION: { 188 genie_identity_dec (SUB (p)); 189 break; 190 } 191 case OPERATOR_DECLARATION: { 192 genie_operator_dec (SUB (p)); 193 break; 194 } 195 case VARIABLE_DECLARATION: { 196 NODE_T *declarer = NO_NODE; 197 ADDR_T pop_sp = A68G_SP; 198 genie_variable_dec (SUB (p), &declarer, A68G_SP); 199 // Voiding to remove garbage from declarers. 200 A68G_SP = pop_sp; 201 break; 202 } 203 case PROCEDURE_VARIABLE_DECLARATION: { 204 ADDR_T pop_sp = A68G_SP; 205 genie_proc_variable_dec (SUB (p)); 206 A68G_SP = pop_sp; 207 break; 208 } 209 default: { 210 genie_declaration (SUB (p)); 211 break; 212 } 213 } 214 } 215 }
© 2001-2026 J.M. van der Veer
jmvdveer@algol68genie.nl