@@ -395,6 +395,13 @@ uniontype MMExp
395395 record MM_MATCH
396396 list< MMMatchCase > matchCases;
397397 end MM_MATCH ;
398+
399+ record MM_FOR_LOOP
400+ Ident idxName;
401+ Ident arrName;
402+ Ident eltName;
403+ list< MMExp > statements;
404+ end MM_FOR_LOOP ;
398405end MMExp ;
399406
400407public type MMMatchCase = tuple< list< MatchingExp > , list< MMExp >> ;
@@ -417,6 +424,7 @@ constant Ident textToStringNamePrefix = "str_";
417424
418425constant Ident matchFunPrefix = "fun_" ;
419426constant Ident listMapFunPrefix = "lm_" ;
427+ constant Ident arrayMapFunPrefix = "am_" ;
420428constant Ident scalarMapFunPrefix = "smf_" ;
421429
422430// constant Ident implicitTxtInArgName = "inTxt";
@@ -2567,7 +2575,7 @@ algorithm
25672575 MMExp stmt, argmmexp, mmRecCall;
25682576 TypeSignature argtype, oftype;
25692577 ScopeEnv scEnv;
2570- Ident intxt, outtxt, fname, idxName, freshIdxName;
2578+ Ident intxt, outtxt, fname, idxName, freshIdxName, arrName, eltName ;
25712579 TypedIdents locals, localArgs, encodedExtargs, maplocals, caseLocals, iargs, oargs;
25722580 MapContext mapctx;
25732581 TemplPackage tplPackage;
@@ -2698,6 +2706,83 @@ algorithm
26982706 = statementsFromMapExp(false , restargs, mapctx, stmt::stmts, intxt, outtxt, locals, scEnv, tplPackage, mmFun :: accMMDecls);
26992707 then ( stmts, locals, scEnv, accMMDecls, intxt);
27002708
2709+ // Array map - elaborate the array-mapping function
2710+ case ( isfirst, (argtomap as (_,argtype,_)) :: restargs,
2711+ MAP_CONTEXT (ofBinding = ofbind,
2712+ mapExp = mapexp as (_,sinfo),
2713+ iterMMExpOptions = iopts,
2714+ hasIndexIdentOpt = hasIndexIdentOpt,
2715+ useIter = useiter),
2716+ stmts, intxt, outtxt, locals, scEnv, tplPackage as TEMPL_PACKAGE (astDefs = astDefs), accMMDecls )
2717+ equation
2718+ ARRAY_TYPE (ofType = oftype) = deAliasedType(argtype, astDefs);
2719+
2720+ ofbindEnc = typeCheckMatchingExp(ofbind, oftype, astDefs);
2721+ // ofbindEnc = encodeMatchingExp(ofbindEnc);
2722+ idxName = Util . getOptionOrDefault(hasIndexIdentOpt, impossibleIdent);
2723+ freshIdxName = indexNamePrefix + idxName;// + "_" + intString(listLength(locals));
2724+
2725+ // i0ti = ("i_i0",INTEGER_TYPE());
2726+ // i1ti = ("i_i1",INTEGER_TYPE());
2727+ // elaborate statemennts and gather extra arguments and usage of i0 and i1
2728+ (mapstmts, maplocals, scEnv, accMMDecls, _)
2729+ = statementsFromExp(mapexp,{}, {}, imlicitTxt, imlicitTxt, {},
2730+ LET_SCOPE (idxName, INTEGER_TYPE (), freshIdxName, false )
2731+ :: CASE_SCOPE (ofbindEnc, oftype, {}, {}, {}, impossibleIdent, true )
2732+ :: FUN_SCOPE ({},{})
2733+ :: scEnv,
2734+ tplPackage, accMMDecls);
2735+ (LET_SCOPE (_, _, _, isUsed)
2736+ :: CASE_SCOPE (mexp, _, localNames, caseLocals, encodedExtargs, _, _)
2737+ :: FUN_SCOPE (_,localArgs)
2738+ :: scEnv) = scEnv; // releaseImmediateLocalScope(scEnv);
2739+
2740+ (mexp,_) = rewriteMatchExpByLocalNames(mexp, oftype, localNames,{}, astDefs);
2741+ maplocals = listAppend(caseLocals, maplocals);
2742+
2743+ // put nextIter() if needed
2744+ useiter = shouldUseIterFunctions(isfirst, useiter, true , isUsed, iopts, restargs);
2745+ // add nextIter() if needed
2746+ stmt = tplStatement("nextIter" , {}, imlicitTxt, imlicitTxt);
2747+ mapstmts = if useiter then stmt :: mapstmts else mapstmts;
2748+ // (mapstmts,_) = addNextIter(useiter, mapstmts, imlicitTxt, imlicitTxt);
2749+
2750+ // create a new array-map function
2751+ fname = arrayMapFunPrefix + intString(listLength(accMMDecls));
2752+ iargs = imlicitTxtArg :: ("items" ,argtype) :: encodedExtargs;
2753+ assignedIdents = getAssignedIdents(mapstmts, {});
2754+ // oargs = List.filterOnTrue(extargs, isText);
2755+ oargs = List . filter1OnTrue(encodedExtargs, isAssignedText, assignedIdents);
2756+ oargs = imlicitTxtArg :: oargs;
2757+ mapstmts = listReverse(mapstmts);
2758+ // add indexed value if needed
2759+ (mapstmts, maplocals)
2760+ = addGetIndex(isUsed, freshIdxName, mapstmts, imlicitTxt, maplocals);
2761+
2762+ // assume the array element is the first identifier in case locals
2763+ idxName = "i" ;
2764+ arrName = "items" ;
2765+ (eltName, _) :: _ = caseLocals;
2766+
2767+ mapctx = MAP_CONTEXT (ofbind, mapexp, iopts, hasIndexIdentOpt, useiter);
2768+
2769+ // make fun
2770+ mmFun = MM_FUN (false ,fname, iargs, oargs, maplocals,
2771+ { MM_FOR_LOOP ( idxName, arrName, eltName, mapstmts ) },
2772+ GI_MAP_FUN (argtype, mapctx)
2773+ );
2774+
2775+ // add pushIter() if it is the first element of MAP_ARG_LIST (like <[exp1,exp2,...] : mapexp> ) or a simple one (list)exp to be mapped (like <exp of mexp: mapexp>)
2776+ (stmts, intxt) = addPushIter((isfirst and useiter), iopts, stmts, intxt, outtxt);
2777+ extargvals = List . map(localArgs, makeMMArgValue);
2778+ // call the elaborated function
2779+ (_, stmt, _, _, locals, intxt)
2780+ = statementFromFun(argtomap :: extargvals, IDENT (fname), iargs, oargs, {}, intxt, outtxt, locals, tplPackage, sinfo);
2781+
2782+ (stmts, locals, scEnv, accMMDecls, intxt)
2783+ = statementsFromMapExp(false , restargs, mapctx, stmt::stmts, intxt, outtxt, locals, scEnv, tplPackage, mmFun :: accMMDecls);
2784+ then ( stmts, locals, scEnv, accMMDecls, intxt);
2785+
27012786 // scalar map - <argtomap of ofbind: mapexp; iopts>
27022787 // TODO: try to inline or eliminate this at all ... design problems with mixed list/scalar arguments in { }, i.e. MAP_ARG_LIST
27032788 case ( isfirst, (argtomap as (_,argtype,_)) :: restargs,
@@ -2709,6 +2794,7 @@ algorithm
27092794 stmts, intxt, outtxt, locals, scEnv, tplPackage as TEMPL_PACKAGE (astDefs = astDefs), accMMDecls )
27102795 equation
27112796 failure(LIST_TYPE () = deAliasedType(argtype, astDefs));
2797+ failure(ARRAY_TYPE () = deAliasedType(argtype, astDefs));
27122798
27132799 ofbindEnc = typeCheckMatchingExp(ofbind, argtype, astDefs);
27142800 // ofbindEnc = encodeMatchingExp(ofbindEnc);
@@ -2790,6 +2876,31 @@ algorithm
27902876 end matchcontinue;
27912877end statementsFromMapExp;
27922878
2879+ public function intersectInOutArgs
2880+ input TypedIdents inList1;
2881+ input TypedIdents inList2;
2882+ output tuple< TypedIdents , TypedIdents , TypedIdents > outIntersectionAndRests;
2883+ function areTypedIdentsEqual
2884+ input tuple< Ident , TypeSignature > inTypedIdent1;
2885+ input tuple< Ident , TypeSignature > inTypedIdent2;
2886+ output Boolean equal;
2887+ protected
2888+ Ident ident1;
2889+ Ident ident2;
2890+ algorithm
2891+ (ident1, _) := inTypedIdent1;
2892+ (ident2, _) := inTypedIdent2;
2893+ equal := stringEq(ident1, ident2);
2894+ end areTypedIdentsEqual;
2895+ protected
2896+ TypedIdents outIntersection;
2897+ TypedIdents outList1Rest;
2898+ TypedIdents outList2Rest;
2899+ algorithm
2900+ (outIntersection, outList1Rest, outList2Rest) := List . intersection1OnTrue(inList1, inList2, areTypedIdentsEqual);
2901+ outIntersectionAndRests := (outIntersection, outList1Rest, outList2Rest);
2902+ end intersectInOutArgs;
2903+
27932904/*
27942905function isIndexArg
27952906 input tuple<Ident, TypeSignature> inArg;
0 commit comments