Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 0861aa3

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Fix Typing.typeCrefDim.
- Rewrite Typing.typeCrefDim so that it handles qualified crefs correctly and with less magic. Belonging to [master]: - #2882
1 parent ea40561 commit 0861aa3

File tree

1 file changed

+63
-53
lines changed

1 file changed

+63
-53
lines changed

Compiler/NFFrontEnd/NFTyping.mo

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,68 +1243,78 @@ function typeCrefDim
12431243
input SourceInfo info;
12441244
output Dimension dim;
12451245
output TypingError error;
1246+
protected
1247+
list<ComponentRef> crl;
1248+
list<Subscript> subs;
1249+
Integer index, dim_count, dim_total = 0;
1250+
InstNode node;
1251+
Component c;
1252+
Type ty;
12461253
algorithm
1247-
(dim, error) := match cref
1248-
case ComponentRef.CREF(node = InstNode.COMPONENT_NODE())
1249-
then typeComponentDim(cref.node, dimIndex, listLength(cref.subscripts), origin, info);
1254+
// TODO: If the cref has subscripts it becomes trickier to correctly calculate
1255+
// the dimension. For now we take the easy way out and just type the
1256+
// whole cref, but doing so might introduce unnecessary cycles.
1257+
if ComponentRef.hasSubscripts(cref) then
1258+
(_, ty) := typeCref(cref, origin, info);
1259+
(dim, error) := nthDimensionBoundsChecked(ty, dimIndex);
1260+
return;
1261+
end if;
12501262

1251-
else
1252-
algorithm
1253-
Error.assertion(false, getInstanceName() + " got invalid cref.", sourceInfo());
1254-
then
1255-
fail();
1263+
// Loop through the cref in reverse, reducing the index by the number of
1264+
// dimensions each component has until we find a component that the index is
1265+
// valid for. This is done even if the index is 0 or negative, since the loop
1266+
// also sums up the total number of dimensions which is needed to give a good
1267+
// error message.
1268+
crl := ComponentRef.toListReverse(cref);
1269+
index := dimIndex;
1270+
1271+
for cr in crl loop
1272+
() := match cr
1273+
case ComponentRef.CREF(node = InstNode.COMPONENT_NODE(), subscripts = subs)
1274+
algorithm
1275+
node := InstNode.resolveOuter(cr.node);
1276+
c := InstNode.component(node);
12561277

1257-
end match;
1258-
end typeCrefDim;
1278+
dim_count := match c
1279+
case Component.UNTYPED_COMPONENT()
1280+
algorithm
1281+
dim_count := arrayLength(c.dimensions);
12591282

1260-
function typeComponentDim
1261-
input InstNode component;
1262-
input Integer dimIndex;
1263-
input Integer offset "The number of dimensions to skip due to subscripts.";
1264-
input ExpOrigin.Type origin;
1265-
input SourceInfo info;
1266-
output Dimension dim;
1267-
output TypingError error;
1268-
protected
1269-
InstNode node = InstNode.resolveOuter(component);
1270-
Component c = InstNode.component(node);
1271-
algorithm
1272-
(dim, error) := match c
1273-
local
1274-
Dimension d;
1275-
Type ty;
1276-
Integer index, dim_count;
1283+
if index <= dim_count and index > 0 then
1284+
error := TypingError.NO_ERROR();
1285+
dim := typeDimension(c.dimensions, index, node, c.binding, origin, c.info);
1286+
return;
1287+
end if;
1288+
then
1289+
dim_count;
12771290

1278-
// An untyped component, get the requested dimension from the component and type it.
1279-
case Component.UNTYPED_COMPONENT()
1280-
algorithm
1281-
index := dimIndex + offset;
1282-
dim_count := arrayLength(c.dimensions);
1291+
case Component.TYPED_COMPONENT()
1292+
algorithm
1293+
dim_count := Type.dimensionCount(c.ty);
12831294

1284-
if index < 1 then
1285-
error := TypingError.OUT_OF_BOUNDS(max(dim_count - offset, 0));
1286-
d := Dimension.UNKNOWN();
1287-
elseif index > dim_count then
1288-
node := InstNode.parent(node);
1295+
if index <= dim_count and index > 0 then
1296+
error := TypingError.NO_ERROR();
1297+
dim := Type.nthDimension(c.ty, index);
1298+
return;
1299+
end if;
1300+
then
1301+
dim_count;
12891302

1290-
if InstNode.isComponent(node) then
1291-
(d, error) := typeComponentDim(node, dimIndex - dim_count, offset - dim_count, origin, info);
1292-
else
1293-
error := TypingError.OUT_OF_BOUNDS(max(dim_count - offset, 0));
1294-
d := Dimension.UNKNOWN();
1295-
end if;
1296-
else
1297-
error := TypingError.NO_ERROR();
1298-
d := typeDimension(c.dimensions, index, node, c.binding, origin, c.info);
1299-
end if;
1300-
then
1301-
(d, error);
1303+
else 0;
1304+
end match;
1305+
1306+
index := index - dim_count;
1307+
dim_total := dim_total + dim_count;
1308+
then
1309+
();
13021310

1303-
// A typed component, get the requested dimension from its type.
1304-
else nthDimensionBoundsChecked(Component.getType(c), dimIndex, offset);
1311+
else ();
1312+
end match;
1313+
end for;
13051314

1306-
end match;
1307-
end typeComponentDim;
1315+
dim := Dimension.UNKNOWN();
1316+
error := TypingError.OUT_OF_BOUNDS(dim_total);
1317+
end typeCrefDim;
13081318

13091319
function nthDimensionBoundsChecked
13101320
"Returns the requested dimension from the given type, along with a TypingError

0 commit comments

Comments
 (0)