Skip to content

Commit

Permalink
Add setElementType API (OpenModelica#12200)
Browse files Browse the repository at this point in the history
  • Loading branch information
perost committed Apr 5, 2024
1 parent 1d26a1a commit 3ad175e
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 0 deletions.
76 changes: 76 additions & 0 deletions OMCompiler/Compiler/FrontEnd/AbsynUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,20 @@ algorithm
end match;
end crefToPathIgnoreSubs;

public function crefToTypeSpec
"Converts a ComponentRef to a TypeSpec, treating subscripts on the last
identifier as dimensions and failing if any other identifier is subscripted."
input Absyn.ComponentRef cref;
output Absyn.TypeSpec ty;
protected
list<Absyn.Subscript> subs;
Absyn.Path path;
algorithm
subs := crefGetLastSubs(cref);
path := crefToPath(crefStripLastSubs(cref));
ty := Absyn.TypeSpec.TPATH(path, if listEmpty(subs) then NONE() else SOME(subs));
end crefToTypeSpec;

public function pathToCref "This function converts a Absyn.Path to a Absyn.ComponentRef."
input Absyn.Path inPath;
output Absyn.ComponentRef outComponentRef;
Expand Down Expand Up @@ -6538,5 +6552,67 @@ algorithm
end match;
end isAlgorithmSection;

function setElementType
"Sets the type of a component or short class definition. If the element
contains multiple components the type is only changed if
allowMultipleComponents = true, otherwise the function will fail."
input output Absyn.Element element;
input Absyn.TypeSpec typeSpec;
input Boolean allowMultipleComponents = false;
algorithm
() := match element
case Absyn.Element.ELEMENT()
algorithm
element.specification := setElementSpecType(element.specification, typeSpec, allowMultipleComponents);
then
();

else ();
end match;
end setElementType;

function setElementSpecType
input output Absyn.ElementSpec spec;
input Absyn.TypeSpec typeSpec;
input Boolean allowMultipleComponents = false;
protected
Absyn.Class cls;
algorithm
() := match spec
case Absyn.ElementSpec.CLASSDEF()
algorithm
spec.class_ := setClassType(spec.class_, typeSpec);
then
();

case Absyn.ElementSpec.COMPONENTS()
guard allowMultipleComponents or listLength(spec.components) == 1
algorithm
spec.typeSpec := typeSpec;
then
();
end match;
end setElementSpecType;

function setClassType
input output Absyn.Class cls;
input Absyn.TypeSpec typeSpec;
algorithm
cls.body := setClassDefType(cls.body, typeSpec);
end setClassType;

function setClassDefType
input output Absyn.ClassDef cdef;
input Absyn.TypeSpec typeSpec;
algorithm
() := match cdef
case Absyn.ClassDef.DERIVED()
algorithm
cdef.typeSpec := typeSpec;
then
();
end match;
end setClassDefType;

annotation(__OpenModelica_Interface="frontend");
end AbsynUtil;
12 changes: 12 additions & 0 deletions OMCompiler/Compiler/FrontEnd/ModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -3349,6 +3349,18 @@ annotation(
preferredView="text");
end setElementAnnotation;

function setElementType
input TypeName elementName;
input VariableName typeName;
output Boolean success;
external "builtin";
annotation(
Documentation(info="<html>
<p>Changes the type of a component or short class element.</p>
</html>"),
preferredView="text");
end setElementType;

function removeExtendsModifiers
input TypeName className;
input TypeName baseClassName;
Expand Down
12 changes: 12 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -3591,6 +3591,18 @@ annotation(
preferredView="text");
end setElementAnnotation;

function setElementType
input TypeName elementName;
input VariableName typeName;
output Boolean success;
external "builtin";
annotation(
Documentation(info="<html>
<p>Changes the type of a component or short class element.</p>
</html>"),
preferredView="text");
end setElementType;

function getInstantiatedParametersAndValues
input TypeName cls;
output String[:] values;
Expand Down
8 changes: 8 additions & 0 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Original file line number Diff line number Diff line change
Expand Up @@ -3099,6 +3099,14 @@ algorithm
then
Values.BOOL(b);
case ("setElementType",
{Values.CODE(Absyn.C_TYPENAME(path)),
Values.CODE(Absyn.C_VARIABLENAME(cr))})
algorithm
(p, b) := InteractiveUtil.setElementType(path, cr, SymbolTable.getAbsyn());
then
Values.BOOL(b);
end matchcontinue;
end cevalInteractiveFunctions4;
Expand Down
24 changes: 24 additions & 0 deletions OMCompiler/Compiler/Script/InteractiveUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -6080,5 +6080,29 @@ algorithm
end while;
end getInheritedAnnotation;

public function setElementType
input Absyn.Path elementPath;
input Absyn.ComponentRef className;
input output Absyn.Program program;
output Boolean success = true;
protected
Option<Absyn.Annotation> ann;
String name;
Option<Absyn.Element> elem_opt;
Absyn.TypeSpec ty;
algorithm
try
ty := AbsynUtil.crefToTypeSpec(className);
(program, elem_opt, success) := transformPathedElementInProgram(elementPath,
function AbsynUtil.setElementType(typeSpec = ty, allowMultipleComponents = false), program);

if success then
SymbolTable.setAbsynElement(program, Util.getOption(elem_opt), elementPath);
end if;
else
success := false;
end try;
end setElementType;

annotation(__OpenModelica_Interface="backend");
end InteractiveUtil;
1 change: 1 addition & 0 deletions testsuite/openmodelica/interactive-API/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ saveTotalModel.mos \
setComponentComment.mos \
setComponentModifierValue.mos \
setElementAnnotation.mos \
setElementType.mos \
setElementModifierValue.mos \
setExtendsModifierValue.mos \
setSourceFileListFile.mos \
Expand Down
40 changes: 40 additions & 0 deletions testsuite/openmodelica/interactive-API/setElementType.mos
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// name: setElementType
// keywords:
// status: correct
// cflags: -d=newInst
//
// Tests the setElementType API function.
//

loadString("
model M
Real x;
connector C = RealInput;
end M;
");

setElementType(M.x, Integer[3]);
list(M);
setElementType(M.C, RealOutput);
list(M);
setElementType(M.C, RealOutput[2]);
list(M);

// Result:
// true
// true
// "model M
// Integer[3] x;
// connector C = RealInput;
// end M;"
// true
// "model M
// Integer[3] x;
// connector C = RealOutput;
// end M;"
// true
// "model M
// Integer[3] x;
// connector C = RealOutput[2];
// end M;"
// endResult

0 comments on commit 3ad175e

Please sign in to comment.