@@ -1710,9 +1710,13 @@ algorithm
17101710end printRangeTypeError;
17111711
17121712function typeSize
1713+ "Types a size expression. If evaluate is true the size expression is also
1714+ evaluated if the dimension is known and the index is a parameter expression,
1715+ otherwise a typed size expression is returned."
17131716 input output Expression sizeExp;
17141717 input ExpOrigin . Type origin;
17151718 input SourceInfo info;
1719+ input Boolean evaluate = true ;
17161720 output Type sizeType;
17171721 output Variability variability;
17181722protected
@@ -1724,7 +1728,7 @@ protected
17241728 TypingError ty_err;
17251729algorithm
17261730 (sizeExp, sizeType, variability) := match sizeExp
1727- case Expression . SIZE (dimIndex = SOME (index))
1731+ case Expression . SIZE (exp = exp, dimIndex = SOME (index))
17281732 algorithm
17291733 (index, index_ty, variability) := typeExp(index, origin, info);
17301734
@@ -1747,33 +1751,15 @@ algorithm
17471751 Expression . INTEGER (iindex) := index;
17481752
17491753 // Get the iindex'd dimension of the expression.
1750- (dim, ty_err) := typeExpDim(sizeExp. exp, iindex, origin, info);
1754+ (dim, ty_err) := typeExpDim(exp, iindex, origin, info);
1755+ checkSizeTypingError(ty_err, exp, iindex, info);
17511756
1752- () := match ty_err
1753- case NO_ERROR () then ();
1754-
1755- // The first argument wasn't an array.
1756- case OUT_OF_BOUNDS (0 )
1757- algorithm
1758- Error . addSourceMessage(Error . INVALID_ARGUMENT_TYPE_FIRST_ARRAY , {"size" }, info);
1759- then
1760- fail();
1761-
1762- // The index referred to an invalid dimension.
1763- case OUT_OF_BOUNDS ()
1764- algorithm
1765- Error . addSourceMessage(Error . INVALID_SIZE_INDEX ,
1766- {String (iindex), Expression . toString(sizeExp. exp), String (ty_err. upperBound)}, info);
1767- then
1768- fail();
1769- end match;
1770-
1771- if Dimension . isKnown(dim) then
1772- // The dimension size is known, return its size.
1757+ if Dimension . isKnown(dim) and evaluate then
1758+ // If the dimension size is known, return its size.
17731759 exp := Expression . INTEGER (Dimension . size(dim));
17741760 else
1775- // The dimension size is unknown, return a size expression. This can
1776- // happen in functions where unknown dimensions are allowed .
1761+ // If the dimension size is unknown (e.g. in a function) or
1762+ // evaluation is disabled, return a size expression instead .
17771763 exp := typeExp(sizeExp. exp, origin, info);
17781764 exp := Expression . SIZE (exp, SOME (index));
17791765 end if ;
@@ -1815,6 +1801,32 @@ algorithm
18151801 end match;
18161802end typeSize;
18171803
1804+ function checkSizeTypingError
1805+ input TypingError typingError;
1806+ input Expression exp;
1807+ input Integer index;
1808+ input SourceInfo info;
1809+ algorithm
1810+ () := match typingError
1811+ case NO_ERROR () then ();
1812+
1813+ // The first argument wasn't an array.
1814+ case OUT_OF_BOUNDS (0 )
1815+ algorithm
1816+ Error . addSourceMessage(Error . INVALID_ARGUMENT_TYPE_FIRST_ARRAY , {"size" }, info);
1817+ then
1818+ fail();
1819+
1820+ // The index referred to an invalid dimension.
1821+ case OUT_OF_BOUNDS ()
1822+ algorithm
1823+ Error . addSourceMessage(Error . INVALID_SIZE_INDEX ,
1824+ {String (index), Expression . toString(exp), String (typingError. upperBound)}, info);
1825+ then
1826+ fail();
1827+ end match;
1828+ end checkSizeTypingError;
1829+
18181830function evaluateEnd
18191831 input Expression exp;
18201832 input Dimension dim;
@@ -1912,30 +1924,44 @@ function typeExternalArg
19121924protected
19131925 Type ty;
19141926 Variability var ;
1927+ Expression index;
19151928algorithm
1916- (outArg, ty, var ) := typeExp(arg, ExpOrigin . FUNCTION , info);
1917-
1918- // Check that the external function argument is valid. The valid types of
1919- // expressions are crefs, scalar constants and size expressions with constant
1920- // index. The reason why we match on the untyped expression here is because
1921- // size expressions might be evaluated during typing, but the variability
1922- // would still be parameter in that case.
19231929 outArg := match arg
1924- case Expression . CREF () then outArg;
1925- case Expression . SIZE () guard var <= Variability . PARAMETER then outArg;
1926- else
1930+ case Expression . SIZE (dimIndex = SOME (_))
19271931 algorithm
1928- if Type . isScalarBuiltin(ty) and var == Variability . CONSTANT then
1929- outArg := Ceval . evalExp(outArg, Ceval . EvalTarget . GENERIC (info));
1930- outArg := SimplifyExp . simplifyExp(arg);
1931- else
1932- Error . addSourceMessage(Error . EXTERNAL_ARG_WRONG_EXP ,
1933- {Expression . toString(outArg)}, info);
1932+ outArg := typeSize(arg, ExpOrigin . FUNCTION , info, evaluate = false );
1933+ Expression . SIZE (dimIndex = SOME (index)) := outArg;
1934+
1935+ // Size expression must have a constant dimension index.
1936+ if not Expression . isInteger(index) then
1937+ Error . addSourceMessage(Error . EXTERNAL_ARG_NONCONSTANT_SIZE_INDEX ,
1938+ {Expression . toString(arg)}, info);
19341939 fail();
19351940 end if ;
19361941 then
19371942 outArg;
19381943
1944+ else
1945+ algorithm
1946+ (outArg, ty, var ) := typeExp(arg, ExpOrigin . FUNCTION , info);
1947+ then
1948+ match arg
1949+ // All kinds of crefs are allowed.
1950+ case Expression . CREF () then outArg;
1951+ else
1952+ algorithm
1953+ // The only other kind of expression that's allowed is scalar constants.
1954+ if Type . isScalarBuiltin(ty) and var == Variability . CONSTANT then
1955+ outArg := Ceval . evalExp(outArg, Ceval . EvalTarget . GENERIC (info));
1956+ outArg := SimplifyExp . simplifyExp(arg);
1957+ else
1958+ Error . addSourceMessage(Error . EXTERNAL_ARG_WRONG_EXP ,
1959+ {Expression . toString(outArg)}, info);
1960+ fail();
1961+ end if ;
1962+ then
1963+ outArg;
1964+ end match;
19391965 end match;
19401966end typeExternalArg;
19411967
0 commit comments