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

Commit 17cf378

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Initial partial function application support.
- Implemented handling of partial function applications. - Changed TypeMatch.matchExpressions to handle type checking/casting by itself instead of relying on matchTypes, since matchTypes assumes a strict actual/expected relation between the types which is not the case for matchExpressions. This could e.g. lead to inconsistent boxing/unboxing of expressions depending on which side of a binary expression a boxed expression appeared on. - Replaced all usage of intBitOr/intBitAnd for ExpOrigin flags with ExpOrigin.setFlag/flagSet. Belonging to [master]: - #2797 - OpenModelica/OpenModelica-testsuite#1080
1 parent 0fa8007 commit 17cf378

File tree

10 files changed

+568
-171
lines changed

10 files changed

+568
-171
lines changed

Compiler/NFFrontEnd/NFBuiltinCall.mo

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ protected
531531
end if;
532532

533533
// pre/change may not be used in a function context.
534-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
534+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
535535
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
536536
{ComponentRef.toString(fn_ref)}, info);
537537
end if;
@@ -570,7 +570,7 @@ protected
570570
Type ety;
571571
algorithm
572572
// der may not be used in a function context.
573-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
573+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
574574
Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, {"der"}, info);
575575
fail();
576576
end if;
@@ -659,7 +659,7 @@ protected
659659
CallAttributes ca;
660660
algorithm
661661
// edge may not be used in a function context.
662-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
662+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
663663
Error.addSourceMessage(Error.EXP_INVALID_IN_FUNCTION, {"edge"}, info);
664664
fail();
665665
end if;
@@ -950,7 +950,7 @@ protected
950950
{fn} := Function.typeRefCache(fnRef);
951951
ty := Type.liftArrayLeftList(fillType, dims);
952952

953-
if evaluated and intBitAnd(origin, ExpOrigin.FUNCTION) == 0 then
953+
if evaluated and ExpOrigin.flagNotSet(origin, ExpOrigin.FUNCTION) then
954954
callExp := Ceval.evalBuiltinFill(ty_args);
955955
else
956956
callExp := Expression.CALL(Call.makeTypedCall(NFBuiltinFuncs.FILL_FUNC, ty_args, variability, ty));
@@ -1286,7 +1286,7 @@ protected
12861286
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector) => Integer"}, info);
12871287
end if;
12881288

1289-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1289+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
12901290
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
12911291
{ComponentRef.toString(fn_ref)}, info);
12921292
end if;
@@ -1334,7 +1334,7 @@ protected
13341334
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector, Connector)"}, info);
13351335
end if;
13361336

1337-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1337+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
13381338
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
13391339
{ComponentRef.toString(fn_ref)}, info);
13401340
end if;
@@ -1373,7 +1373,7 @@ protected
13731373
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
13741374
end if;
13751375

1376-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1376+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
13771377
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
13781378
{ComponentRef.toString(fn_ref)}, info);
13791379
end if;
@@ -1421,7 +1421,7 @@ protected
14211421
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector, Integer = 0)"}, info);
14221422
end if;
14231423

1424-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1424+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
14251425
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
14261426
{ComponentRef.toString(fn_ref)}, info);
14271427
end if;
@@ -1471,7 +1471,7 @@ protected
14711471
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
14721472
end if;
14731473

1474-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1474+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
14751475
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
14761476
{ComponentRef.toString(fn_ref)}, info);
14771477
end if;
@@ -1506,7 +1506,7 @@ protected
15061506
{Call.toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
15071507
end if;
15081508

1509-
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
1509+
if ExpOrigin.flagSet(origin, ExpOrigin.FUNCTION) then
15101510
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
15111511
{ComponentRef.toString(fn_ref)}, info);
15121512
end if;
@@ -1588,7 +1588,7 @@ protected
15881588
end if;
15891589

15901590
{arg} := args;
1591-
(arg, ty, variability) := Typing.typeExp(arg, intBitOr(origin, ExpOrigin.NOEVENT), info);
1591+
(arg, ty, variability) := Typing.typeExp(arg, ExpOrigin.setFlag(origin, ExpOrigin.NOEVENT), info);
15921592

15931593
{fn} := Function.typeRefCache(fn_ref);
15941594
callExp := Expression.CALL(Call.makeTypedCall(fn, {arg}, variability, ty));

Compiler/NFFrontEnd/NFCall.mo

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,10 +1054,13 @@ protected
10541054
list<TypedArg> typedArgs;
10551055
list<TypedNamedArg> typedNamedArgs;
10561056
String name;
1057+
ExpOrigin.Type next_origin;
10571058

10581059
case UNTYPED_CALL()
10591060
algorithm
10601061
typedArgs := {};
1062+
next_origin := ExpOrigin.setFlag(origin, ExpOrigin.SUBEXPRESSION);
1063+
10611064
for arg in call.arguments loop
10621065
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info);
10631066
typedArgs := (arg, arg_ty, arg_var) :: typedArgs;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected
4848
import TypeCheck = NFTypeCheck;
4949
import ValuesUtil;
5050
import MetaModelica.Dangerous.listReverseInPlace;
51+
import Types;
5152

