Skip to content

Commit

Permalink
Fix for #3337:
Browse files Browse the repository at this point in the history
- Lift type modifiers to the dimensions of the component.
  • Loading branch information
perost committed May 28, 2015
1 parent b7387b3 commit b406a81
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 10 deletions.
19 changes: 19 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -1116,6 +1116,25 @@ algorithm
end match;
end unliftExp;

public function liftExp
input DAE.Exp inExp;
input DAE.Dimension inDimension;
output DAE.Exp outExp;
algorithm
outExp := DAE.ARRAY(Types.liftArray(typeof(inExp), inDimension),
false, List.fill(inExp, dimensionSize(inDimension)));
end liftExp;

public function liftExpList
input DAE.Exp inExp;
input list<DAE.Dimension> inDimensions;
output DAE.Exp outExp = inExp;
algorithm
for dim in listReverse(inDimensions) loop
outExp := liftExp(outExp, dim);
end for;
end liftExpList;

public function liftArrayRight "
This function adds an array dimension to a type on the right side, i.e.
liftArrayRigth(Real[2,3],SOME(4)) => Real[2,3,4].
Expand Down
78 changes: 78 additions & 0 deletions Compiler/FrontEnd/InstVar.mo
Expand Up @@ -590,6 +590,7 @@ algorithm
attr := inAttributes;
else
// Userdefined array type, e.g. type Point = Real[3].
type_mods := liftUserTypeMod(type_mods, inDimensions);
dims := listAppend(inDimensions, dims);
mod := Mod.merge(inMod, type_mods, inEnv, inPrefix);
attr := InstUtil.propagateClassPrefix(inAttributes, inPrefix);
Expand All @@ -615,6 +616,83 @@ algorithm
end try;
end instVar_dispatch;

protected function liftUserTypeMod
"This function adds dimensions to a modifier. This is a bit of a hack to make
modifiers on user-defined types behave as expected, e.g.:

type T = Real[3](start = {1, 2, 3});
T x[2]; // Modifier from T must be lifted to become [2, 3].
"
input DAE.Mod inMod;
input list<DAE.Dimension> inDims;
output DAE.Mod outMod = inMod;
algorithm
if listEmpty(inDims) then
return;
end if;

outMod := matchcontinue outMod
case DAE.MOD()
algorithm
// Only lift modifiers without 'each'.
if not SCode.eachBool(outMod.eachPrefix) then
outMod.eqModOption := liftUserTypeEqMod(outMod.eqModOption, inDims);
outMod.subModLst := list(liftUserTypeSubMod(s, inDims) for s in outMod.subModLst);
end if;
then
outMod;

else outMod;
end matchcontinue;
end liftUserTypeMod;

protected function liftUserTypeSubMod
input DAE.SubMod inSubMod;
input list<DAE.Dimension> inDims;
output DAE.SubMod outSubMod = inSubMod;
algorithm
outSubMod := match outSubMod
case DAE.NAMEMOD()
algorithm
outSubMod.mod := liftUserTypeMod(outSubMod.mod, inDims);
then
outSubMod;
end match;
end liftUserTypeSubMod;

protected function liftUserTypeEqMod
input Option<DAE.EqMod> inEqMod;
input list<DAE.Dimension> inDims;
output Option<DAE.EqMod> outEqMod;
protected
DAE.EqMod eq;
DAE.Type ty;
algorithm
if isNone(inEqMod) then
outEqMod := inEqMod;
return;
end if;

SOME(eq) := inEqMod;

eq := match eq
case DAE.TYPED()
algorithm
eq.modifierAsExp := Expression.liftExpList(eq.modifierAsExp, inDims);
eq.modifierAsValue := Util.applyOption1(eq.modifierAsValue,
ValuesUtil.liftValueList, inDims);
ty := Types.getPropType(eq.properties);
eq.properties := Types.setPropType(eq.properties,
Types.liftArrayListDims(ty, inDims));
then
eq;

else eq;
end match;

outEqMod := SOME(eq);
end liftUserTypeEqMod;

protected function addArrayVarEquation
input FCore.Cache inCache;
input FCore.Graph inEnv;
Expand Down
16 changes: 6 additions & 10 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -3786,10 +3786,9 @@ public function getPropType "author: LS
input DAE.Properties inProperties;
output DAE.Type outType;
algorithm
outType := match (inProperties)
local Type ty;
case DAE.PROP(type_ = ty) then ty;
case DAE.PROP_TUPLE(type_ = ty) then ty;
outType := match inProperties
case DAE.PROP() then inProperties.type_;
case DAE.PROP_TUPLE() then inProperties.type_;
end match;
end getPropType;

Expand All @@ -3798,12 +3797,9 @@ public function setPropType "Set the Type from Properties."
input DAE.Type ty;
output DAE.Properties outProperties;
algorithm
outProperties := match (inProperties,ty)
local
DAE.Const constFlag;
DAE.TupleConst tupleConst;
case (DAE.PROP(constFlag = constFlag),_) then DAE.PROP(ty,constFlag);
case (DAE.PROP_TUPLE(tupleConst = tupleConst),_) then DAE.PROP_TUPLE(ty,tupleConst);
outProperties := match inProperties
case DAE.PROP() then DAE.PROP(ty, inProperties.constFlag);
case DAE.PROP_TUPLE() then DAE.PROP_TUPLE(ty, inProperties.tupleConst);
end match;
end setPropType;

Expand Down
10 changes: 10 additions & 0 deletions Compiler/FrontEnd/ValuesUtil.mo
Expand Up @@ -2582,5 +2582,15 @@ algorithm
end for;
end arrayContainsEmpty;

public function liftValueList
input Values.Value inValue;
input list<DAE.Dimension> inDimensions;
output Values.Value outValue = inValue;
algorithm
for dim in listReverse(inDimensions) loop
outValue := makeArray(List.fill(outValue, Expression.dimensionSize(dim)));
end for;
end liftValueList;

annotation(__OpenModelica_Interface="frontend");
end ValuesUtil;

0 comments on commit b406a81

Please sign in to comment.