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

Commit 6609484

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Function improvements/cleanup.
- Refactored handling of builtin functions with special rules into a new package NFBuiltinCall. - Cleaned up NFCall a bit. - Removed default variability argument from BuiltinCall.makeCall and fixed all calls to it to give the actual variability instead of just setting it to constant. - Implemented some basic handling of functional formal parameters. - Fixed handling of String function so that it doesn't fail without error for a non-basic argument without a 'String' overload. Belonging to [master]: - #2481 - OpenModelica/OpenModelica-testsuite#966
1 parent 6f42885 commit 6609484

File tree

12 files changed

+2450
-2355
lines changed

12 files changed

+2450
-2355
lines changed

Compiler/NFFrontEnd/NFBuiltinCall.mo

Lines changed: 1516 additions & 0 deletions
Large diffs are not rendered by default.

Compiler/NFFrontEnd/NFCall.mo

Lines changed: 735 additions & 2266 deletions
Large diffs are not rendered by default.

Compiler/NFFrontEnd/NFConnectEquations.mo

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import NFClass.Class;
6161
import NFBinding.Binding;
6262
import NFFunction.Function;
6363
import Global;
64+
import BuiltinCall = NFBuiltinCall;
6465

6566
constant Expression EQ_ASSERT_STR =
6667
Expression.STRING("Connected constants/parameters must be equal");
@@ -209,7 +210,7 @@ algorithm
209210
// Modelica doesn't allow == for Reals, so to keep the flat Modelica
210211
// somewhat valid we use 'abs(lhs - rhs) <= 0' instead.
211212
exp := Expression.BINARY(lhs_exp, Operator.makeSub(ty), rhs_exp);
212-
exp := Expression.CALL(Call.makeBuiltinCall(NFBuiltinFuncs.ABS_REAL, {exp}));
213+
exp := Expression.CALL(BuiltinCall.makeCall(NFBuiltinFuncs.ABS_REAL, {exp}, Expression.variability(exp)));
213214
exp := Expression.RELATION(exp, Operator.makeLessEq(ty), Expression.REAL(0.0));
214215
else
215216
// For any other type, generate assertion for 'lhs == rhs'.
@@ -295,6 +296,7 @@ algorithm
295296
DAE.ElementSource src, src1, src2;
296297
Expression cref1, cref2, e1, e2;
297298
list<Connector> inside, outside;
299+
Variability var1, var2;
298300

299301
// Unconnected stream connector, do nothing.
300302
case ({Connector.CONNECTOR(face = Face.INSIDE)}) then {};
@@ -508,7 +510,8 @@ function makeInStreamCall
508510
output Expression inStreamCall;
509511
annotation(__OpenModelica_EarlyInline = true);
510512
algorithm
511-
inStreamCall := Expression.CALL(Call.makeBuiltinCall(NFBuiltinFuncs.IN_STREAM, {streamExp}));
513+
inStreamCall := Expression.CALL(BuiltinCall.makeCall(
514+
NFBuiltinFuncs.IN_STREAM, {streamExp}, Expression.variability(streamExp)));
512515
end makeInStreamCall;
513516

514517
function makePositiveMaxCall
@@ -532,8 +535,8 @@ algorithm
532535
flow_threshold := flowThreshold;
533536
end if;
534537

535-
positiveMaxCall := Expression.CALL(Call.makeBuiltinCall(NFBuiltinFuncs.POSITIVE_MAX_REAL,
536-
{flowExp, flow_threshold}));
538+
positiveMaxCall := Expression.CALL(BuiltinCall.makeCall(NFBuiltinFuncs.POSITIVE_MAX_REAL,
539+
{flowExp, flow_threshold}, Connector.variability(element)));
537540

538541
setGlobalRoot(Global.isInStream, SOME(true));
539542
end makePositiveMaxCall;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ protected
3636
import List;
3737

