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 (1201, "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 (1202, "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 (1203, "too many dimensions", NO_TEXT);
99 }
100 }
101 (void) rc;
102 }
103
104 void dimension (void)
105 {
106 int_4 rc = scan (EXPECT_NONE), set = 0;
107 while (rc != END_OF_LINE) {
108 MODE mode;
109 if (rc == WORD) {
110 if (/* reserved (curlex) */ FALSE) {
111 ERROR (1204, "reserved symbol", curlex);
112 }
113 set++;
114 IDENT *idf = void_decl (curlex, &mode);
115 rc = scan ("(");
116 if (idf != NO_IDENT) {
117 if (IS_ROW (idf->mode)) {
118 ERROR (1205, "already dimensioned", C_NAME (idf));
119 }
120 get_dims (idf, 1);
121 CHECKPOINT (1206, ")");
122 rc = scan (EXPECT_NONE);
123 }
124 }
125 if (TOKEN (",")) {
126 rc = scan (EXPECT_NONE);
127 if (! WITHIN) {
128 SYNTAX (1207, NO_TEXT);
129 }
130 } else {
131 if (rc != END_OF_LINE) {
132 SYNTAX (1208, NO_TEXT);
133 rc = scan (EXPECT_NONE);
134 }
135 }
136 }
137 if (set == 0) {
138 SYNTAX (1209, "dimension statement");
139 }
140 }
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|