Skip to content

Commit 5ef4a70

Browse files
Implement array traversal with Susan map operator (#12648)
1 parent d54c72f commit 5ef4a70

File tree

3 files changed

+178
-1
lines changed

3 files changed

+178
-1
lines changed

OMCompiler/Compiler/Template/TplAbsyn.mo

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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;
398405
end MMExp;
399406

400407
public type MMMatchCase = tuple<list<MatchingExp>, list<MMExp>>;
@@ -417,6 +424,7 @@ constant Ident textToStringNamePrefix = "str_";
417424

418425
constant Ident matchFunPrefix = "fun_";
419426
constant Ident listMapFunPrefix = "lm_";
427+
constant Ident arrayMapFunPrefix = "am_";
420428
constant 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;
27912877
end 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
/*
27942905
function isIndexArg
27952906
input tuple<Ident, TypeSignature> inArg;

OMCompiler/Compiler/susan_codegen/TplCodegen.tpl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ template mmDeclaration(MMDeclaration it) ::=
4848
<%match statements
4949
case {c as MM_MATCH(__)} then //match function
5050
mmMatchFunBody(mf.inArgs, mf.outArgs, mf.locals, c.matchCases)
51+
case {c as MM_FOR_LOOP(__)} then //for-loop function
52+
mmForLoopFunBody(mf.inArgs, mf.outArgs, mf.locals, c.idxName, c.arrName, c.eltName, c.statements)
5153
case sts then //simple assignment functions
5254
<<
5355
<%typedIdentsEx(mf.inArgs, "input", "")%>
@@ -119,6 +121,57 @@ end try;
119121
>>
120122
end mmMatchFunBody;
121123

124+
template mmForLoopFunBody(TypedIdents inArgs, TypedIdents outArgs, TypedIdents locals, Ident idxName, Ident arrName, Ident eltName, list<MMExp> statements) ::=
125+
<<
126+
<%inOutArgs(inArgs, outArgs)%>
127+
<%if locals then <<
128+
protected
129+
<%typedIdents(locals)%>
130+
>>%>
131+
algorithm<% if debugSusan() then
132+
<<
133+
134+
try
135+
>>
136+
%>
137+
for <%idxName%> in 1:arrayLength(<%arrName%>) loop
138+
<%eltName%> := arrayGet(<%arrName%>, <%idxName%>);
139+
<%statements |> it => '<%mmExp(it, ":=")%>;' ;separator="\n"%>
140+
end for;<% if debugSusan() then
141+
<<
142+
143+
else
144+
Tpl.fakeStackOverflow();
145+
end try;
146+
>>
147+
%>
148+
>>
149+
end mmForLoopFunBody;
150+
151+
template inOutArgs(TypedIdents inArgs, TypedIdents outArgs) ::=
152+
match intersectInOutArgs(inArgs, outArgs)
153+
case (inOut, in, out) then
154+
<<
155+
<%if inOut then <<
156+
<%typedIdentsEx(inOut, "input output", "")%>
157+
<%if in then <<
158+
159+
>> else if out then <<
160+
161+
>>%>
162+
>>%>
163+
<%if in then <<
164+
<%typedIdentsEx(in, "input", "")%>
165+
<%if out then <<
166+
167+
>>%>
168+
>>%>
169+
<%if out then <<
170+
<%typedIdentsEx(out, "output", "")%>
171+
>>%>
172+
>>
173+
end inOutArgs;
174+
122175
template pathIdent(PathIdent path) ::=
123176
match path
124177
case IDENT(__) then ident

OMCompiler/Compiler/susan_codegen/TplCodegenTV.mo

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ package TplAbsyn
202202
record MM_MATCH
203203
list<MMMatchCase> matchCases;
204204
end MM_MATCH;
205+
206+
record MM_FOR_LOOP
207+
Ident idxName;
208+
Ident arrName;
209+
Ident eltName;
210+
list<MMExp> statements;
211+
end MM_FOR_LOOP;
205212
end MMExp;
206213

207214
// **** types for dumping purposes ... i.e. Susan input AST
@@ -350,6 +357,12 @@ package TplAbsyn
350357
end TEMPLATE_DEF;
351358
end TemplateDef;
352359

360+
function intersectInOutArgs
361+
input TypedIdents inList1;
362+
input TypedIdents inList2;
363+
output tuple<TypedIdents, TypedIdents, TypedIdents> outIntersectionAndRests;
364+
end intersectInOutArgs;
365+
353366
end TplAbsyn;
354367

355368
end TplCodegenTV;

0 commit comments

Comments
 (0)