diff --git a/Compiler/NFFrontEnd/NFCall.mo b/Compiler/NFFrontEnd/NFCall.mo index b6638210ff9..623354412fa 100644 --- a/Compiler/NFFrontEnd/NFCall.mo +++ b/Compiler/NFFrontEnd/NFCall.mo @@ -1064,7 +1064,7 @@ uniontype Call dims := Type.arrayDims(resTy); resTyToMatch := Type.ARRAY(Type.arrayElementType(resTy), List.set(dims, n, Dimension.UNKNOWN())); dims := list(listGet(lst, n) for lst in dimsLst); - sumDim := Dimension.INTEGER(0); + sumDim := Dimension.fromInteger(0); for d in dims loop // Create the concatenated dimension sumDim := Dimension.add(sumDim, d); @@ -2019,7 +2019,7 @@ protected dim_size := 1; end if; - ty := Type.ARRAY(Type.arrayElementType(ty), {Dimension.INTEGER(dim_size)}); + ty := Type.ARRAY(Type.arrayElementType(ty), {Dimension.fromInteger(dim_size)}); {fn} := typeCachedFunctions(fn_ref); callExp := Expression.CALL(makeBuiltinCall2(fn, {arg}, ty, variability)); end typeVectorCall; @@ -2058,8 +2058,8 @@ protected dims := Type.arrayDims(ty); dims := match listLength(dims) - case 0 then {Dimension.INTEGER(1), Dimension.INTEGER(1)}; - case 1 then {listHead(dims), Dimension.INTEGER(1)}; + case 0 then {Dimension.fromInteger(1), Dimension.fromInteger(1)}; + case 1 then {listHead(dims), Dimension.fromInteger(1)}; case 2 then dims; else algorithm diff --git a/Compiler/NFFrontEnd/NFCeval.mo b/Compiler/NFFrontEnd/NFCeval.mo index 51262f809b5..88dbfcb3d1a 100644 --- a/Compiler/NFFrontEnd/NFCeval.mo +++ b/Compiler/NFFrontEnd/NFCeval.mo @@ -44,6 +44,7 @@ import Dimension = NFDimension; import Type = NFType; import NFTyping.ExpOrigin; import ExpressionSimplify; +import NFPrefixes.Variability; protected import NFFunction.Function; @@ -177,8 +178,9 @@ algorithm case Expression.SIZE() algorithm expl := list(Expression.INTEGER(Dimension.size(d)) for d in Type.arrayDims(Expression.typeOf(exp.exp))); + dim := Dimension.INTEGER(listLength(expl), Variability.PARAMETER); then - Expression.ARRAY(Type.ARRAY(Type.INTEGER(), {Dimension.INTEGER(listLength(expl))}), expl); + Expression.ARRAY(Type.ARRAY(Type.INTEGER(), {dim}), expl); case Expression.BINARY() algorithm @@ -486,7 +488,7 @@ protected Type ty; algorithm ty := Expression.typeOf(listHead(args)); - ty := Type.liftArrayLeft(ty, Dimension.INTEGER(listLength(args))); + ty := Type.liftArrayLeft(ty, Dimension.fromInteger(listLength(args))); result := Expression.ARRAY(ty, args); end evalBuiltinArray; @@ -560,7 +562,7 @@ algorithm fail(); end if; (es,dims) := ExpressionSimplify.evalCat(n, args, getArrayContents=Expression.arrayElements, toString=Expression.toString); - result := Expression.arrayFromList(es, Type.arrayElementType(ty), list(Dimension.INTEGER(d) for d in dims)); + result := Expression.arrayFromList(es, Type.arrayElementType(ty), list(Dimension.fromInteger(d) for d in dims)); end evalBuiltinCat; function evalBuiltinCeil @@ -608,7 +610,7 @@ algorithm z2 := Expression.REAL(x3 * y1 - x1 * y3); z3 := Expression.REAL(x1 * y2 - x2 * y1); then - Expression.ARRAY(Type.ARRAY(Type.REAL(), {Dimension.INTEGER(3)}), {z1, z2, z3}); + Expression.ARRAY(Type.ARRAY(Type.REAL(), {Dimension.fromInteger(3)}), {z1, z2, z3}); else algorithm printWrongArgsError(getInstanceName(), args, sourceInfo()); then fail(); end match; @@ -636,7 +638,7 @@ algorithm n := listLength(elems); elem_ty := Expression.typeOf(listHead(elems)); - row_ty := Type.liftArrayLeft(elem_ty, Dimension.INTEGER(n)); + row_ty := Type.liftArrayLeft(elem_ty, Dimension.fromInteger(n)); zero := Expression.makeZero(elem_ty); for e in listReverse(elems) loop @@ -656,7 +658,7 @@ algorithm rows := Expression.ARRAY(row_ty, row) :: rows; end for; then - Expression.ARRAY(Type.liftArrayLeft(row_ty, Dimension.INTEGER(n)), rows); + Expression.ARRAY(Type.liftArrayLeft(row_ty, Dimension.fromInteger(n)), rows); else algorithm printWrongArgsError(getInstanceName(), {arg}, sourceInfo()); then fail(); end match; @@ -736,7 +738,7 @@ algorithm end match; arr := list(result for e in 1:dim_size); - arr_ty := Type.liftArrayLeft(arr_ty, Dimension.INTEGER(dim_size)); + arr_ty := Type.liftArrayLeft(arr_ty, Dimension.fromInteger(dim_size)); result := Expression.ARRAY(arr_ty, arr); end for; end evalBuiltinFill2; @@ -981,18 +983,18 @@ protected algorithm Error.assertion(n >= 1, "Promote called with n<1", sourceInfo()); if n == 1 then - result := Expression.ARRAY(Type.liftArrayLeft(Expression.typeOf(arg),Dimension.INTEGER(1)), {arg}); + result := Expression.ARRAY(Type.liftArrayLeft(Expression.typeOf(arg),Dimension.fromInteger(1)), {arg}); return; end if; result := match arg case Expression.ARRAY() algorithm (exps as (Expression.ARRAY(ty=ty)::_)) := list(evalBuiltinPromoteWork(e, n-1) for e in arg.elements); - then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.INTEGER(listLength(arg.elements))), exps); + then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.fromInteger(listLength(arg.elements))), exps); else algorithm (exp as Expression.ARRAY(ty=ty)) := evalBuiltinPromoteWork(arg, n-1); - then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.INTEGER(1)), {exp}); + then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.fromInteger(1)), {exp}); end match; end evalBuiltinPromoteWork; @@ -1096,7 +1098,7 @@ algorithm y1 := Expression.ARRAY(ty, {zero, Expression.negate(x3), x2}); y2 := Expression.ARRAY(ty, {x3, zero, Expression.negate(x1)}); y3 := Expression.ARRAY(ty, {Expression.negate(x2), x1, zero}); - ty := Type.liftArrayLeft(ty, Dimension.INTEGER(3)); + ty := Type.liftArrayLeft(ty, Dimension.fromInteger(3)); then Expression.ARRAY(ty, {y1, y2, y3}); @@ -1203,7 +1205,7 @@ protected algorithm expl := Expression.fold(arg, evalBuiltinVector2, {}); ty := Type.liftArrayLeft(Type.arrayElementType(Expression.typeOf(arg)), - Dimension.INTEGER(listLength(expl))); + Dimension.fromInteger(listLength(expl))); result := Expression.ARRAY(ty, listReverse(expl)); end evalBuiltinVector; diff --git a/Compiler/NFFrontEnd/NFDimension.mo b/Compiler/NFFrontEnd/NFDimension.mo index 5cb2010df6d..844291534d6 100644 --- a/Compiler/NFFrontEnd/NFDimension.mo +++ b/Compiler/NFFrontEnd/NFDimension.mo @@ -58,6 +58,7 @@ public record INTEGER Integer size; + Variability var; end INTEGER; record BOOLEAN @@ -86,7 +87,7 @@ public ComponentRef cref; Type ty; - case Expression.INTEGER() then INTEGER(exp.value); + case Expression.INTEGER() then INTEGER(exp.value, var); case Expression.TYPENAME(ty = Type.ARRAY(elementType = ty)) then @@ -104,9 +105,14 @@ public end match; end fromExp; + function fromInteger + input Integer n; + output Dimension dim = INTEGER(n, Variability.CONSTANT); + end fromInteger; + function fromExpList input list expl; - output Dimension dim = INTEGER(listLength(expl)); + output Dimension dim = INTEGER(listLength(expl), Variability.CONSTANT); end fromExpList; function toDAE @@ -133,7 +139,7 @@ public c := match (a, b) case (UNKNOWN(),_) then UNKNOWN(); case (_,UNKNOWN()) then UNKNOWN(); - case (INTEGER(),INTEGER()) then INTEGER(a.size+b.size); + case (INTEGER(),INTEGER()) then INTEGER(a.size+b.size, Prefixes.variabilityMax(a.var, b.var)); case (INTEGER(),EXP()) then EXP(Expression.BINARY(b.exp, Operator.OPERATOR(Type.INTEGER(), NFOperator.Op.ADD), Expression.INTEGER(a.size)), b.var); case (EXP(),INTEGER()) then EXP(Expression.BINARY(a.exp, Operator.OPERATOR(Type.INTEGER(), NFOperator.Op.ADD), Expression.INTEGER(b.size)), a.var); case (EXP(),EXP()) then EXP(Expression.BINARY(a.exp, Operator.OPERATOR(Type.INTEGER(), NFOperator.Op.ADD), b.exp), Prefixes.variabilityMax(a.var, b.var)); @@ -283,5 +289,18 @@ public end match; end setScope; + function variability + input Dimension dim; + output Variability var; + algorithm + var := match dim + case INTEGER() then dim.var; + case BOOLEAN() then Variability.CONSTANT; + case ENUM() then Variability.CONSTANT; + case EXP() then dim.var; + case UNKNOWN() then Variability.CONTINUOUS; + end match; + end variability; + annotation(__OpenModelica_Interface="frontend"); end NFDimension; diff --git a/Compiler/NFFrontEnd/NFExpression.mo b/Compiler/NFFrontEnd/NFExpression.mo index f1d10c41fc4..4232486c4d0 100644 --- a/Compiler/NFFrontEnd/NFExpression.mo +++ b/Compiler/NFFrontEnd/NFExpression.mo @@ -2041,7 +2041,7 @@ public subs := expandCref2(crefExp.cref); if listEmpty(subs) then - arrayExp := ARRAY(Type.ARRAY(Type.arrayElementType(crefExp.ty), {Dimension.INTEGER(0)}), {}); + arrayExp := ARRAY(Type.ARRAY(Type.arrayElementType(crefExp.ty), {Dimension.fromInteger(0)}), {}); else arrayExp := expandCref3(subs, crefExp.cref, Type.arrayElementType(crefExp.ty)); end if; @@ -2696,7 +2696,7 @@ public algorithm zero := makeZero(elementType); one := makeOne(elementType); - row_ty := Type.ARRAY(elementType, {Dimension.INTEGER(n)}); + row_ty := Type.ARRAY(elementType, {Dimension.fromInteger(n)}); for i in 1:n loop row := {}; @@ -2714,7 +2714,7 @@ public rows := Expression.ARRAY(row_ty, row) :: rows; end for; - matrix := ARRAY(Type.liftArrayLeft(row_ty, Dimension.INTEGER(n)), rows); + matrix := ARRAY(Type.liftArrayLeft(row_ty, Dimension.fromInteger(n)), rows); end makeIdentityMatrix; function promote @@ -2724,7 +2724,7 @@ public protected list dims; algorithm - dims := list(Dimension.INTEGER(1) for i in Type.dimensionCount(ty):n-1); + dims := list(Dimension.fromInteger(1) for i in Type.dimensionCount(ty):n-1); ty := Type.liftArrayRightList(ty, dims); e := CALL(Call.makeBuiltinCall2(NFBuiltinFuncs.PROMOTE, {e, INTEGER(n)}, ty)); end promote; diff --git a/Compiler/NFFrontEnd/NFSubscript.mo b/Compiler/NFFrontEnd/NFSubscript.mo index 45130db888d..9bd3dbfc0cc 100644 --- a/Compiler/NFFrontEnd/NFSubscript.mo +++ b/Compiler/NFFrontEnd/NFSubscript.mo @@ -330,7 +330,7 @@ public output Dimension dimension; algorithm dimension := match subscript - case INDEX() then Dimension.INTEGER(1); + case INDEX() then Dimension.fromInteger(1); case SLICE() then listHead(Type.arrayDims(Expression.typeOf(subscript.slice))); case WHOLE() then Dimension.UNKNOWN(); end match; diff --git a/Compiler/NFFrontEnd/NFTypeCheck.mo b/Compiler/NFFrontEnd/NFTypeCheck.mo index ce1c6800e37..a74826892e0 100644 --- a/Compiler/NFFrontEnd/NFTypeCheck.mo +++ b/Compiler/NFFrontEnd/NFTypeCheck.mo @@ -1979,7 +1979,7 @@ algorithm Integer step; case (Expression.INTEGER(), NONE(), Expression.INTEGER()) - then Dimension.INTEGER(max(stopExp.value - startExp.value + 1, 0)); + then Dimension.fromInteger(max(stopExp.value - startExp.value + 1, 0)); case (Expression.INTEGER(), SOME(Expression.INTEGER(value = step)), Expression.INTEGER()) algorithm @@ -1988,7 +1988,7 @@ algorithm Error.addSourceMessageAndFail(Error.RANGE_ZERO_STEP, {}, info); end if; then - Dimension.INTEGER(max(intDiv(stopExp.value - startExp.value, step) + 1, 0)); + Dimension.fromInteger(max(intDiv(stopExp.value - startExp.value, step) + 1, 0)); else Dimension.UNKNOWN(); end match; @@ -2006,7 +2006,7 @@ algorithm Real step; case (Expression.REAL(), NONE(), Expression.REAL()) - then Dimension.INTEGER(Util.realRangeSize(startExp.value, 1.0, stopExp.value)); + then Dimension.fromInteger(Util.realRangeSize(startExp.value, 1.0, stopExp.value)); case (Expression.REAL(), SOME(Expression.REAL(value = step)), Expression.REAL()) algorithm @@ -2017,7 +2017,7 @@ algorithm Error.addSourceMessageAndFail(Error.RANGE_ZERO_STEP, {}, info); end if; then - Dimension.INTEGER(Util.realRangeSize(startExp.value, step, stopExp.value)); + Dimension.fromInteger(Util.realRangeSize(startExp.value, step, stopExp.value)); else Dimension.UNKNOWN(); end match; @@ -2038,7 +2038,7 @@ algorithm elseif startExp.value < startExp.value then 2 else 0; then - Dimension.INTEGER(sz); + Dimension.fromInteger(sz); else Dimension.UNKNOWN(); end match; @@ -2051,7 +2051,7 @@ function getRangeTypeEnum algorithm dim := match (startExp, stopExp) case (Expression.ENUM_LITERAL(), Expression.ENUM_LITERAL()) - then Dimension.INTEGER(max(stopExp.index - startExp.index + 1, 0)); + then Dimension.fromInteger(max(stopExp.index - startExp.index + 1, 0)); else Dimension.UNKNOWN(); end match; diff --git a/Compiler/NFFrontEnd/NFTyping.mo b/Compiler/NFFrontEnd/NFTyping.mo index 3894b4c0e9f..8c62872093c 100644 --- a/Compiler/NFFrontEnd/NFTyping.mo +++ b/Compiler/NFFrontEnd/NFTyping.mo @@ -1778,7 +1778,9 @@ algorithm exp := Expression.SIZE(exp, SOME(index)); end if; - variability := Variability.PARAMETER; + // Use the most variable of the index and the dimension as the variability + // of the size expression. + variability := Prefixes.variabilityMax(variability, Dimension.variability(dim)); else // If the index is not a constant, type the whole expression. (exp, exp_ty) := typeExp(sizeExp.exp, origin, info); @@ -1806,7 +1808,7 @@ algorithm fail(); end if; - sizeType := Type.ARRAY(Type.INTEGER(), {Dimension.INTEGER(Type.dimensionCount(exp_ty))}); + sizeType := Type.ARRAY(Type.INTEGER(), {Dimension.fromInteger(Type.dimensionCount(exp_ty))}); then (Expression.SIZE(exp, NONE()), sizeType, Variability.PARAMETER);