• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rjfarmer / gfModParser / 15257689366

26 May 2025 03:38PM UTC coverage: 83.597% (-0.3%) from 83.884%
15257689366

push

github

rjfarmer
Fix case handling

3 of 3 new or added lines in 1 file covered. (100.0%)

34 existing lines in 2 files now uncovered.

688 of 823 relevant lines covered (83.6%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.64
/gfModParser/modules/expressions.py
1
# SPDX-License-Identifier: GPL-2.0+
2

3
import numpy as np
1✔
4

5
from .. import utils
1✔
6

7
from . import procedures
1✔
8

9

10
class Expression:
1✔
11
    def __init__(self, expression, *, version):
1✔
12
        self._expression = expression
1✔
13
        self.version = version
1✔
14
        t = self._expression[0]
1✔
15

16
        map = {
1✔
17
            "OP": ExpOp,
18
            "FUNCTION": ExpFunction,
19
            "CONSTANT": ExpConstant,
20
            "VARIABLE": ExpVariable,
21
            "SUBSTRING": ExpSubString,
22
            "ARRAY": ExpArray,
23
            "NULL": ExpNull,
24
            "COMPCALL": ExpCompCall,
25
            "PPC": ExpPPC,
26
            "UNKNOWN": ExpUnknown,
27
        }
28

29
        self._exp = map[t](
1✔
30
            self.typespec.type,
31
            self.typespec.kind,
32
            self._expression,
33
            version=self.version,
34
        )
35

36
    @property
1✔
37
    def type(self):
1✔
38
        return self._exp
1✔
39

40
    @property
1✔
41
    def typespec(self):
1✔
42
        return typespec(self._expression[1], version=self.version)
1✔
43

44
    @property
1✔
45
    def rank(self):
1✔
46
        return int(self._expression[2])
1✔
47

48
    @property
1✔
49
    def arglist(self):
1✔
UNCOV
50
        if len(self._exp._args) == 7:
×
UNCOV
51
            return procedures.actual_arglist(self._exp._args[6])
×
52

53
    @property
1✔
54
    def value(self):
1✔
55
        return self._exp.value
1✔
56

57
    def __str__(self):
1✔
58
        return self._exp.__str__()
1✔
59

60
    def __repr__(self):
1✔
61
        return self._exp.__repr__()
1✔
62

63
    @property
1✔
64
    def len(self):
1✔
65
        return self._exp.len
1✔
66

67
    @property
1✔
68
    def kind(self):
1✔
69
        return self._exp._kind
1✔
70

71

72
class ExpGeneric:
1✔
73
    def __init__(self, type, kind, args, *, version):
1✔
74
        self._args = args
1✔
75
        self.version = version
1✔
76
        self._type = type
1✔
77
        self._kind = kind
1✔
78

79
    def __str__(self):
1✔
UNCOV
80
        return self._type
×
81

82
    def __repr__(self):
1✔
83
        return self._type
1✔
84

85
    @property
1✔
86
    def value(self):
1✔
UNCOV
87
        return None
×
88

89
    def __eq__(self, key):
1✔
90
        return self._type == key
1✔
91

92
    @property
1✔
93
    def kind(self):
1✔
94
        return self._kind
1✔
95

96

97
class ExpOp(ExpGeneric):
1✔
98

99
    @property
1✔
100
    def unary_op(self):
1✔
UNCOV
101
        return self._args[3]
×
102

103
    @property
1✔
104
    def unary_args(self):
1✔
UNCOV
105
        return Expression(self._args[4], version=self.version), Expression(
×
106
            self._args[5], version=self.version
107
        )
108

109

110
class ExpNotImplemented(ExpGeneric):
1✔
111
    @property
1✔
112
    def value(self):
1✔
113
        raise NotImplementedError
×
114

115

116
class ExpFunction(ExpGeneric):
1✔
117
    @property
1✔
118
    def value(self):
1✔
UNCOV
119
        return self._args[3]
×
120

121
    @property
1✔
122
    def args(self):
1✔
UNCOV
123
        return Expression(self._args[4], version=self.version)
×
124

125

126
class ExpConstant(ExpGeneric):
1✔
127
    @property
1✔
128
    def value(self):
1✔
129
        if self._type == "REAL":
1✔
130
            return utils.hextofloat(utils.string_clean(self._args[3]), self._kind)
1✔
131
        elif self._type == "INTEGER":
1✔
132
            return int(utils.string_clean(self._args[3]))
1✔
133
        elif self._type == "CHARACTER":
1✔
134
            return utils.string_clean(self._args[4])
1✔
135
        elif self._type == "COMPLEX":
1✔
136
            return complex(
1✔
137
                utils.hextofloat(utils.string_clean(self._args[3]), self._kind),
138
                utils.hextofloat(utils.string_clean(self._args[4]), self._kind),
139
            )
140
        elif self._type == "LOGICAL":
1✔
141
            return int(self._args[3]) == 1
1✔
142
        else:
UNCOV
143
            raise NotImplementedError(f"Type={self._type} args3={self._args[3]}")
×
144

145
    @property
1✔
146
    def len(self):
1✔
147
        if self._type == "CHARACTER":
1✔
148
            return int(self._args[3])
1✔
149

150
    def __str__(self):
1✔
151
        if self._type == "CHARACTER":
1✔
152
            return f"CHARACTER(kind={self.kind},len={self.len})"
1✔
153
        else:
154
            return f"{self.type}(kind={self.kind})"
1✔
155

156
    @property
1✔
157
    def type(self):
1✔
158
        return self._type
1✔
159

160

161
class ExpVariable(ExpGeneric):
1✔
162
    @property
1✔
163
    def value(self):
1✔
UNCOV
164
        return self._args[3]
×
165

166
    def __str__(self):
1✔
UNCOV
167
        if self.type == "CHARACTER":
×
UNCOV
168
            return f"CHARACTER(kind={self.kind},len={self.len})"
×
169
        else:
UNCOV
170
            return f"{self.type}"
×
171

172

173
class ExpArray(ExpGeneric):
1✔
174
    def __init__(self, *args, **kwargs):
1✔
175
        super().__init__(*args, **kwargs)
1✔
176
        self._value = None
1✔
177

178
    @property
1✔
179
    def value(self):
1✔
180
        if self._value is None:
1✔
181
            self._value = []
1✔
182
            for i in self._args[3]:
1✔
183
                self._value.append(Expression(i[0], version=self.version))
1✔
184

185
        value = []
1✔
186

187
        for v in self._value:
1✔
188
            value.append(v.value)
1✔
189

190
        return np.array(value, dtype=self.dtype).reshape(self.shape)
1✔
191

192
    @property
1✔
193
    def shape(self):
1✔
194
        return tuple([int(utils.string_clean(i)) for i in self._args[4]])
1✔
195

196
    @property
1✔
197
    def dtype(self):
1✔
198
        v = Expression(self._args[3][0][0], version=self.version)
1✔
199
        return utils.dtype(v.type, self.kind, len=v.len)
1✔
200

201
    def __str__(self):
1✔
202
        v = Expression(self._args[3][0][0], version=self.version)
1✔
203
        if v.type == "CHARACTER":
1✔
204
            return f"CHARACTER(kind={v.kind},len={v.len}),dimension{self.shape}"
1✔
205
        else:
206
            return f"{v.type},dimension{self.shape}"
1✔
207

208

209
class ExpSubString(ExpNotImplemented):
1✔
210
    pass
1✔
211

212

213
class ExpNull(ExpNotImplemented):
1✔
214
    pass
1✔
215

216

217
class ExpCompCall(ExpNotImplemented):
1✔
218
    pass
1✔
219

220

221
class ExpPPC(ExpNotImplemented):
1✔
222
    pass
1✔
223

224

225
class ExpUnknown(ExpNotImplemented):
1✔
226
    pass
1✔
227

228

229
# Need to store this here as we get a cyclic dependency
230
# between expressions and typespec
231
class typespec:
1✔
232
    def __init__(self, typespec, *, version):
1✔
233
        self._typespec = typespec
1✔
234
        self.version = version
1✔
235

236
    @property
1✔
237
    def type(self):
1✔
238
        return self._typespec[0]
1✔
239

240
    def _isclass(self):
1✔
241
        return self.type == "CLASS" or self.type == "DERIVED"
1✔
242

243
    @property
1✔
244
    def kind(self):
1✔
245
        if not self._isclass():
1✔
246
            return int(self._typespec[1])
1✔
247

248
    @property
1✔
249
    def class_ref(self):
1✔
UNCOV
250
        if self._isclass():
×
UNCOV
251
            return int(self._typespec[1])
×
252

253
    @property
1✔
254
    def interface(self):
1✔
UNCOV
255
        return self._typespec[2]
×
256

257
    @property
1✔
258
    def is_c_interop(self):
1✔
259
        return int(self._typespec[3]) == 1
1✔
260

261
    @property
1✔
262
    def is_iso_c(self):
1✔
263
        return int(self._typespec[4]) == 1
1✔
264

265
    @property
1✔
266
    def type2(self):
1✔
267
        # Whats this?
UNCOV
268
        return self._typespec[5]
×
269

270
    @property
1✔
271
    def charlen(self):
1✔
UNCOV
272
        return self._typespec[6]
×
273

274
    #     try:
275
    #         if not args[6][0]:
276
    #             self.charlen = -1
277
    #         else:
278
    #             self.charlen = Expression(
279
    #                 *args[6][0]
280
    #             )  # TODO: might this need to be iterated for mulit-d strings?
281
    #     except IndexError:
282
    #         self.charlen = -1
283

284
    @property
1✔
285
    def deferred_cl(self):
1✔
UNCOV
286
        if len(self._typespec) == 8:
×
UNCOV
287
            return self._typespec[7] == "DEFERRED_CL"
×
288

UNCOV
289
        return False
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc