From b406a81e82f01029c30ece05c609edf31c3c145b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Thu, 28 May 2015 14:53:31 +0200 Subject: [PATCH] Fix for #3337: - Lift type modifiers to the dimensions of the component. --- Compiler/FrontEnd/Expression.mo | 19 ++++++++ Compiler/FrontEnd/InstVar.mo | 78 +++++++++++++++++++++++++++++++++ Compiler/FrontEnd/Types.mo | 16 +++---- Compiler/FrontEnd/ValuesUtil.mo | 10 +++++ 4 files changed, 113 insertions(+), 10 deletions(-) diff --git a/Compiler/FrontEnd/Expression.mo b/Compiler/FrontEnd/Expression.mo index 9be665d2d4f..dfc19613d88 100644 --- a/Compiler/FrontEnd/Expression.mo +++ b/Compiler/FrontEnd/Expression.mo @@ -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 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]. diff --git a/Compiler/FrontEnd/InstVar.mo b/Compiler/FrontEnd/InstVar.mo index 591192c0eae..8b8dbdbb80d 100644 --- a/Compiler/FrontEnd/InstVar.mo +++ b/Compiler/FrontEnd/InstVar.mo @@ -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); @@ -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 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 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 inEqMod; + input list inDims; + output Option 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; diff --git a/Compiler/FrontEnd/Types.mo b/Compiler/FrontEnd/Types.mo index e159f337aaf..ce27dd63570 100644 --- a/Compiler/FrontEnd/Types.mo +++ b/Compiler/FrontEnd/Types.mo @@ -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; @@ -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; diff --git a/Compiler/FrontEnd/ValuesUtil.mo b/Compiler/FrontEnd/ValuesUtil.mo index c322e2088c6..e5893455ba8 100644 --- a/Compiler/FrontEnd/ValuesUtil.mo +++ b/Compiler/FrontEnd/ValuesUtil.mo @@ -2582,5 +2582,15 @@ algorithm end for; end arrayContainsEmpty; +public function liftValueList + input Values.Value inValue; + input list 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;