common.c
1 //! @file common.c
2 //! @author J. Marcel van der Veer
3 //
4 //! @section Copyright
5 //
6 // This file is part of VIF - vintage FORTRAN compiler.
7 // Copyright 2020-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 //! Compile COMMON.
25
26 #include <vif.h>
27
28 void merge_commons (void)
29 {
30 int_4 k, g;
31 for (k = 0; k < nlocals; k++) {
32 IDENT *idf = &locals[k];
33 int_4 found = FALSE;
34 if (NOT_LOCAL (idf) && idf->common != EXTERN) {
35 for (g = 0; g < nglobals && !found; g++) {
36 IDENT *idg = &globals[g];
37 if (idf->common == idg->common && EQUAL (C_NAME (idf), C_NAME (idg))) {
38 int_4 same = TRUE;
39 found = TRUE;
40 same &= (idf->mode.type == idg->mode.type);
41 same &= (idf->mode.len == idg->mode.len);
42 same &= (idf->mode.dim == idg->mode.dim);
43 if (same) {
44 int_4 n;
45 for (n = 0; n < idf->mode.dim; n++) {
46 same &= (EQUAL (idf->lwb[n], idg->lwb[n]));
47 same &= (EQUAL (idf->upb[n], idg->upb[n]));
48 }
49 }
50 if (!same) {
51 NEW_RECORD (where);
52 _srecordf (where, "%s in block %s", FTN_NAME (idg), commons[idg->common]);
53 ERROR (701, "common block consistency", where);
54 }
55 }
56 }
57 if (!found) {
58 if (nglobals >= MAX_IDENTS) {
59 ERROR (702, "too many common identifiers", NO_TEXT);
60 return;
61 }
62 // Copy-paste into global name space.
63 IDENT *idn = &globals[nglobals++];
64 memcpy (idn, idf, sizeof (IDENT));
65 }
66 }
67 }
68 }
69
70 void common (void)
71 {
72 int_4 cblck = LOCAL, rc;
73 rc = scan (EXPECT_NONE);
74 if (!TOKEN ("/")) {
75 cblck = add_block ("_common");
76 }
77 while (WITHIN) {
78 if (TOKEN (",")) {
79 rc = scan (EXPECT_NONE);
80 if (!WITHIN) {
81 SYNTAX (703, "common block");
82 }
83 } else if (TOKEN ("/")) {
84 rc = scan (EXPECT_NONE);
85 if (rc != WORD) {
86 SYNTAX (704, "common block name");
87 } else {
88 cblck = add_block (curlex);
89 }
90 rc = scan ("/");
91 rc = scan (EXPECT_NONE);
92 } else if (rc == WORD) {
93 if (reserved (curlex)) {
94 ERROR (705, "reserved symbol", curlex);
95 }
96 MODE mode;
97 IDENT *idf = void_decl (curlex, &mode);
98 if (idf != NO_IDENT) {
99 idf->common = cblck;
100 }
101 rc = scan (EXPECT_NONE);
102 if (TOKEN ("(") && idf != NO_IDENT) {
103 if (IS_ROW (idf->mode)) {
104 ERROR (706, "already dimensioned", FTN_NAME (idf));
105 }
106 get_dims (idf, 1);
107 rc = scan (EXPECT_NONE);
108 }
109 } else {
110 SYNTAX (707, "common block");
111 rc = scan (EXPECT_NONE);
112 }
113 }
114 }
115
116 void get_common (void)
117 {
118 int_4 go_on = TRUE;
119 while (go_on) {
120 SAVE_POS;
121 int_4 rc = scan (EXPECT_NONE);
122 if (rc == DECLAR) {
123 skip_card (FALSE);
124 } else if (TOKEN ("implicit")) {
125 skip_card (FALSE);
126 } else if (TOKEN ("save")) {
127 skip_card (FALSE);
128 } else if (TOKEN ("automatic")) {
129 skip_card (FALSE);
130 } else if (TOKEN ("parameter")) {
131 skip_card (FALSE);
132 } else if (TOKEN ("common")) {
133 common ();
134 skip_card (FALSE);
135 } else if (TOKEN ("dimension")) {
136 skip_card (FALSE);
137 } else if (TOKEN ("equivalence")) {
138 skip_card (FALSE);
139 } else if (TOKEN ("external")) {
140 skip_card (FALSE);
141 } else if (TOKEN ("intrinsic")) {
142 skip_card (FALSE);
143 } else if (TOKEN ("data")) {
144 skip_card (FALSE);
145 } else if (rc == WORD && is_macro_decl (curlex)) {
146 skip_card (FALSE);
147 } else if (strlen (curlex) > 0) {
148 // Backspace and done.
149 RESTORE_POS;
150 go_on = FALSE;
151 }
152 }
153 }
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|