Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit ef2d3b4

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Element-wise overloaded operator support.
Belonging to [master]: - #2879
1 parent 1f8adde commit ef2d3b4

File tree

3 files changed

+166
-17
lines changed

3 files changed

+166
-17
lines changed

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ public
325325
end match;
326326
end isArray;
327327

328+
function isEmptyArray
329+
input Expression exp;
330+
output Boolean emptyArray;
331+
algorithm
332+
emptyArray := match exp
333+
case ARRAY(elements = {}) then true;
334+
else false;
335+
end match;
336+
end isEmptyArray;
337+
328338
function isCref
329339
input Expression exp;
330340
output Boolean isCref;

Compiler/NFFrontEnd/NFOperator.mo

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,5 +436,32 @@ public
436436
outOp := OPERATOR(ty, o);
437437
end makeArrayScalar;
438438

439+
function stripEW
440+
input output Operator op;
441+
algorithm
442+
() := match op.op
443+
case Op.ADD_EW algorithm op.op := Op.ADD; then ();
444+
case Op.SUB_EW algorithm op.op := Op.SUB; then ();
445+
case Op.MUL_EW algorithm op.op := Op.MUL; then ();
446+
case Op.DIV_EW algorithm op.op := Op.DIV; then ();
447+
case Op.POW_EW algorithm op.op := Op.POW; then ();
448+
else ();
449+
end match;
450+
end stripEW;
451+
452+
function isElementWise
453+
input Operator op;
454+
output Boolean ew;
455+
algorithm
456+
ew := match op.op
457+
case Op.ADD_EW then true;
458+
case Op.SUB_EW then true;
459+
case Op.MUL_EW then true;
460+
case Op.DIV_EW then true;
461+
case Op.POW_EW then true;
462+
else false;
463+
end match;
464+
end isElementWise;
465+
439466
annotation(__OpenModelica_Interface="frontend");
440467
end NFOperator;

Compiler/NFFrontEnd/NFTypeCheck.mo

Lines changed: 129 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ protected
185185
list<Function> candidates;
186186
Type ety1, ety2;
187187
algorithm
188-
op_str := Operator.symbol(op,"'");
188+
op_str := Operator.symbol(Operator.stripEW(op), "'");
189189
ety1 := Type.arrayElementType(type1);
190190
ety2 := Type.arrayElementType(type2);
191191

@@ -201,7 +201,13 @@ algorithm
201201
printUnresolvableTypeError(Expression.BINARY(exp1, op, exp2), {type1, type2}, info);
202202
end if;
203203

