Skip to content

Commit

Permalink
Improve getInstanceName (#11602)
Browse files Browse the repository at this point in the history
- Evaluate getInstanceName during the flattening instead of during the
  typing, so that subscripts are included in the name.

Fixes #11600
  • Loading branch information
perost committed Nov 17, 2023
1 parent 6185468 commit 8fef40a
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 11 deletions.
14 changes: 12 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFBuiltinCall.mo
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public
case "DynamicSelect" then typeDynamicSelectCall("DynamicSelect", call, next_context, info);
case "edge" then typeEdgeCall(call, next_context, info);
case "fill" then typeFillCall(call, next_context, info);
case "getInstanceName" then typeGetInstanceName(call);
case "getInstanceName" then typeGetInstanceName(call, next_context, info);
//case "initialState" then typeInitialStateCall(call, next_context, info);
case "initial" then typeDiscreteCall(call, next_context, info);
case "inStream" then typeActualInStreamCall("inStream", call, next_context, info);
Expand Down Expand Up @@ -1841,15 +1841,25 @@ protected

function typeGetInstanceName
input Call call;
input InstContext.Type context;
input SourceInfo info;
output Expression result;
output Type ty = Type.STRING();
output Variability var = Variability.CONSTANT;
output Purity purity = Purity.PURE;
protected
InstNode scope;
Call ty_call;
algorithm
Call.UNTYPED_CALL(call_scope = scope) := call;
result := Expression.STRING(AbsynUtil.pathString(InstNode.rootPath(scope)));
ty_call := Call.typeMatchNormalCall(call, context, info);
// getInstanceName is normally derived from the prefix during the flattening,
// but sometimes the call is constant evaluated instead (e.g. when it's used
// in a package). So we add the scope as an argument here to have it
// available later if needed.
ty_call := Call.setArguments(ty_call,
{Expression.fromCref(ComponentRef.fromNode(scope, Type.UNKNOWN()))});
result := Expression.CALL(ty_call);
end typeGetInstanceName;

function typeClockCall
Expand Down
14 changes: 14 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFCeval.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,7 @@ algorithm
case "realClock" then evalRealClock(args);
case "booleanClock" then evalBooleanClock(args);
case "solverClock" then evalSolverClock(args);
case "getInstanceName" then evalGetInstanceName(listHead(args));
else
algorithm
Error.addInternalError(getInstanceName() + ": unimplemented case for " +
Expand Down Expand Up @@ -3072,6 +3073,19 @@ algorithm
end match;
end evalSolverClock;

function evalGetInstanceName
input Expression scopeArg;
output Expression result;
protected
ComponentRef cref;
algorithm
// getInstanceName is normally evaluated by the flattening, but we might get
// here when getInstanceName is used in e.g. a package. In that case use the
// scope that was added as an argument during the typing.
cref := Expression.toCref(scopeArg);
result := Expression.STRING(AbsynUtil.pathString(InstNode.rootPath(ComponentRef.node(cref))));
end evalGetInstanceName;

function evalArrayConstructor
input Expression callExp;
output Expression result;
Expand Down
4 changes: 2 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ algorithm
eexp := Ceval.evalExp(exp, Ceval.EvalTarget.ATTRIBUTE(binding));
end if;

eexp := Flatten.flattenExp(eexp, Flatten.PREFIX(prefix));
eexp := Flatten.flattenExp(eexp, Flatten.PREFIX(InstNode.EMPTY_NODE(), prefix));
else
info := Binding.getInfo(binding);
eexp := evaluateExp(exp, info);
Expand Down Expand Up @@ -204,7 +204,7 @@ algorithm
not Type.isExternalObject(ty) then
// Evaluate all constants and structural parameters.
outExp := Ceval.evalCref(cref, outExp, Ceval.EvalTarget.IGNORE_ERRORS(), evalSubscripts = false);
outExp := Flatten.flattenExp(outExp, Flatten.Prefix.PREFIX(cref));
outExp := Flatten.flattenExp(outExp, Flatten.Prefix.PREFIX(InstNode.EMPTY_NODE(), cref));
outChanged := true;
elseif outChanged then
ty := ComponentRef.getSubscriptedType(cref);
Expand Down
49 changes: 43 additions & 6 deletions OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,26 @@ end FlattenSettings;

uniontype Prefix
record PREFIX
InstNode root;
ComponentRef prefix;
end PREFIX;

record INDEXED_PREFIX
InstNode root;
ComponentRef prefix;
ComponentRef indexedPrefix;
end INDEXED_PREFIX;

function new
input InstNode root;
input Boolean indexed = false;
output Prefix prefix;
algorithm
prefix := if indexed then
INDEXED_PREFIX(root, ComponentRef.EMPTY(), ComponentRef.EMPTY()) else
PREFIX(root, ComponentRef.EMPTY());
end new;

function isEmpty
input Prefix prefix;
output Boolean empty;
Expand Down Expand Up @@ -237,7 +249,7 @@ uniontype Prefix
algorithm
prefix := match prefix
case PREFIX() then prefix;
case INDEXED_PREFIX() then PREFIX(prefix.prefix);
case INDEXED_PREFIX() then PREFIX(prefix.root, prefix.prefix);
end match;
end toNonIndexedPrefix;

Expand Down Expand Up @@ -271,10 +283,31 @@ uniontype Prefix
input Prefix pre;
output String str = ComponentRef.toString(prefix(pre));
end toString;

function rootNode
input Prefix pre;
output InstNode node;
algorithm
node := match pre
case PREFIX() then pre.root;
case INDEXED_PREFIX() then pre.root;
end match;
end rootNode;

function instanceName
input Prefix pre;
output String str;
algorithm
str := InstNode.name(rootNode(pre));

if not ComponentRef.isEmpty(indexedPrefix(pre)) then
str := str + "." + toString(pre);
end if;
end instanceName;
end Prefix;

constant Prefix EMPTY_PREFIX = Prefix.PREFIX(ComponentRef.EMPTY());
constant Prefix EMPTY_INDEXED_PREFIX = Prefix.INDEXED_PREFIX(ComponentRef.EMPTY(), ComponentRef.EMPTY());
constant Prefix EMPTY_PREFIX = Prefix.PREFIX(InstNode.EMPTY_NODE(), ComponentRef.EMPTY());
constant Prefix EMPTY_INDEXED_PREFIX = Prefix.INDEXED_PREFIX(InstNode.EMPTY_NODE(), ComponentRef.EMPTY(), ComponentRef.EMPTY());

function flatten
input InstNode classInst;
Expand All @@ -300,7 +333,7 @@ algorithm
Flags.isSet(Flags.VECTORIZE_BINDINGS)
);

prefix := if settings.vectorizeBindings then EMPTY_INDEXED_PREFIX else EMPTY_PREFIX;
prefix := Prefix.new(classInst, indexed = settings.vectorizeBindings);

sections := Sections.EMPTY();
src := ElementSource.createElementSource(InstNode.info(classInst));
Expand Down Expand Up @@ -654,7 +687,7 @@ algorithm
ty := flattenType(ty, prefix);
verifyDimensions(Type.arrayDims(ty), comp_node);
pre := Prefix.push(comp_node, ty, Type.arrayDims(ty), prefix);
ty_attrs := list(flattenTypeAttribute(m, pre) for m in typeAttrs);
ty_attrs := list(flattenTypeAttribute(m, prefix) for m in typeAttrs);

// Set fixed = false for parameters that are part of a record instance whose
// binding couldn't be split and was moved to an initial equation.
Expand Down Expand Up @@ -878,7 +911,7 @@ algorithm
for i in arrayLength(comps):-1:1 loop
ty := InstNode.getType(comps[i]);
field_cr := ComponentRef.prefixCref(comps[i], ty, {}, cr);
field_cr := flattenCref(field_cr, Prefix.PREFIX(cr));
field_cr := flattenCref(field_cr, Prefix.PREFIX(InstNode.EMPTY_NODE(), cr));
fields := Expression.fromCref(field_cr) :: fields;
end for;
then
Expand Down Expand Up @@ -1394,6 +1427,10 @@ algorithm
flattenConditionalArrayIfExp(exp),
function flattenExp(prefix = prefix));

