diff --git a/Compiler/NFFrontEnd/NFCall.mo b/Compiler/NFFrontEnd/NFCall.mo index 3270812153..c2803dd862 100644 --- a/Compiler/NFFrontEnd/NFCall.mo +++ b/Compiler/NFFrontEnd/NFCall.mo @@ -139,31 +139,31 @@ uniontype Call CallAttributes attributes; end TYPED_CALL; - // Right now this represents only array() calls. - // Any other mapping call e.g. F(i for i in ...) is converted to - // array(F(i) for i in ...) at instIteratorCall(). - // So the fn is always NFBuiltinFuncs.ARRAY_FUNC. - - // Note that F(i for i in ...) only allows - // calling functions with just one argument according to the current - // grammar anyway. array(F(i,j) for i in ..) makes this multi calls possible - // in Modelica code. - - // If you need to have more mapping calls e.g list() at some point just add them - // and make use of fn; - record UNTYPED_MAP_CALL - // Function fn; + record UNTYPED_ARRAY_CONSTRUCTOR Expression exp; list> iters; - end UNTYPED_MAP_CALL; + end UNTYPED_ARRAY_CONSTRUCTOR; - record TYPED_MAP_CALL - // Function fn; + record TYPED_ARRAY_CONSTRUCTOR Type ty; Variability var; Expression exp; list> iters; - end TYPED_MAP_CALL; + end TYPED_ARRAY_CONSTRUCTOR; + + record UNTYPED_REDUCTION + ComponentRef ref; + Expression exp; + list> iters; + end UNTYPED_REDUCTION; + + record TYPED_REDUCTION + Function fn; + Type ty; + Variability var; + Expression exp; + list> iters; + end TYPED_REDUCTION; function instantiate input Absyn.ComponentRef functionName; @@ -192,27 +192,29 @@ uniontype Call output Type ty; output Variability var; protected - Call call; + Call call, ty_call; list args; ComponentRef cref; algorithm - outExp := match callExp - case Expression.CALL(UNTYPED_CALL(ref = cref)) + Expression.CALL(call = call) := callExp; + + outExp := match call + case UNTYPED_CALL(ref = cref) algorithm - if(BuiltinCall.needSpecialHandling(callExp.call)) then - (outExp, ty, var) := BuiltinCall.typeSpecial(callExp.call, origin, info); + if(BuiltinCall.needSpecialHandling(call)) then + (outExp, ty, var) := BuiltinCall.typeSpecial(call, origin, info); else - call := typeMatchNormalCall(callExp.call, origin, info); - ty := typeOf(call); - var := variability(call); + ty_call := typeMatchNormalCall(call, origin, info); + ty := typeOf(ty_call); + var := variability(ty_call); - if isRecordConstructor(call) then - outExp := toRecordExpression(call, ty); + if isRecordConstructor(ty_call) then + outExp := toRecordExpression(ty_call, ty); else if Function.hasUnboxArgs(InstNode.definition(ComponentRef.node(cref))) then - outExp := Expression.CALL(Call.unboxArgs(call)); + outExp := Expression.CALL(Call.unboxArgs(ty_call)); else - outExp := Expression.CALL(call); + outExp := Expression.CALL(ty_call); end if; outExp := Inline.inlineCallExp(outExp); end if; @@ -220,22 +222,26 @@ uniontype Call then outExp; - case Expression.CALL(UNTYPED_MAP_CALL()) + case UNTYPED_ARRAY_CONSTRUCTOR() algorithm - call := typeMapIteratorCall(callExp.call, origin, info); - ty := typeOf(call); - var := variability(call); + (ty_call, ty, var) := typeArrayConstructor(call, origin, info); then - Expression.CALL(call); + Expression.CALL(ty_call); - case Expression.CALL(call as TYPED_CALL()) + case UNTYPED_REDUCTION() + algorithm + (ty_call, ty, var) := typeReduction(call, origin, info); + then + Expression.CALL(ty_call); + + case TYPED_ARRAY_CONSTRUCTOR() algorithm ty := call.ty; var := call.var; then callExp; - case Expression.CALL(call as TYPED_MAP_CALL()) + case TYPED_REDUCTION() algorithm ty := call.ty; var := call.var; @@ -384,7 +390,8 @@ uniontype Call algorithm ty := match call case TYPED_CALL() then call.ty; - case TYPED_MAP_CALL() then call.ty; + case TYPED_ARRAY_CONSTRUCTOR() then call.ty; + case TYPED_REDUCTION() then call.ty; else Type.UNKNOWN(); end match; end typeOf; @@ -395,7 +402,8 @@ uniontype Call algorithm call := match call case TYPED_CALL() algorithm call.ty := ty; then call; - case TYPED_MAP_CALL() algorithm call.ty := ty; then call; + case TYPED_ARRAY_CONSTRUCTOR() algorithm call.ty := ty; then call; + case TYPED_REDUCTION() algorithm call.ty := ty; then call; end match; end setType; @@ -432,9 +440,11 @@ uniontype Call then var; - case UNTYPED_MAP_CALL() then Expression.variability(call.exp); + case UNTYPED_ARRAY_CONSTRUCTOR() then Expression.variability(call.exp); + case UNTYPED_REDUCTION() then Expression.variability(call.exp); case TYPED_CALL() then call.var; - case TYPED_MAP_CALL() then call.var; + case TYPED_ARRAY_CONSTRUCTOR() then call.var; + case TYPED_REDUCTION() then call.var; else algorithm Error.assertion(false, getInstanceName() + " got untyped call", sourceInfo()); then fail(); @@ -517,7 +527,8 @@ uniontype Call algorithm fn := match call case TYPED_CALL() then call.fn; - case TYPED_MAP_CALL() then NFBuiltinFuncs.ARRAY_FUNC; + case TYPED_ARRAY_CONSTRUCTOR() then NFBuiltinFuncs.ARRAY_FUNC; + case TYPED_REDUCTION() then call.fn; else algorithm Error.assertion(false, getInstanceName() + " got untyped function", sourceInfo()); @@ -574,12 +585,23 @@ uniontype Call then name + "(" + arg_str + ")"; - case UNTYPED_MAP_CALL() + case UNTYPED_ARRAY_CONSTRUCTOR() algorithm name := Absyn.pathString(Function.name(NFBuiltinFuncs.ARRAY_FUNC)); arg_str := Expression.toString(call.exp); + c := stringDelimitList(list(InstNode.name(Util.tuple21(iter)) + " in " + + Expression.toString(Util.tuple22(iter)) for iter in call.iters), ", "); then - name + "(" + arg_str + ")"; + "{" + arg_str + " for " + c + "}"; + + case UNTYPED_REDUCTION() + algorithm + name := ComponentRef.toString(call.ref); + arg_str := Expression.toString(call.exp); + c := stringDelimitList(list(InstNode.name(Util.tuple21(iter)) + " in " + + Expression.toString(Util.tuple22(iter)) for iter in call.iters), ", "); + then + name + "(" + arg_str + " for " + c + ")"; case TYPED_CALL() algorithm @@ -588,12 +610,21 @@ uniontype Call then name + "(" + arg_str + ")"; - case TYPED_MAP_CALL() + case TYPED_ARRAY_CONSTRUCTOR() algorithm name := Absyn.pathString(Function.name(NFBuiltinFuncs.ARRAY_FUNC)); arg_str := Expression.toString(call.exp); c := stringDelimitList(list(InstNode.name(Util.tuple21(iter)) + " in " + Expression.toString(Util.tuple22(iter)) for iter in call.iters), ", "); + then + "{" + arg_str + " for " + c + "}"; + + case TYPED_REDUCTION() + algorithm + name := Absyn.pathString(Function.name(call.fn)); + arg_str := Expression.toString(call.exp); + c := stringDelimitList(list(InstNode.name(Util.tuple21(iter)) + " in " + + Expression.toString(Util.tuple22(iter)) for iter in call.iters), ", "); then name + "(" + arg_str + " for " + c + ")"; @@ -645,7 +676,7 @@ uniontype Call list(Expression.toDAE(e) for e in call.arguments), CallAttributes.toDAE(call.attributes)); - case TYPED_MAP_CALL() + case TYPED_ARRAY_CONSTRUCTOR() then DAE.REDUCTION( DAE.REDUCTIONINFO( Function.name(NFBuiltinFuncs.ARRAY_FUNC), @@ -658,6 +689,19 @@ uniontype Call Expression.toDAE(call.exp), list(iteratorToDAE(iter) for iter in call.iters)); + case TYPED_REDUCTION() + then DAE.REDUCTION( + DAE.REDUCTIONINFO( + Function.name(call.fn), + Absyn.COMBINE(), + Type.toDAE(call.ty), + NONE(), + String(Util.getTempVariableIndex()), + String(Util.getTempVariableIndex()), + NONE()), + Expression.toDAE(call.exp), + list(iteratorToDAE(iter) for iter in call.iters)); + else algorithm Error.assertion(false, getInstanceName() + " got untyped call", sourceInfo()); @@ -758,50 +802,27 @@ protected input SourceInfo info; output Expression callExp; protected - ComponentRef fn_ref, arr_fn_ref; + Absyn.ComponentRef fn_name; + ComponentRef fn_ref; Expression exp; list> iters; - Call call; - Boolean is_builtin_reduction, is_array; + Boolean is_array; algorithm - (is_builtin_reduction, is_array) := match Absyn.crefFirstIdent(functionName) - case "$array" then (false, true); - case "array" then (false, true); - case "min" then (true, false); - case "max" then (true, false); - case "sum" then (true, false); - case "product" then (true, false); - else (false, false); + // The parser turns {exp for i in ...} into $array(exp for i in ...), but we + // change it to just array here so we can handle array constructors uniformly. + fn_name := match functionName + case Absyn.CREF_IDENT("$array") then Absyn.CREF_IDENT("array", {}); + else functionName; end match; (exp, iters) := instIteratorCallArgs(functionArgs, scope, info); - // If it is one of the builtin functions above the call operates as a "reduction" - // (think of it like just a call to the overload of the function that takes array as argument.) - // We handle it by making a call to the builtin function with an array as argument. - // Which is valid since all these builtin functions accept array arguments anyway. - if is_builtin_reduction then - // start by making an array map call. - call := UNTYPED_MAP_CALL(exp, iters); - - // wrap the array call in the given function - // e.g. sum(array(i for i in ...)). - fn_ref := Function.instFunction(functionName, scope, info); - call := UNTYPED_CALL(fn_ref, {Expression.CALL(call)}, {}, scope); + if Absyn.crefFirstIdent(fn_name) == "array" then + callExp := Expression.CALL(UNTYPED_ARRAY_CONSTRUCTOR(exp, iters)); else - // Otherwise, make an array call with the original function call as an argument. - // But only if the original function is not array() itself. - // e.g. Change myfunc(i for i in ...) TO array(myfunc(i) for i in ...). - if not is_array then - fn_ref := Function.instFunction(functionName, scope, info); - call := UNTYPED_CALL(fn_ref, {exp}, {}, scope); - exp := Expression.CALL(call); - end if; - - call := UNTYPED_MAP_CALL(exp, iters); + fn_ref := Function.instFunction(fn_name, scope, info); + callExp := Expression.CALL(UNTYPED_REDUCTION(fn_ref, exp, iters)); end if; - - callExp := Expression.CALL(call); end instIteratorCall; function instIteratorCallArgs @@ -843,7 +864,7 @@ protected outIters := listReverse(outIters); end instIterators; - function typeMapIteratorCall + function typeArrayConstructor input output Call call; input ExpOrigin.Type origin; input SourceInfo info; @@ -852,7 +873,6 @@ protected protected Expression arg, range; Type iter_ty; - Binding binding; Variability iter_var; InstNode iter; list dims = {}; @@ -861,9 +881,7 @@ protected Boolean is_structural; algorithm (call, ty, variability) := match call - // This is always a call to the function array()/$array(). See instIteratorCall. - // Other mapping function calls are already wrapped by array() at this point. - case UNTYPED_MAP_CALL() + case UNTYPED_ARRAY_CONSTRUCTOR() algorithm variability := Variability.CONSTANT; // The size of the expression must be known unless we're in a function. @@ -889,7 +907,7 @@ protected (arg, ty) := Typing.typeExp(call.exp, next_origin, info); ty := Type.liftArrayLeftList(ty, dims); then - (TYPED_MAP_CALL(ty, variability, arg, iters), ty, variability); + (TYPED_ARRAY_CONSTRUCTOR(ty, variability, arg, iters), ty, variability); else algorithm @@ -897,7 +915,50 @@ protected then fail(); end match; - end typeMapIteratorCall; + end typeArrayConstructor; + + function typeReduction + input output Call call; + input ExpOrigin.Type origin; + input SourceInfo info; + output Type ty; + output Variability variability; + protected + Expression range, arg; + InstNode iter; + Variability iter_var; + list> iters = {}; + ExpOrigin.Type next_origin; + Function fn; + algorithm + (call, ty, variability) := match call + case UNTYPED_REDUCTION() + algorithm + variability := Variability.CONSTANT; + + for i in call.iters loop + (iter, range) := i; + (range, _, iter_var) := Typing.typeIterator(iter, range, origin, structural = false); + variability := Variability.variabilityMax(variability, iter_var); + iters := (iter, range) :: iters; + end for; + + iters := listReverseInPlace(iters); + + // ExpOrigin.FOR is used here as a marker that this expression may contain iterators. + next_origin := intBitOr(origin, ExpOrigin.FOR); + (arg, ty) := Typing.typeExp(call.exp, next_origin, info); + {fn} := Function.typeRefCache(call.ref); + then + (TYPED_REDUCTION(fn, ty, variability, arg, iters), ty, variability); + + else + algorithm + Error.assertion(false, getInstanceName() + " got invalid reduction call", sourceInfo()); + then + fail(); + end match; + end typeReduction; function typeArgs input output Call call; @@ -1102,7 +1163,7 @@ protected vect_ty := Type.liftArrayLeftList(base_call.ty, vect_dims); then - TYPED_MAP_CALL(vect_ty, base_call.var, Expression.CALL(base_call), iters); + TYPED_ARRAY_CONSTRUCTOR(vect_ty, base_call.var, Expression.CALL(base_call), iters); end match; end vectorizeCall; diff --git a/Compiler/NFFrontEnd/NFCeval.mo b/Compiler/NFFrontEnd/NFCeval.mo index 5725aeeacf..cb0feccc9d 100644 --- a/Compiler/NFFrontEnd/NFCeval.mo +++ b/Compiler/NFFrontEnd/NFCeval.mo @@ -60,6 +60,7 @@ import ExpressionIterator = NFExpressionIterator; import MetaModelica.Dangerous.*; import NFClass.Class; import TypeCheck = NFTypeCheck; +import ExpandExp = NFExpandExp; public uniontype EvalTarget @@ -577,32 +578,10 @@ function evalTypename input Expression originExp; input EvalTarget target; output Expression exp; -protected - list lits; algorithm // Only expand the typename into an array if it's used as a range, and keep // them as typenames when used as e.g. dimensions. - if not EvalTarget.isRange(target) then - exp := originExp; - else - exp := match ty - case Type.ARRAY(elementType = Type.BOOLEAN()) - then Expression.ARRAY(ty, {Expression.BOOLEAN(false), Expression.BOOLEAN(true)}); - - case Type.ARRAY(elementType = Type.ENUMERATION()) - algorithm - lits := Expression.makeEnumLiterals(ty.elementType); - then - Expression.ARRAY(ty, lits); - - else - algorithm - Error.addInternalError(getInstanceName() + " got invalid typename", sourceInfo()); - then - fail(); - - end match; - end if; + exp := if EvalTarget.isRange(target) then ExpandExp.expandTypename(ty) else originExp; end evalTypename; function evalRange @@ -1464,8 +1443,11 @@ algorithm else evalNormalCall(call.fn, args); - case Call.TYPED_MAP_CALL() - then evalReduction(call.exp, call.ty, call.iters); + case Call.TYPED_ARRAY_CONSTRUCTOR() + then evalArrayConstructor(call.exp, call.ty, call.iters); + + case Call.TYPED_REDUCTION() + then evalReduction(call.fn, call.exp, call.ty, call.iters); else algorithm @@ -2627,30 +2609,40 @@ algorithm end match; end evalSolverClock; -function evalReduction +function evalArrayConstructor input Expression exp; input Type ty; input list> iterators; output Expression result; protected - Expression e = exp, range; + Expression e; + list ranges; + list> iters; +algorithm + (e, ranges, iters) := createIterationRanges(exp, iterators); + result := evalArrayConstructor2(e, ty, ranges, iters); +end evalArrayConstructor; + +function createIterationRanges + input output Expression exp; + input list> iterators; + output list ranges = {}; + output list> iters = {}; +protected InstNode node; - list ranges = {}, expl; + Expression range; Mutable iter; - list> iters = {}; algorithm for i in iterators loop (node, range) := i; iter := Mutable.create(Expression.INTEGER(0)); - e := Expression.replaceIterator(e, node, Expression.MUTABLE(iter)); + exp := Expression.replaceIterator(exp, node, Expression.MUTABLE(iter)); iters := iter :: iters; ranges := evalExp(range) :: ranges; end for; +end createIterationRanges; - result := evalReduction2(e, ty, ranges, iters); -end evalReduction; - -function evalReduction2 +function evalArrayConstructor2 input Expression exp; input Type ty; input list ranges; @@ -2676,11 +2668,79 @@ algorithm while ExpressionIterator.hasNext(range_iter) loop (range_iter, value) := ExpressionIterator.next(range_iter); Mutable.update(iter, value); - expl := evalReduction2(exp, el_ty, ranges_rest, iters_rest) :: expl; + expl := evalArrayConstructor2(exp, el_ty, ranges_rest, iters_rest) :: expl; end while; result := Expression.ARRAY(ty, listReverseInPlace(expl)); end if; +end evalArrayConstructor2; + +partial function ReductionFn + input Expression exp1; + input Expression exp2; + output Expression result; +end ReductionFn; + +function evalReduction + input Function fn; + input Expression exp; + input Type ty; + input list> iterators; + output Expression result; +protected + Expression e, default_exp; + list ranges; + list> iters; + ReductionFn red_fn; +algorithm + (e, ranges, iters) := createIterationRanges(exp, iterators); + + (red_fn, default_exp) := match Absyn.pathString(Function.name(fn)) + case "sum" then (evalBinaryAdd, Expression.makeZero(ty)); + case "product" then (evalBinaryMul, Expression.makeOne(ty)); + case "min" then (evalBuiltinMin2, Expression.makeMaxValue(ty)); + case "max" then (evalBuiltinMax2, Expression.makeMinValue(ty)); + else + algorithm + Error.assertion(false, getInstanceName() + " got unknown reduction function " + + Absyn.pathString(Function.name(fn)), sourceInfo()); + then + fail(); + end match; + + result := evalReduction2(e, ranges, iters, default_exp, red_fn); +end evalReduction; + +function evalReduction2 + input Expression exp; + input list ranges; + input list> iterators; + input Expression foldExp; + input ReductionFn fn; + output Expression result; +protected + Expression range; + list ranges_rest, expl = {}; + Mutable iter; + list> iters_rest; + ExpressionIterator range_iter; + Expression value; + Type el_ty; +algorithm + if listEmpty(ranges) then + result := fn(foldExp, evalExp(exp)); + else + range :: ranges_rest := ranges; + iter :: iters_rest := iterators; + range_iter := ExpressionIterator.fromExp(range); + result := foldExp; + + while ExpressionIterator.hasNext(range_iter) loop + (range_iter, value) := ExpressionIterator.next(range_iter); + Mutable.update(iter, value); + result := evalReduction2(exp, ranges_rest, iters_rest, result, fn); + end while; + end if; end evalReduction2; function evalSize diff --git a/Compiler/NFFrontEnd/NFExpandExp.mo b/Compiler/NFFrontEnd/NFExpandExp.mo index c06c979b07..ac1e89e0b5 100644 --- a/Compiler/NFFrontEnd/NFExpandExp.mo +++ b/Compiler/NFFrontEnd/NFExpandExp.mo @@ -68,6 +68,7 @@ public (exp, expanded); case Expression.ARRAY() then (exp, true); + case Expression.TYPENAME() then (expandTypename(exp.ty), true); case Expression.RANGE() then expandRange(exp); case Expression.CALL() then expandCall(exp.call, exp); case Expression.SIZE() then expandSize(exp); @@ -198,6 +199,31 @@ public end match; end expandCref4; + function expandTypename + input Type ty; + output Expression outExp; + algorithm + outExp := match ty + local + list lits; + + case Type.ARRAY(elementType = Type.BOOLEAN()) + then Expression.ARRAY(ty, {Expression.BOOLEAN(false), Expression.BOOLEAN(true)}); + + case Type.ARRAY(elementType = Type.ENUMERATION()) + algorithm + lits := Expression.makeEnumLiterals(ty.elementType); + then + Expression.ARRAY(ty, lits); + + else + algorithm + Error.addInternalError(getInstanceName() + " got invalid typename", sourceInfo()); + then + fail(); + end match; + end expandTypename; + function expandRange input Expression exp; output Expression outExp; @@ -227,8 +253,8 @@ public guard Function.isBuiltin(call.fn) and not Function.isImpure(call.fn) then expandBuiltinCall(call.fn, call.arguments, call); - case Call.TYPED_MAP_CALL() - then expandReduction(call.exp, call.ty, call.iters); + case Call.TYPED_ARRAY_CONSTRUCTOR() + then expandArrayConstructor(call.exp, call.ty, call.iters); else expandGeneric(exp); end matchcontinue; @@ -340,7 +366,7 @@ public end match; end expandBuiltinGeneric2; - function expandReduction + function expandArrayConstructor input Expression exp; input Type ty; input list> iterators; @@ -362,10 +388,10 @@ public ranges := range :: ranges; end for; - result := expandReduction2(e, ty, ranges, iters); - end expandReduction; + result := expandArrayConstructor2(e, ty, ranges, iters); + end expandArrayConstructor; - function expandReduction2 + function expandArrayConstructor2 input Expression exp; input Type ty; input list ranges; @@ -384,8 +410,8 @@ public // Normally it wouldn't be the expansion's task to simplify expressions, // but we make an exception here since the generated expressions contain // MUTABLE expressions that we need to get rid of. Also, expansion of - // reductions is often done during the scalarization phase, after the - // simplification phase, so they wouldn't otherwise be simplified. + // array constructors is often done during the scalarization phase, after + // the simplification phase, so they wouldn't otherwise be simplified. result := expand(SimplifyExp.simplify(exp)); else range :: ranges_rest := ranges; @@ -396,12 +422,12 @@ public while ExpressionIterator.hasNext(range_iter) loop (range_iter, value) := ExpressionIterator.next(range_iter); Mutable.update(iter, value); - expl := expandReduction2(exp, el_ty, ranges_rest, iters_rest) :: expl; + expl := expandArrayConstructor2(exp, el_ty, ranges_rest, iters_rest) :: expl; end while; result := Expression.ARRAY(ty, listReverseInPlace(expl)); end if; - end expandReduction2; + end expandArrayConstructor2; function expandSize input Expression exp; diff --git a/Compiler/NFFrontEnd/NFExpression.mo b/Compiler/NFFrontEnd/NFExpression.mo index c4ab991c9a..c7e407bfff 100644 --- a/Compiler/NFFrontEnd/NFExpression.mo +++ b/Compiler/NFFrontEnd/NFExpression.mo @@ -34,6 +34,7 @@ protected import Util; import Absyn; import List; + import System; import Builtin = NFBuiltin; import BuiltinCall = NFBuiltinCall; @@ -437,6 +438,17 @@ public then Util.boolCompare(exp1.value, b); + case ENUM_LITERAL() + algorithm + ENUM_LITERAL(ty = ty, index = i) := exp2; + comp := Absyn.pathCompare(Type.enumName(exp1.ty), Type.enumName(ty)); + + if comp == 0 then + comp := Util.intCompare(exp1.index, i); + end if; + then + comp; + case CLKCONST(clk1) algorithm CLKCONST(clk2) := exp2; @@ -853,8 +865,8 @@ public case RANGE() guard listEmpty(restSubscripts) then applySubscriptRange(subscript, exp); - case CALL(call = Call.TYPED_MAP_CALL()) - then applySubscriptReduction(subscript, exp.call, restSubscripts); + case CALL(call = Call.TYPED_ARRAY_CONSTRUCTOR()) + then applySubscriptArrayConstructor(subscript, exp.call, restSubscripts); case IF() then applySubscriptIf(subscript, exp, restSubscripts); @@ -1083,21 +1095,21 @@ public end match; end applyIndexSubscriptRange2; - function applySubscriptReduction + function applySubscriptArrayConstructor input Subscript subscript; input Call call; input list restSubscripts; output Expression outExp; algorithm if Subscript.isIndex(subscript) and listEmpty(restSubscripts) then - outExp := applyIndexSubscriptReduction(call, subscript); + outExp := applyIndexSubscriptArrayConstructor(call, subscript); else // TODO: Handle slicing and multiple subscripts better. outExp := makeSubscriptedExp(subscript :: restSubscripts, CALL(call)); end if; - end applySubscriptReduction; + end applySubscriptArrayConstructor; - function applyIndexSubscriptReduction + function applyIndexSubscriptArrayConstructor input Call call; input Subscript index; output Expression subscriptedExp; @@ -1108,15 +1120,15 @@ public list> iters; InstNode iter; algorithm - Call.TYPED_MAP_CALL(ty, var, exp, iters) := call; + Call.TYPED_ARRAY_CONSTRUCTOR(ty, var, exp, iters) := call; ((iter, iter_exp), iters) := List.splitLast(iters); iter_exp := applySubscript(index, iter_exp); subscriptedExp := replaceIterator(exp, iter, iter_exp); if not listEmpty(iters) then - subscriptedExp := CALL(Call.TYPED_MAP_CALL(Type.unliftArray(ty), var, subscriptedExp, iters)); + subscriptedExp := CALL(Call.TYPED_ARRAY_CONSTRUCTOR(Type.unliftArray(ty), var, subscriptedExp, iters)); end if; - end applyIndexSubscriptReduction; + end applyIndexSubscriptArrayConstructor; function applySubscriptIf input Subscript subscript; @@ -1422,8 +1434,8 @@ public case CREF() then DAE.CREF(ComponentRef.toDAE(exp.cref), Type.toDAE(exp.ty)); - // TYPENAME() doesn't have a DAE representation, and shouldn't need to be - // converted anyway. + case TYPENAME() + then toDAE(ExpandExp.expandTypename(exp.ty)); case ARRAY() then DAE.ARRAY(Type.toDAE(exp.ty), Type.isScalarArray(exp.ty), @@ -1769,19 +1781,33 @@ public then Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() algorithm e := map(call.exp, func); iters := mapCallIterators(call.iters, func); then - Call.UNTYPED_MAP_CALL(e, iters); + Call.UNTYPED_ARRAY_CONSTRUCTOR(e, iters); - case Call.TYPED_MAP_CALL() + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm e := map(call.exp, func); iters := mapCallIterators(call.iters, func); then - Call.TYPED_MAP_CALL(call.ty, call.var, e, iters); + Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters); + + case Call.UNTYPED_REDUCTION() + algorithm + e := map(call.exp, func); + iters := mapCallIterators(call.iters, func); + then + Call.UNTYPED_REDUCTION(call.ref, e, iters); + + case Call.TYPED_REDUCTION() + algorithm + e := map(call.exp, func); + iters := mapCallIterators(call.iters, func); + then + Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters); end match; end mapCall; @@ -2086,18 +2112,29 @@ public then Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() algorithm e := func(call.exp); then - Call.UNTYPED_MAP_CALL(e, call.iters); + Call.UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters); - case Call.TYPED_MAP_CALL() + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm e := func(call.exp); then - Call.TYPED_MAP_CALL(call.ty, call.var, e, call.iters); + Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters); + case Call.UNTYPED_REDUCTION() + algorithm + e := func(call.exp); + then + Call.UNTYPED_REDUCTION(call.ref, e, call.iters); + + case Call.TYPED_REDUCTION() + algorithm + e := func(call.exp); + then + Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, call.iters); end match; end mapCallShallow; @@ -2330,7 +2367,17 @@ public then (); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() + algorithm + foldArg := fold(call.exp, func, foldArg); + + for i in call.iters loop + foldArg := fold(Util.tuple22(i), func, foldArg); + end for; + then + (); + + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm foldArg := fold(call.exp, func, foldArg); @@ -2340,7 +2387,7 @@ public then (); - case Call.TYPED_MAP_CALL() + case Call.UNTYPED_REDUCTION() algorithm foldArg := fold(call.exp, func, foldArg); @@ -2350,6 +2397,15 @@ public then (); + case Call.TYPED_REDUCTION() + algorithm + foldArg := fold(call.exp, func, foldArg); + + for i in call.iters loop + foldArg := fold(Util.tuple22(i), func, foldArg); + end for; + then + (); end match; end foldCall; @@ -2564,7 +2620,7 @@ public then (); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() algorithm apply(call.exp, func); @@ -2574,7 +2630,7 @@ public then (); - case Call.TYPED_MAP_CALL() + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm apply(call.exp, func); @@ -2584,6 +2640,25 @@ public then (); + case Call.UNTYPED_REDUCTION() + algorithm + apply(call.exp, func); + + for i in call.iters loop + apply(Util.tuple22(i), func); + end for; + then + (); + + case Call.TYPED_REDUCTION() + algorithm + apply(call.exp, func); + + for i in call.iters loop + apply(Util.tuple22(i), func); + end for; + then + (); end match; end applyCall; @@ -2903,18 +2978,29 @@ public then Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() + algorithm + (e, foldArg) := mapFold(call.exp, func, foldArg); + then + Call.UNTYPED_ARRAY_CONSTRUCTOR(e, call.iters); + + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm (e, foldArg) := mapFold(call.exp, func, foldArg); then - Call.UNTYPED_MAP_CALL(e, call.iters); + Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, call.iters); - case Call.TYPED_MAP_CALL() + case Call.UNTYPED_REDUCTION() algorithm (e, foldArg) := mapFold(call.exp, func, foldArg); then - Call.TYPED_MAP_CALL(call.ty, call.var, e, call.iters); + Call.UNTYPED_REDUCTION(call.ref, e, call.iters); + case Call.TYPED_REDUCTION() + algorithm + (e, foldArg) := mapFold(call.exp, func, foldArg); + then + Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, call.iters); end match; end mapFoldCall; @@ -3260,19 +3346,33 @@ public then Call.TYPED_CALL(call.fn, call.ty, call.var, args, call.attributes); - case Call.UNTYPED_MAP_CALL() + case Call.UNTYPED_ARRAY_CONSTRUCTOR() algorithm (e, foldArg) := func(call.exp, foldArg); iters := mapFoldCallIteratorsShallow(call.iters, func, foldArg); then - Call.UNTYPED_MAP_CALL(e, iters); + Call.UNTYPED_ARRAY_CONSTRUCTOR(e, iters); - case Call.TYPED_MAP_CALL() + case Call.TYPED_ARRAY_CONSTRUCTOR() algorithm (e, foldArg) := func(call.exp, foldArg); iters := mapFoldCallIteratorsShallow(call.iters, func, foldArg); then - Call.TYPED_MAP_CALL(call.ty, call.var, e, iters); + Call.TYPED_ARRAY_CONSTRUCTOR(call.ty, call.var, e, iters); + + case Call.UNTYPED_REDUCTION() + algorithm + (e, foldArg) := func(call.exp, foldArg); + iters := mapFoldCallIteratorsShallow(call.iters, func, foldArg); + then + Call.UNTYPED_REDUCTION(call.ref, e, iters); + + case Call.TYPED_REDUCTION() + algorithm + (e, foldArg) := func(call.exp, foldArg); + iters := mapFoldCallIteratorsShallow(call.iters, func, foldArg); + then + Call.TYPED_REDUCTION(call.fn, call.ty, call.var, e, iters); end match; end mapFoldCallShallow; @@ -3510,8 +3610,10 @@ public false; case Call.TYPED_CALL() then listContains(call.arguments, func); - case Call.UNTYPED_MAP_CALL() then contains(call.exp, func); - case Call.TYPED_MAP_CALL() then contains(call.exp, func); + case Call.UNTYPED_ARRAY_CONSTRUCTOR() then contains(call.exp, func); + case Call.TYPED_ARRAY_CONSTRUCTOR() then contains(call.exp, func); + case Call.UNTYPED_REDUCTION() then contains(call.exp, func); + case Call.TYPED_REDUCTION() then contains(call.exp, func); end match; end callContains; @@ -3737,6 +3839,36 @@ public end match; end makeOne; + function makeMaxValue + input Type ty; + output Expression exp; + algorithm + exp := match ty + case Type.REAL() then REAL(System.realMaxLit()); + case Type.INTEGER() then INTEGER(System.intMaxLit()); + case Type.BOOLEAN() then BOOLEAN(true); + case Type.ENUMERATION() then ENUM_LITERAL(ty, List.last(ty.literals), listLength(ty.literals)); + case Type.ARRAY() + then ARRAY(ty, List.fill(makeMaxValue(Type.unliftArray(ty)), + Dimension.size(listHead(ty.dimensions)))); + end match; + end makeMaxValue; + + function makeMinValue + input Type ty; + output Expression exp; + algorithm + exp := match ty + case Type.REAL() then REAL(-System.realMaxLit()); + case Type.INTEGER() then INTEGER(-System.intMaxLit()); + case Type.BOOLEAN() then BOOLEAN(false); + case Type.ENUMERATION() then ENUM_LITERAL(ty, listHead(ty.literals), 1); + case Type.ARRAY() + then ARRAY(ty, List.fill(makeMaxValue(Type.unliftArray(ty)), + Dimension.size(listHead(ty.dimensions)))); + end match; + end makeMinValue; + function unbox input Expression boxedExp; output Expression exp; @@ -4187,8 +4319,6 @@ public then (); - //case CALL(call = Call.TYPED_MAP_CALL()) - else (); end match; end retype; diff --git a/Compiler/NFFrontEnd/NFInst.mo b/Compiler/NFFrontEnd/NFInst.mo index c1edd74b2e..4e7e2d5fe4 100644 --- a/Compiler/NFFrontEnd/NFInst.mo +++ b/Compiler/NFFrontEnd/NFInst.mo @@ -3036,7 +3036,7 @@ algorithm local list> iters; - case Expression.CALL(call = Call.UNTYPED_MAP_CALL(iters = iters)) + case Expression.CALL(call = Call.UNTYPED_ARRAY_CONSTRUCTOR(iters = iters)) algorithm for iter in iters loop markStructuralParamsExp(Util.tuple22(iter)); diff --git a/Compiler/NFFrontEnd/NFModelicaBuiltin.mo b/Compiler/NFFrontEnd/NFModelicaBuiltin.mo index f21426ef94..9dadaf54d3 100644 --- a/Compiler/NFFrontEnd/NFModelicaBuiltin.mo +++ b/Compiler/NFFrontEnd/NFModelicaBuiltin.mo @@ -455,14 +455,12 @@ function cardinality "Number of connectors in connection" "),version="Deprecated"); end cardinality; -/* function array "Constructs an array" external "builtin"; annotation(Documentation(info=" See array() ")); end array; -*/ function zeros "Returns a zero array" external "builtin"; diff --git a/Compiler/NFFrontEnd/NFSimplifyExp.mo b/Compiler/NFFrontEnd/NFSimplifyExp.mo index bb9ef2cc4c..694205670a 100644 --- a/Compiler/NFFrontEnd/NFSimplifyExp.mo +++ b/Compiler/NFFrontEnd/NFSimplifyExp.mo @@ -172,7 +172,14 @@ algorithm then callExp; - case Call.TYPED_MAP_CALL() + case Call.TYPED_ARRAY_CONSTRUCTOR() + algorithm + call.exp := simplify(call.exp); + call.iters := list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in call.iters); + then + Expression.CALL(call); + + case Call.TYPED_REDUCTION() algorithm call.exp := simplify(call.exp); call.iters := list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in call.iters); diff --git a/Compiler/NFFrontEnd/NFType.mo b/Compiler/NFFrontEnd/NFType.mo index 58ea177059..51d0ab4a29 100644 --- a/Compiler/NFFrontEnd/NFType.mo +++ b/Compiler/NFFrontEnd/NFType.mo @@ -766,5 +766,12 @@ public end match; end lookupRecordFieldType; + function enumName + input Type ty; + output Absyn.Path name; + algorithm + ENUMERATION(typePath = name) := ty; + end enumName; + annotation(__OpenModelica_Interface="frontend"); end NFType; diff --git a/Compiler/NFFrontEnd/NFTyping.mo b/Compiler/NFFrontEnd/NFTyping.mo index a80e3161fd..237f09565a 100644 --- a/Compiler/NFFrontEnd/NFTyping.mo +++ b/Compiler/NFFrontEnd/NFTyping.mo @@ -1351,10 +1351,6 @@ algorithm i := i + 1; end for; - for dim in dims loop - typedSubs := Subscript.WHOLE() :: typedSubs; - end for; - typedSubs := listReverseInPlace(typedSubs); end typeSubscripts;