204-
(outExp, outType) := matchOverloadedBinaryOperator(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
204+
if Operator.isElementWise(op) then
205+
(outExp, outType) := checkOverloadedBinaryArrayEW(
206+
exp1, type1, var1, Operator.stripEW(op), exp2, type2, var2, candidates, info);
207+
else
208+
(outExp, outType) := matchOverloadedBinaryOperator(
209+
exp1, type1, var1, op, exp2, type2, var2, candidates, info);
210+
end if;
205211
end checkOverloadedBinaryOperator;
206212

207213
function matchOverloadedBinaryOperator
@@ -245,20 +251,17 @@ algorithm
245251
ErrorExt.rollBack("NFTypeCheck:implicitConstruction");
246252

247253
if Type.isArray(type1) or Type.isArray(type2) then
248-
oop := op.op;
249-
250-
if oop == Op.ADD or oop == Op.SUB then
251-
(outExp, outType) :=
252-
checkOverloadedBinaryArrayAddSub(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
253-
elseif oop == Op.MUL then
254-
(outExp, outType) :=
255-
checkOverloadedBinaryArrayMul(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
256-
elseif oop == Op.DIV then
257-
(outExp, outType) :=
258-
checkOverloadedBinaryArrayDiv(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
259-
else
260-
printUnresolvableTypeError(Expression.BINARY(exp1, op, exp2), {type1, type2}, info, showErrors);
261-
end if;
254+
(outExp, outType) := match op.op
255+
case Op.ADD then checkOverloadedBinaryArrayAddSub(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
256+
case Op.SUB then checkOverloadedBinaryArrayAddSub(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
257+
case Op.MUL then checkOverloadedBinaryArrayMul(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
258+
case Op.DIV then checkOverloadedBinaryArrayDiv(exp1, type1, var1, op, exp2, type2, var2, candidates, info);
259+
else
260+
algorithm
261+
printUnresolvableTypeError(Expression.BINARY(exp1, op, exp2), {type1, type2}, info, showErrors);
262+
then
263+
fail();
264+
end match;
262265
else
263266
printUnresolvableTypeError(Expression.BINARY(exp1, op, exp2), {type1, type2}, info, showErrors);
264267
end if;
@@ -361,7 +364,7 @@ algorithm
361364
end if;
362365

363366
outType := Type.setArrayElementType(type1, ty);
364-
outExp := Expression.makeArray(outType, expl, literal = exp1.literal and exp2.literal);
367+
outExp := Expression.makeArray(outType, expl);
365368
then
366369
(outExp, outType);
367370

@@ -573,6 +576,115 @@ algorithm
573576
end if;
574577
end checkOverloadedBinaryArrayDiv;
575578

579+
function checkOverloadedBinaryArrayEW
580+
input Expression exp1;
581+
input Type type1;
582+
input Variability var1;
583+
input Operator op;
584+
input Expression exp2;
585+
input Type type2;
586+
input Variability var2;
587+
input list<Function> candidates;
588+
input SourceInfo info;
589+
output Expression outExp;
590+
output Type outType;
591+
protected
592+
Expression e1, e2;
593+
MatchKind mk;
594+
list<Expression> expl1, expl2;
595+
Type ty;
596+
algorithm
597+
if Type.isArray(type1) and Type.isArray(type2) then
598+
(e1, e2, _, mk) := matchExpressions(exp1, type1, exp2, type2, true);
599+
else
600+
(e1, e2, _, mk) := matchExpressions(exp1, Type.arrayElementType(type1),
601+
exp2, Type.arrayElementType(type2), true);
602+
end if;
603+
604+
if not isCompatibleMatch(mk) then
605+
printUnresolvableTypeError(Expression.BINARY(e1, op, e2), {type1, type2}, info);
606+
end if;
607+
608+
e1 := ExpandExp.expand(exp1);
609+
e2 := ExpandExp.expand(exp2);
610+
611+
(outExp, outType) := checkOverloadedBinaryArrayEW2(
612+
e1, type1, var1, op, e2, type2, var2, candidates, info);
613+
end checkOverloadedBinaryArrayEW;
614+
615+
function checkOverloadedBinaryArrayEW2
616+
input Expression exp1;
617+
input Type type1;
618+
input Variability var1;
619+
input Operator op;
620+
input Expression exp2;
621+
input Type type2;
622+
input Variability var2;
623+
input list<Function> candidates;
624+
input SourceInfo info;
625+
output Expression outExp;
626+
output Type outType;
627+
protected
628+
Expression e2;
629+
list<Expression> expl, expl1, expl2;
630+
Type ty, ty1, ty2;
631+
Boolean is_array1, is_array2;
632+
algorithm
633+
is_array1 := Type.isArray(type1);
634+
is_array2 := Type.isArray(type2);
635+
636+
if is_array1 or is_array2 then
637+
expl := {};
638+
639+
if Expression.isEmptyArray(exp1) or Expression.isEmptyArray(exp2) then
640+
ty1 := Type.arrayElementType(type1);
641+
ty2 := Type.arrayElementType(type2);
642+
643+
try
644+
(_, ty) := matchOverloadedBinaryOperator(
645+
Expression.EMPTY(ty1), ty1, var1, op,
646+
Expression.EMPTY(ty2), ty2, var2, candidates, info);
647+
else
648+
printUnresolvableTypeError(Expression.BINARY(exp1, op, exp2), {type1, type2}, info);
649+
end try;
650+
elseif is_array1 and is_array2 then
651+
ty1 := Type.unliftArray(type1);
652+
ty2 := Type.unliftArray(type2);
653+
expl1 := Expression.arrayElements(exp1);
654+
expl2 := Expression.arrayElements(exp2);
655+
656+
for e in expl1 loop
657+
e2 :: expl2 := expl2;
658+
(e, ty) := checkOverloadedBinaryArrayEW2(e, ty1, var1, op, e2, ty2, var2, candidates, info);
659+
expl := e :: expl;
660+
end for;
661+
elseif is_array1 then
662+
ty1 := Type.unliftArray(type1);
663+
expl1 := Expression.arrayElements(exp1);
664+
665+
for e in expl1 loop
666+
(e, ty) := checkOverloadedBinaryArrayEW2(e, ty1, var1, op, exp2, type2, var2, candidates, info);
667+
expl := e :: expl;
668+
end for;
669+
elseif is_array2 then
670+
ty2 := Type.unliftArray(type2);
671+
expl2 := Expression.arrayElements(exp2);
672+
673+
for e in expl2 loop
674+
(e, ty) := checkOverloadedBinaryArrayEW2(exp1, type1, var1, op, e, ty2, var2, candidates, info);
675+
expl := e :: expl;
676+
end for;
677+
end if;
678+
679+
outType := Type.setArrayElementType(type1, ty);
680+
outExp := Expression.makeArray(outType, listReverseInPlace(expl));
681+
else
682+
(outExp, outType) := matchOverloadedBinaryOperator(
683+
exp1, type1, var1, op,
684+
exp2, type2, var2, candidates, info);
685+
end if;
686+
end checkOverloadedBinaryArrayEW2;
687+
576688
function implicitConstructAndMatch
577689
input list<Function> candidates;
578690
input Expression inExp1;

0 commit comments

Comments
 (0)