case Expression.CALL()
guard Call.isNamed(exp.call, "getInstanceName")
then Expression.STRING(Prefix.instanceName(prefix));

else Expression.mapShallow(exp, function flattenExp(prefix = prefix));
end match;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ end BuiltinAttribute23;
// Result:
// class BuiltinAttribute23
// parameter Real x0;
// Real[3] t(start = array(x0 for $t1 in 1:3));
// Real[3] t(start = array(x0 for $i1 in 1:3));
// end BuiltinAttribute23;
// endResult
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ model FuncBuiltinGetInstanceName

String s = getInstanceName();
A a;
A a1[2];
C c;
C c2[1, 2];
String ps = P.s;
String pas = P.a.s;
constant String fs = f();
Expand All @@ -43,8 +45,16 @@ end FuncBuiltinGetInstanceName;
// String s = "FuncBuiltinGetInstanceName";
// String a.b.s = "FuncBuiltinGetInstanceName.a.b";
// String a.s = "FuncBuiltinGetInstanceName.a";
// String a1[1].b.s = "FuncBuiltinGetInstanceName.a1[1].b";
// String a1[1].s = "FuncBuiltinGetInstanceName.a1[1]";
// String a1[2].b.s = "FuncBuiltinGetInstanceName.a1[2].b";
// String a1[2].s = "FuncBuiltinGetInstanceName.a1[2]";
// String c.b.s = "FuncBuiltinGetInstanceName.c.b";
// String c.s = "FuncBuiltinGetInstanceName.c";
// String c2[1,1].b.s = "FuncBuiltinGetInstanceName.c2[1, 1].b";
// String c2[1,1].s = "FuncBuiltinGetInstanceName.c2[1, 1]";
// String c2[1,2].b.s = "FuncBuiltinGetInstanceName.c2[1, 2].b";
// String c2[1,2].s = "FuncBuiltinGetInstanceName.c2[1, 2]";
// String ps = "P";
// String pas = "P.a";
// constant String fs = "FuncBuiltinGetInstanceName.f";
Expand Down

0 comments on commit 8fef40a

Please sign in to comment.