@@ -34,6 +34,7 @@ encapsulated uniontype NFExpandExp
3434
3535protected
3636 import RangeIterator = NFRangeIterator ;
37+ import ExpressionIterator = NFExpressionIterator ;
3738 import Subscript = NFSubscript ;
3839 import Type = NFType ;
3940 import NFCall.Call ;
@@ -42,6 +43,9 @@ protected
4243 import NFFunction.Function ;
4344 import Operator = NFOperator ;
4445 import Ceval = NFCeval ;
46+ import NFInstNode.InstNode ;
47+ import SimplifyExp = NFSimplifyExp ;
48+ import MetaModelica.Dangerous.* ;
4549
4650public
4751 function expand
@@ -173,6 +177,9 @@ protected
173177 guard Function . isBuiltin(call. fn) and not Function . isImpure(call. fn)
174178 then expandBuiltinCall(call. fn, call. arguments);
175179
180+ case Call . TYPED_MAP_CALL ()
181+ then expandReduction(call. exp, call. ty, call. iters);
182+
176183 else expandGeneric(exp);
177184 end matchcontinue;
178185 end expandCall;
@@ -214,6 +221,67 @@ protected
214221 exp := Expression . promote(eexp, Expression . typeOf(eexp), n);
215222 end expandBuiltinPromote;
216223
224+ function expandReduction
225+ input Expression exp;
226+ input Type ty;
227+ input list< tuple< InstNode , Expression >> iterators;
228+ output Expression result;
229+ protected
230+ Expression e = exp, range;
231+ InstNode node;
232+ list< Expression > ranges = {}, expl;
233+ Mutable < Expression > iter;
234+ list< Mutable < Expression >> iters = {};
235+ algorithm
236+ for i in iterators loop
237+ (node, range) := i;
238+ iter := Mutable . create(Expression . INTEGER (0 ));
239+ e := Expression . replaceIterator(e, node, Expression . MUTABLE (iter));
240+ iters := iter :: iters;
241+ ranges := expand(range) :: ranges;
242+ end for ;
243+
244+ result := expandReduction2(e, ty, ranges, iters);
245+ end expandReduction;
246+
247+ function expandReduction2
248+ input Expression exp;
249+ input Type ty;
250+ input list< Expression > ranges;
251+ input list< Mutable < Expression >> iterators;
252+ output Expression result;
253+ protected
254+ Expression range;
255+ list< Expression > ranges_rest, expl = {};
256+ Mutable < Expression > iter;
257+ list< Mutable < Expression >> iters_rest;
258+ ExpressionIterator range_iter;
259+ Expression value;
260+ Type el_ty;
261+ algorithm
262+ if listEmpty(ranges) then
263+ // Normally it wouldn't be the expansion's task to simplify expressions,
264+ // but we make an exception here since the generated expressions contain
265+ // MUTABLE expressions that we need to get rid of. Also, expansion of
266+ // reductions is often done during the scalarization phase, after the
267+ // simplification phase, so they wouldn't otherwise be simplified.
268+ result := expand(SimplifyExp . simplify(exp));
269+ else
270+ range :: ranges_rest := ranges;
271+ iter :: iters_rest := iterators;
272+ range_iter := ExpressionIterator . fromExp(range);
273+ el_ty := Type . unliftArray(ty);
274+
275+ while ExpressionIterator . hasNext(range_iter) loop
276+ (range_iter, value) := ExpressionIterator . next(range_iter);
277+ Mutable . update(iter, value);
278+ expl := expandReduction2(exp, el_ty, ranges_rest, iters_rest) :: expl;
279+ end while ;
280+
281+ result := Expression . ARRAY (ty, listReverseInPlace(expl));
282+ end if ;
283+ end expandReduction2;
284+
217285 function expandBinary
218286 input Expression exp1;
219287 input Operator op;
0 commit comments