3838
import Builtin = NFBuiltin;
39+
import BuiltinCall = NFBuiltinCall;
3940
import Expression = NFExpression;
4041
import Function = NFFunction;
4142
import RangeIterator = NFRangeIterator;
@@ -3104,7 +3105,8 @@ public
31043105
// An expression with array type, but which is not an array expression.
31053106
// Such an expression can't be promoted here, so we create a promote call instead.
31063107
case (_, _) guard isArray
3107-
then CALL(Call.makeBuiltinCall2(NFBuiltinFuncs.PROMOTE, {exp, INTEGER(dims)}, listHead(types)));
3108+
then CALL(BuiltinCall.makeCall2(
3109+
NFBuiltinFuncs.PROMOTE, {exp, INTEGER(dims)}, listHead(types), variability(exp)));
31083110

31093111
// A scalar expression, promote it as many times as the number of types given.
31103112
else
@@ -3262,7 +3264,7 @@ public
32623264
algorithm
32633265
indexExp := match enumExp
32643266
case ENUM_LITERAL() then INTEGER(enumExp.index);
3265-
else CALL(Call.makeBuiltinCall(
3267+
else CALL(BuiltinCall.makeCall(
32663268
NFBuiltinFuncs.INTEGER_ENUM, {enumExp}, variability(enumExp)));
32673269
end match;
32683270
end enumIndexExp;

Compiler/NFFrontEnd/NFFunction.mo

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ uniontype Function
295295
CachedData cache;
296296
algorithm
297297
// Look up the function.
298-
fn_node := ComponentRef.node(fn_ref);
298+
fn_node := InstNode.classScope(ComponentRef.node(fn_ref));
299299
cache := InstNode.getFuncCache(fn_node);
300300

301301
// Check if a cached instantiation of this function already exists.
@@ -408,7 +408,7 @@ uniontype Function
408408
protected
409409
CachedData cache;
410410
algorithm
411-
cache := InstNode.getFuncCache(inNode);
411+
cache := InstNode.getFuncCache(InstNode.classScope(inNode));
412412
outFuncs := match cache
413413
case CachedData.FUNCTION() then cache.funcs;
414414
else fail();
@@ -509,6 +509,11 @@ uniontype Function
509509
str := Absyn.pathString(fn_name) + "(" + input_str + ")" + output_str;
510510
end signatureString;
511511

512+
function candidateFuncListString
513+
input list<Function> fns;
514+
output String s = stringDelimitList(list(Function.signatureString(fn, true) for fn in fns), "\n ");
515+
end candidateFuncListString;
516+
512517
function callString
513518
"Constructs a string representing a call, for use in error messages."
514519
input Function fn;
@@ -942,6 +947,40 @@ uniontype Function
942947
end match;
943948
end isTyped;
944949

950+
function typeRefCache
951+
"Returns the function(s) referenced by the given cref, and types them if
952+
they are not already typed."
953+
input ComponentRef functionRef;
954+
output list<Function> functions;
955+
protected
956+
InstNode fn_node;
957+
Boolean typed, special;
958+
String name;
959+
algorithm
960+
functions := match functionRef
961+
case ComponentRef.CREF(node = fn_node)
962+
algorithm
963+
fn_node := InstNode.classScope(fn_node);
964+
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);
965+
966+
// Type the function(s) if not already done.
967+
if not typed then
968+
functions := list(typeFunctionSignature(f) for f in functions);
969+
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
970+
functions := list(typeFunctionBody(f) for f in functions);
971+
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
972+
end if;
973+
then
974+
functions;
975+
976+
else
977+
algorithm
978+
Error.assertion(false, getInstanceName() + " got invalid function call reference", sourceInfo());
979+
then
980+
fail();
981+
end match;
982+
end typeRefCache;
983+
945984
function typeFunction
946985
input output Function fn;
947986
algorithm

Compiler/NFFrontEnd/NFInst.mo

Lines changed: 101 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ algorithm
13181318
Component inst_comp;
13191319
InstNode ty_node;
13201320
Class ty;
1321-
Boolean use_binding;
1321+
Boolean use_binding, in_function;
13221322

13231323
case SCode.COMPONENT(info = info)
13241324
algorithm
@@ -1340,7 +1340,8 @@ algorithm
13401340
// Instantiate the component's attributes, and merge them with the
13411341
// attributes of the component's parent (e.g. constant SomeComplexClass c).
13421342
attr := instComponentAttributes(component.attributes, component.prefixes);
1343-
attr := mergeComponentAttributes(attributes, attr, node);
1343+
attr := mergeComponentAttributes(attributes, attr, node,
1344+
Class.isFunction(InstNode.getClass(parent)));
13441345

13451346
// Create the untyped component and update the node with it. We need the
13461347
// untyped component in instClass to make sure everything is scoped
@@ -1495,6 +1496,7 @@ function mergeComponentAttributes
14951496
input Component.Attributes outerAttr;
14961497
input Component.Attributes innerAttr;
14971498
input InstNode node;
1499+
input Boolean inFunction;
14981500
output Component.Attributes attr;
14991501
protected
15001502
ConnectorType cty;
@@ -1513,7 +1515,13 @@ algorithm
15131515
cty := Prefixes.mergeConnectorType(outerAttr.connectorType, innerAttr.connectorType, node);
15141516
par := Prefixes.mergeParallelism(outerAttr.parallelism, innerAttr.parallelism, node);
15151517
var := Prefixes.variabilityMin(outerAttr.variability, innerAttr.variability);
1516-
dir := Prefixes.mergeDirection(outerAttr.direction, innerAttr.direction, node);
1518+
1519+
if inFunction then
1520+
dir := innerAttr.direction;
1521+
else
1522+
dir := Prefixes.mergeDirection(outerAttr.direction, innerAttr.direction, node);
1523+
end if;
1524+
15171525
fin := outerAttr.isFinal or innerAttr.isFinal;
15181526
redecl := innerAttr.isRedeclare;
15191527
repl := innerAttr.isReplaceable;
@@ -2140,72 +2148,112 @@ algorithm
21402148

21412149
crefExp := match cref
21422150
case ComponentRef.CREF()
2151+
then
2152+
match cref.node
2153+
case InstNode.COMPONENT_NODE()
2154+
then instCrefComponent(cref, cref.node, found_scope, info);
2155+
case InstNode.CLASS_NODE()
2156+
then if Class.isFunction(InstNode.getClass(cref.node)) then
2157+
instCrefFunction(cref, info)
2158+
else
2159+
instCrefTypename(cref, cref.node, info);
2160+
else
2161+
algorithm
2162+
Error.assertion(false, getInstanceName() + " got invalid instance node", sourceInfo());
2163+
then
2164+
fail();
2165+
end match;
2166+
2167+
else Expression.CREF(Type.UNKNOWN(), cref);
2168+
end match;
2169+
end instCref;
2170+
2171+
function instCrefComponent
2172+
input ComponentRef cref;
2173+
input InstNode node;
2174+
input InstNode scope;
2175+
input SourceInfo info;
2176+
output Expression crefExp;
2177+
protected
2178+
Component comp;
2179+
ComponentRef prefixed_cref;
2180+
algorithm
2181+
comp := InstNode.component(node);
2182+
2183+
crefExp := match comp
2184+
case Component.ITERATOR()
21432185
algorithm
2144-
if InstNode.isComponent(cref.node) then
2145-
comp := InstNode.component(cref.node);
2186+
checkUnsubscriptableCref(cref, info);
2187+
then
2188+
Expression.CREF(Type.UNKNOWN(), ComponentRef.makeIterator(node, comp.ty));
21462189

2147-
crefExp := match comp
2148-
case Component.ITERATOR()
2149-
algorithm
2150-
checkUnsubscriptableCref(cref, cref.subscripts, info);
2151-
then
2152-
Expression.CREF(Type.UNKNOWN(), ComponentRef.makeIterator(cref.node, comp.ty));
2190+
case Component.ENUM_LITERAL()
2191+
algorithm
2192+
checkUnsubscriptableCref(cref, info);
2193+
then
2194+
comp.literal;
21532195

2154-
case Component.ENUM_LITERAL()
2155-
algorithm
2156-
checkUnsubscriptableCref(cref, cref.subscripts, info);
2157-
then
2158-
comp.literal;
2196+
case Component.TYPE_ATTRIBUTE()
2197+
algorithm
2198+
Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR,
2199+
{InstNode.name(node), InstNode.name(InstNode.parent(node))}, info);
2200+
then
2201+
fail();
21592202

