dimension.c
1 //! @file dimension.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 DIMENSION.
25
26 #include <vif.h>
27
28 void get_dims (IDENT * idf, int_4 dim)
29 {
30 EXPR reg;
31 NEW_RECORD (str);
32 int_4 rc;
33 memset (®, 0, sizeof (EXPR));
34 rc = scan (EXPECT_NONE);
35 if (TOKEN ("*")) {
36 idf->lwb[idf->mode.dim] = f_stralloc ("1");
37 idf->upb[idf->mode.dim] = f_stralloc ("0");
38 idf->len[idf->mode.dim++] = f_stralloc ("VARY");
39 rc = scan (EXPECT_NONE);
40 } else {
41 express (®, INTEGER, 4);
42 if (reg.variant != EXPR_CONST) {
43 if (reg.variant == EXPR_VAR && reg.idf->arg == ARG) {
44 ;
45 } else if (reg.variant == EXPR_VAR && reg.idf->common > 0) {
46 ;
47 } else if (reg.variant == EXPR_VAR) {
48 ERROR (1101, "must be common or parameter", FTN_NAME (reg.idf));
49 }
50 idf->variable = TRUE;
51 idf->mode.save = AUTOMATIC;
52 }
53 rc = scan (EXPECT_NONE);
54 int varying = FALSE;
55 if (TOKEN (":")) {
56 idf->lwb[idf->mode.dim] = f_stralloc (reg.str);
57 rc = scan (EXPECT_NONE);
58 if (TOKEN ("*")) {
59 // (lwb : *)
60 idf->upb[idf->mode.dim] = f_stralloc ("0");
61 idf->len[idf->mode.dim++] = f_stralloc ("VARY");
62 varying = TRUE;
63 } else {
64 express (®, INTEGER, 4);
65 if (reg.variant != EXPR_CONST) {
66 if (reg.variant == EXPR_VAR && reg.idf->arg == ARG) {
67 ;
68 } else if (reg.variant == EXPR_VAR && reg.idf->common > 0) {
69 ;
70 } else if (reg.variant == EXPR_VAR) {
71 ERROR (1102, "must be common or parameter", FTN_NAME (reg.idf));
72 }
73 idf->variable = TRUE;
74 idf->mode.save = AUTOMATIC;
75 }
76 idf->upb[idf->mode.dim] = f_stralloc (reg.str);
77 }
78 rc = scan (EXPECT_NONE);
79 } else {
80 idf->lwb[idf->mode.dim] = f_stralloc ("1");
81 idf->upb[idf->mode.dim] = f_stralloc (reg.str);
82 }
83 if (! varying) {
84 NEW_RECORD (buf);
85 if (strcmp (idf->lwb[idf->mode.dim], "1") == 0) {
86 _srecordf (str, "%s", idf->upb[idf->mode.dim]);
87 } else {
88 _srecordf (str, "%s - %s + 1", idf->upb[idf->mode.dim], idf->lwb[idf->mode.dim]);
89 }
90 fold_int_4 (buf, str);
91 idf->len[idf->mode.dim++] = f_stralloc (buf);
92 }
93 }
94 if (TOKEN (",")) {
95 if (dim < MAX_DIMS) {
96 get_dims (idf, dim + 1);
97 } else {
98 ERROR (1103, "too many dimensions", NO_TEXT);
99 }
100 }
101 (void) rc;
102 }
103
104 void dimension (void)
105 {
106 int_4 rc = scan (EXPECT_NONE);
107 while (rc != END_OF_LINE) {
108 MODE mode;
109 if (rc == WORD) {
110 if (reserved (curlex)) {
111 ERROR (1104, "reserved symbol", curlex);
112 }
113 IDENT *idf = void_decl (curlex, &mode);
114 rc = scan ("(");
115 if (idf != NO_IDENT) {
116 if (IS_ROW (idf->mode)) {
117 ERROR (1105, "already dimensioned", C_NAME (idf));
118 }
119 get_dims (idf, 1);
120 CHECKPOINT (1106, ")");
121 rc = scan (EXPECT_NONE);
122 }
123 }
124 if (TOKEN (",")) {
125 rc = scan (EXPECT_NONE);
126 if (! WITHIN) {
127 SYNTAX (1107, NO_TEXT);
128 }
129 } else {
130 if (rc != END_OF_LINE) {
131 SYNTAX (1108, NO_TEXT);
132 rc = scan (EXPECT_NONE);
133 }
134 }
135 }
136 }
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|