5253
public
5354
import Absyn.Path;
@@ -306,6 +307,13 @@ public
306307
ClockKind clk "Clock kinds";
307308
end CLKCONST;
308309

310+
record PARTIAL_FUNCTION_APPLICATION
311+
ComponentRef fn;
312+
list<Expression> args;
313+
list<String> argNames;
314+
Type ty;
315+
end PARTIAL_FUNCTION_APPLICATION;
316+
309317
function isArray
310318
input Expression exp;
311319
output Boolean isArray;
@@ -631,6 +639,17 @@ public
631639
then
632640
comp;
633641

642+
case PARTIAL_FUNCTION_APPLICATION()
643+
algorithm
644+
PARTIAL_FUNCTION_APPLICATION(fn = cr, args = expl) := exp2;
645+
comp := ComponentRef.compare(exp1.fn, cr);
646+
647+
if comp == 0 then
648+
comp := compareList(exp1.args, expl);
649+
end if;
650+
then
651+
comp;
652+
634653
else
635654
algorithm
636655
Error.assertion(false, getInstanceName() + " got unknown expression.", sourceInfo());
@@ -712,10 +731,11 @@ public
712731
case UNBOX() then exp.ty;
713732
case SUBSCRIPTED_EXP() then exp.ty;
714733
case TUPLE_ELEMENT() then exp.ty;
715-
case RECORD_ELEMENT() then exp.ty;
734+
case RECORD_ELEMENT() then exp.ty;
716735
case BOX() then Type.METABOXED(typeOf(exp.exp));
717736
case MUTABLE() then typeOf(Mutable.access(exp.exp));
718737
case EMPTY() then exp.ty;
738+
case PARTIAL_FUNCTION_APPLICATION() then exp.ty;
719739
else Type.UNKNOWN();
720740
end match;
721741
end typeOf;
@@ -742,7 +762,8 @@ public
742762
case UNBOX() algorithm exp.ty := ty; then ();
743763
case SUBSCRIPTED_EXP() algorithm exp.ty := ty; then ();
744764
case TUPLE_ELEMENT() algorithm exp.ty := ty; then ();
745-
case RECORD_ELEMENT() algorithm exp.ty := ty; then ();
765+
case RECORD_ELEMENT() algorithm exp.ty := ty; then ();
766+
case PARTIAL_FUNCTION_APPLICATION() algorithm exp.ty := ty; then ();
746767
else ();
747768
end match;
748769
end setType;
@@ -1376,6 +1397,9 @@ public
13761397
case RECORD_ELEMENT() then toString(exp.recordExp) + "[field: " + exp.fieldName + "]";
13771398
case MUTABLE() then toString(Mutable.access(exp.exp));
13781399
case EMPTY() then "#EMPTY#";
1400+
case PARTIAL_FUNCTION_APPLICATION()
1401+
then "function " + ComponentRef.toString(exp.fn) + "(" + stringDelimitList(
1402+
list(n + " = " + Expression.toString(a) threaded for a in exp.args, n in exp.argNames), ", ") + ")";
13791403

13801404
else anyString(exp);
13811405
end match;
@@ -1457,7 +1481,7 @@ public
14571481
Boolean swap;
14581482
DAE.Exp dae1, dae2;
14591483
list<String> names;
1460-
ClockKind clk;
1484+
Function.Function fn;
14611485

14621486
case INTEGER() then DAE.ICONST(exp.value);
14631487
case REAL() then DAE.RCONST(exp.value);
@@ -1466,8 +1490,8 @@ public
14661490
case ENUM_LITERAL(ty = ty as Type.ENUMERATION())
14671491
then DAE.ENUM_LITERAL(Absyn.suffixPath(ty.typePath, exp.name), exp.index);
14681492

1469-
case CLKCONST(clk)
1470-
then DAE.CLKCONST(ClockKind.toDAE(clk));
1493+
case CLKCONST()
1494+
then DAE.CLKCONST(ClockKind.toDAE(exp.clk));
14711495

14721496
case CREF()
14731497
then DAE.CREF(ComponentRef.toDAE(exp.cref), Type.toDAE(exp.ty));
@@ -1541,6 +1565,15 @@ public
15411565
case RECORD_ELEMENT()
15421566
then DAE.RSUB(toDAE(exp.recordExp), exp.index, exp.fieldName, Type.toDAE(exp.ty));
15431567