2160-
case Component.TYPE_ATTRIBUTE()
2161-
algorithm
2162-
Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR,
2163-
{Dump.printComponentRefStr(absynCref), InstNode.name(scope)}, info);
2164-
then
2165-
fail();
2203+
else
2204+
algorithm
2205+
prefixed_cref := ComponentRef.fromNodeList(InstNode.scopeList(scope));
2206+
prefixed_cref := if ComponentRef.isEmpty(prefixed_cref) then
2207+
cref else ComponentRef.append(cref, prefixed_cref);
2208+
then
2209+
Expression.CREF(Type.UNKNOWN(), prefixed_cref);
21662210

2167-
else
2168-
algorithm
2169-
prefixed_cref := ComponentRef.fromNodeList(InstNode.scopeList(found_scope));
2170-
prefixed_cref := if ComponentRef.isEmpty(prefixed_cref) then
2171-
cref else ComponentRef.append(cref, prefixed_cref);
2172-
then
2173-
Expression.CREF(Type.UNKNOWN(), prefixed_cref);
2211+
end match;
2212+
end instCrefComponent;
21742213

2175-
end match;
2176-
else
2177-
checkUnsubscriptableCref(cref, cref.subscripts, info);
2178-
ty := InstNode.getType(cref.node);
2214+
function instCrefFunction
2215+
input ComponentRef cref;
2216+
input SourceInfo info;
2217+
output Expression crefExp;
2218+
protected
2219+
ComponentRef fn_ref;
2220+
algorithm
2221+
fn_ref := Function.instFuncRef(cref, info);
2222+
crefExp := Expression.CREF(Type.UNKNOWN(), fn_ref);
2223+
end instCrefFunction;
21792224

