genie-assign.c
1 //! @file genie-assign.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 assignations.
25
26 #include "a68g.h"
27 #include "a68g-genie.h"
28 #include "a68g-frames.h"
29 #include "a68g-prelude.h"
30
31 //! @brief Assign a value to a name and voiden.
32
33 PROP_T genie_voiding_assignation_constant (NODE_T * p)
34 {
35 NODE_T *dst = SUB (p);
36 NODE_T *src = SOURCE (&PROP (GINFO (NEXT_NEXT (dst))));
37 ADDR_T pop_sp = A68_SP;
38 A68_REF *z = (A68_REF *) STACK_TOP;
39 PROP_T self;
40 UNIT (&self) = genie_voiding_assignation_constant;
41 SOURCE (&self) = p;
42 GENIE_UNIT (dst);
43 CHECK_REF (p, *z, MOID (p));
44 COPY (ADDRESS (z), CONSTANT (GINFO (src)), SIZE (GINFO (src)));
45 A68_SP = pop_sp;
46 return self;
47 }
48
49 //! @brief Assign a value to a name and voiden.
50
51 PROP_T genie_voiding_assignation (NODE_T * p)
52 {
53 NODE_T *dst = SUB (p);
54 NODE_T *src = NEXT_NEXT (dst);
55 MOID_T *src_mode = SUB_MOID (dst);
56 ADDR_T pop_sp = A68_SP, pop_fp = FRAME_DNS (A68_FP);
57 A68_REF z;
58 PROP_T self;
59 UNIT (&self) = genie_voiding_assignation;
60 SOURCE (&self) = p;
61 GENIE_UNIT (dst);
62 POP_OBJECT (p, &z, A68_REF);
63 CHECK_REF (p, z, MOID (p));
64 FRAME_DNS (A68_FP) = REF_SCOPE (&z);
65 GENIE_UNIT (src);
66 STACK_DNS (src, src_mode, REF_SCOPE (&z));
67 FRAME_DNS (A68_FP) = pop_fp;
68 A68_SP = pop_sp;
69 if (HAS_ROWS (src_mode)) {
70 genie_clone_stack (p, src_mode, &z, &z);
71 } else {
72 COPY_ALIGNED (ADDRESS (&z), STACK_TOP, SIZE (src_mode));
73 }
74 return self;
75 }
76
77 //! @brief Assign a value to a name and push the name.
78
79 PROP_T genie_assignation_constant (NODE_T * p)
80 {
81 NODE_T *dst = SUB (p);
82 NODE_T *src = SOURCE (&PROP (GINFO (NEXT_NEXT (dst))));
83 A68_REF *z = (A68_REF *) STACK_TOP;
84 PROP_T self;
85 UNIT (&self) = genie_assignation_constant;
86 SOURCE (&self) = p;
87 GENIE_UNIT (dst);
88 CHECK_REF (p, *z, MOID (p));
89 COPY (ADDRESS (z), CONSTANT (GINFO (src)), SIZE (GINFO (src)));
90 return self;
91 }
92
93 //! @brief Assign a value to a name and push the name.
94
95 PROP_T genie_assignation_quick (NODE_T * p)
96 {
97 NODE_T *dst = SUB (p);
98 NODE_T *src = NEXT_NEXT (dst);
99 MOID_T *src_mode = SUB_MOID (dst);
100 int size = SIZE (src_mode);
101 ADDR_T pop_fp = FRAME_DNS (A68_FP);
102 A68_REF *z = (A68_REF *) STACK_TOP;
103 GENIE_UNIT (dst);
104 CHECK_REF (p, *z, MOID (p));
105 FRAME_DNS (A68_FP) = REF_SCOPE (z);
106 GENIE_UNIT (src);
107 STACK_DNS (src, src_mode, REF_SCOPE (z));
108 FRAME_DNS (A68_FP) = pop_fp;
109 DECREMENT_STACK_POINTER (p, size);
110 if (HAS_ROWS (src_mode)) {
111 genie_clone_stack (p, src_mode, z, z);
112 } else {
113 COPY (ADDRESS (z), STACK_TOP, size);
114 }
115 PROP_T self;
116 UNIT (&self) = genie_assignation_quick;
117 SOURCE (&self) = p;
118 return self;
119 }
120
121 //! @brief Assign a value to a name and push the name.
122
123 PROP_T genie_assignation (NODE_T * p)
124 {
125 PROP_T self, srp;
126 NODE_T *dst = SUB (p);
127 NODE_T *src = NEXT_NEXT (dst);
128 MOID_T *src_mode = SUB_MOID (dst);
129 int size = SIZE (src_mode);
130 ADDR_T pop_fp = FRAME_DNS (A68_FP);
131 A68_REF *z = (A68_REF *) STACK_TOP;
132 GENIE_UNIT (dst);
133 CHECK_REF (p, *z, MOID (p));
134 FRAME_DNS (A68_FP) = REF_SCOPE (z);
135 GENIE_UNIT_2 (src, srp);
136 STACK_DNS (src, src_mode, REF_SCOPE (z));
137 FRAME_DNS (A68_FP) = pop_fp;
138 DECREMENT_STACK_POINTER (p, size);
139 if (HAS_ROWS (src_mode)) {
140 genie_clone_stack (p, src_mode, z, z);
141 UNIT (&self) = genie_assignation;
142 } else {
143 COPY (ADDRESS (z), STACK_TOP, size);
144 if (UNIT (&srp) == genie_constant) {
145 UNIT (&self) = genie_assignation_constant;
146 } else {
147 UNIT (&self) = genie_assignation_quick;
148 }
149 }
150 SOURCE (&self) = p;
151 return self;
152 }
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|