1568+
case PARTIAL_FUNCTION_APPLICATION()
1569+
algorithm
1570+
fn :: _ := Function.Function.typeRefCache(exp.fn);
1571+
then
1572+
DAE.PARTEVALFUNCTION(Function.Function.nameConsiderBuiltin(fn),
1573+
list(toDAE(arg) for arg in exp.args),
1574+
Type.toDAE(exp.ty),
1575+
Type.toDAE(Type.FUNCTION(fn, NFType.FunctionType.FUNCTIONAL_VARIABLE)));
1576+
15441577
else
15451578
algorithm
15461579
Error.assertion(false, getInstanceName() + " got unknown expression '" + toString(exp) + "'", sourceInfo());
@@ -1771,6 +1804,12 @@ public
17711804
then
17721805
exp;
17731806

1807+
case PARTIAL_FUNCTION_APPLICATION()
1808+
algorithm
1809+
exp.args := list(map(e, func) for e in exp.args);
1810+
then
1811+
exp;
1812+
17741813
else exp;
17751814
end match;
17761815

@@ -2103,6 +2142,12 @@ public
21032142
then
21042143
exp;
21052144

2145+
case PARTIAL_FUNCTION_APPLICATION()
2146+
algorithm
2147+
exp.args := list(func(e) for e in exp.args);
2148+
then
2149+
exp;
2150+
21062151
else exp;
21072152
end match;
21082153
end mapShallow;
@@ -2395,6 +2440,7 @@ public
23952440
case RECORD_ELEMENT() then fold(exp.recordExp, func, arg);
23962441
case BOX() then fold(exp.exp, func, arg);
23972442
case MUTABLE() then fold(Mutable.access(exp.exp), func, arg);
2443+
case PARTIAL_FUNCTION_APPLICATION() then foldList(exp.args, func, arg);
23982444
else arg;
23992445
end match;
24002446

@@ -2651,6 +2697,7 @@ public
26512697
case RECORD_ELEMENT() algorithm apply(exp.recordExp, func); then ();
26522698
case BOX() algorithm apply(exp.exp, func); then ();
26532699
case MUTABLE() algorithm apply(Mutable.access(exp.exp), func); then ();
2700+
case PARTIAL_FUNCTION_APPLICATION() algorithm applyList(exp.args, func); then ();
26542701
else ();
26552702
end match;
26562703

@@ -2978,6 +3025,13 @@ public
29783025
then
29793026
exp;
29803027

3028+
case PARTIAL_FUNCTION_APPLICATION()
3029+
algorithm
3030+
(expl, arg) := List.map1Fold(exp.args, mapFold, func, arg);
3031+
exp.args := expl;
3032+
then
3033+
exp;
3034+
29813035
else exp;
29823036
end match;
29833037

@@ -3297,6 +3351,13 @@ public
32973351
then
32983352
exp;
32993353

3354+
case PARTIAL_FUNCTION_APPLICATION()
3355+
algorithm
3356+
(expl, arg) := List.mapFold(exp.args, func, arg);
3357+
exp.args := expl;
3358+
then
3359+
exp;
3360+
33003361
else exp;
33013362
end match;
33023363
end mapFoldShallow;
@@ -3597,12 +3658,9 @@ public
35973658
case SUBSCRIPTED_EXP()
35983659
then contains(exp.exp, func) or Subscript.listContainsExp(exp.subscripts, func);
35993660

3600-
case TUPLE_ELEMENT()
3601-
then contains(exp.tupleExp, func);
3602-
3603-
case RECORD_ELEMENT()
3604-
then contains(exp.recordExp, func);
3605-
3661+
case TUPLE_ELEMENT() then contains(exp.tupleExp, func);
3662+
case RECORD_ELEMENT() then contains(exp.recordExp, func);
3663+
case PARTIAL_FUNCTION_APPLICATION() then listContains(exp.args, func);
36063664
case BOX() then contains(exp.exp, func);
36073665
else false;
36083666
end match;
@@ -3778,7 +3836,7 @@ public
37783836
input ExpOrigin.Type origin;
37793837
output Boolean iter;
37803838
algorithm
3781-
if intBitAnd(origin, ExpOrigin.FOR) > 0 then
3839+
if ExpOrigin.flagSet(origin, ExpOrigin.FOR) then
37823840
iter := contains(exp, isIterator);
37833841
else
37843842
iter := false;
@@ -4270,6 +4328,7 @@ public
42704328
case TUPLE_ELEMENT() then variability(exp.tupleExp);
42714329
case RECORD_ELEMENT() then variability(exp.recordExp);
42724330
case BOX() then variability(exp.exp);
4331+
case PARTIAL_FUNCTION_APPLICATION() then Variability.CONTINUOUS;
42734332
else
42744333
algorithm
42754334
Error.assertion(false, getInstanceName() + " got unknown expression.", sourceInfo());

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,14 @@ algorithm
14981498
then
14991499
();
15001500

1501+
case Expression.PARTIAL_FUNCTION_APPLICATION()
1502+
algorithm
1503+
for f in Function.getRefCache(exp.fn) loop
1504+
funcs := flattenFunction(f, funcs);
1505+
end for;
1506+
then
1507+
();
1508+
15011509
else ();
15021510
end match;
15031511
end collectExpFuncs_traverse;

0 commit comments

Comments
 (0)