2180-
ty := match ty
2181-
case Type.BOOLEAN() then Type.ARRAY(ty, {Dimension.BOOLEAN()});
2182-
case Type.ENUMERATION() then Type.ARRAY(ty, {Dimension.ENUM(ty)});
2183-
else
2184-
algorithm
2185-
// This should be caught by lookupComponent, only type name classes
2186-
// are allowed to be used where a component is expected.
2187-
Error.assertion(false, getInstanceName() + " got unknown class node", sourceInfo());
2188-
then
2189-
fail();
2190-
end match;
2225+
function instCrefTypename
2226+
input ComponentRef cref;
2227+
input InstNode node;
2228+
input SourceInfo info;
2229+
output Expression crefExp;
2230+
protected
2231+
Type ty;
2232+
algorithm
2233+
checkUnsubscriptableCref(cref, info);
2234+
ty := InstNode.getType(node);
21912235

2192-
crefExp := Expression.TYPENAME(ty);
2193-
end if;
2236+
ty := match ty
2237+
case Type.BOOLEAN() then Type.ARRAY(ty, {Dimension.BOOLEAN()});
2238+
case Type.ENUMERATION() then Type.ARRAY(ty, {Dimension.ENUM(ty)});
2239+
else
2240+
algorithm
2241+
Error.assertion(false, getInstanceName() + " got unknown class node " +
2242+
InstNode.name(node), sourceInfo());
21942243
then
2195-
crefExp;
2196-
2197-
else Expression.CREF(Type.UNKNOWN(), cref);
2244+
fail();
21982245
end match;
2199-
end instCref;
2246+
2247+
crefExp := Expression.TYPENAME(ty);
2248+
end instCrefTypename;
22002249

22012250
function checkUnsubscriptableCref
22022251
input ComponentRef cref;
2203-
input list<Subscript> subscripts;
22042252
input SourceInfo info;
22052253
algorithm
2206-
if not listEmpty(subscripts) then
2254+
if ComponentRef.hasSubscripts(cref) then
22072255
Error.addSourceMessage(Error.WRONG_NUMBER_OF_SUBSCRIPTS,
2208-
{ComponentRef.toString(cref), String(listLength(subscripts)), "0"}, info);
2256+
{ComponentRef.toString(cref), String(listLength(ComponentRef.getSubscripts(cref))), "0"}, info);
22092257
fail();
22102258
end if;
22112259
end checkUnsubscriptableCref;

0 commit comments

Comments
 (0)