Skip to content

Commit

Permalink
NFInst improvements.
Browse files Browse the repository at this point in the history
- Implemented support for external functions.
- Implemented support for external objects.
- Fixed complex type paths when converting to DAE.

Belonging to [master]:
  - OpenModelica/OMCompiler#2053
  - OpenModelica/OpenModelica-testsuite#793
  • Loading branch information
perost authored and OpenModelica-Hudson committed Nov 28, 2017
1 parent d653ea8 commit 9085666
Show file tree
Hide file tree
Showing 17 changed files with 783 additions and 78 deletions.
13 changes: 12 additions & 1 deletion Compiler/NFFrontEnd/NFBuiltin.mo
Expand Up @@ -110,12 +110,16 @@ encapsulated package Elements
}),
SCode.noComment, Absyn.dummyInfo);

constant SCode.Element EXTERNALOBJECT = SCode.CLASS("ExternalObject",
SCode.defaultPrefixes, SCode.NOT_ENCAPSULATED(), SCode.PARTIAL(), SCode.R_CLASS(),
SCode.PARTS({}, {}, {}, {}, {}, {}, {}, NONE()), SCode.noComment, Absyn.dummyInfo);

end Elements;

// InstNodes for the builtin types. These have empty class trees to prevent
// access to the attributes via dot notation (which is not needed for
// modifiers and illegal in other cases).
constant InstNode ANYTYPE_NODE = InstNode.CLASS_NODE("polymorphic",
constant InstNode POLYMORPHIC_NODE = InstNode.CLASS_NODE("polymorphic",
Elements.ANY, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.POLYMORPHIC(""), NFClassTree.EMPTY,
Modifier.NOMOD(), Restriction.TYPE())),
Expand Down Expand Up @@ -307,6 +311,13 @@ constant InstNode STATESELECT_ALWAYS =
constant ComponentRef STATESELECT_ALWAYS_CREF =
ComponentRef.CREF(STATESELECT_ALWAYS, {}, STATESELECT_TYPE, Origin.CREF, STATESELECT_CREF);

constant InstNode EXTERNALOBJECT_NODE = InstNode.CLASS_NODE("ExternalObject",
Elements.EXTERNALOBJECT, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.UNKNOWN(), NFClassTree.EMPTY,
Modifier.NOMOD(), Restriction.CLASS())),
arrayCreate(NFInstNode.NUMBER_OF_CACHES, NFInstNode.CachedData.NO_CACHE()),
InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

constant Type ASSERTIONLEVEL_TYPE = Type.ENUMERATION(
Absyn.IDENT("AssertionLevel"), {"error", "warning"});

Expand Down
10 changes: 10 additions & 0 deletions Compiler/NFFrontEnd/NFClass.mo
Expand Up @@ -393,6 +393,16 @@ uniontype Class
output Boolean isConnector = Restriction.isConnector(restriction(cls));
end isConnectorClass;

function isExternalObject
input Class cls;
output Boolean isExternalObject = Restriction.isExternalObject(restriction(cls));
end isExternalObject;

function isFunction
input Class cls;
output Boolean isFunction = Restriction.isFunction(restriction(cls));
end isFunction;

end Class;

annotation(__OpenModelica_Interface="frontend");
Expand Down
53 changes: 52 additions & 1 deletion Compiler/NFFrontEnd/NFClassTree.mo
Expand Up @@ -692,6 +692,23 @@ public
element := resolveEntryPtr(entry, tree);
end lookupElementPtr;

function foldClasses<ArgT>
input ClassTree tree;
input FuncT func;
input output ArgT arg;

partial function FuncT
input InstNode clsNode;
input output ArgT arg;
end FuncT;
protected
array<InstNode> clss = getClasses(tree);
algorithm
for cls in clss loop
arg := func(cls, arg);
end for;
end foldClasses;

function applyExtends
input ClassTree tree;
input FuncT func;
Expand Down Expand Up @@ -797,14 +814,26 @@ public
end match;
end applyLocalComponents;

function classCount
input ClassTree tree;
output Integer count;
algorithm
count := match tree
case PARTIAL_TREE() then arrayLength(tree.classes);
case EXPANDED_TREE() then arrayLength(tree.classes);
case INSTANTIATED_TREE() then arrayLength(tree.classes);
case FLAT_TREE() then arrayLength(tree.classes);
end match;
end classCount;

function componentCount
input ClassTree tree;
output Integer count;
algorithm
count := match tree
case PARTIAL_TREE() then arrayLength(tree.components) - arrayLength(tree.exts);
case EXPANDED_TREE() then arrayLength(tree.components) - arrayLength(tree.exts);
case INSTANTIATED_TREE() then arrayLength(tree.components) - arrayLength(tree.exts);
case INSTANTIATED_TREE() then arrayLength(tree.components);
case FLAT_TREE() then arrayLength(tree.components);
end match;
end componentCount;
Expand Down Expand Up @@ -953,6 +982,17 @@ public
end match;
end enumerateComponents2;

function getClasses
input ClassTree tree;
output array<InstNode> clss;
algorithm
clss := match tree
case PARTIAL_TREE() then tree.classes;
case EXPANDED_TREE() then tree.classes;
case FLAT_TREE() then tree.classes;
end match;
end getClasses;

function getExtends
input ClassTree tree;
output array<InstNode> exts;
Expand All @@ -964,6 +1004,17 @@ public
end match;
end getExtends;

function getComponents
input ClassTree tree;
output array<InstNode> comps;
algorithm
comps := match tree
case PARTIAL_TREE() then tree.components;
case EXPANDED_TREE() then tree.components;
case FLAT_TREE() then tree.components;
end match;
end getComponents;

protected

function instExtendsComps
Expand Down
5 changes: 5 additions & 0 deletions Compiler/NFFrontEnd/NFComplexType.mo
Expand Up @@ -45,5 +45,10 @@ public
Boolean isExpandable;
end CONNECTOR;

record EXTERNAL_OBJECT
InstNode constructor;
InstNode destructor;
end EXTERNAL_OBJECT;

annotation(__OpenModelica_Interface="frontend");
end NFComplexType;
113 changes: 89 additions & 24 deletions Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -908,39 +908,34 @@ function convertFunction
output DAE.Function dfunc;
protected
Class cls;
array<InstNode> comps;
list<DAE.Element> elems;
DAE.FunctionDefinition def;
Sections sections;
algorithm
cls := InstNode.getClass(Function.instance(func));

dfunc := match cls
case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE(components = comps), sections = sections)
case Class.INSTANCED_CLASS(sections = sections)
algorithm
elems := {};

for c in func.inputs loop
elems := convertFunctionParam(c) :: elems;
end for;

for c in func.outputs loop
elems := convertFunctionParam(c) :: elems;
end for;

for c in func.locals loop
elems := convertFunctionParam(c) :: elems;
end for;

// elems := list(convertFunctionParam(c) for c in func.locals) :: elems;
elems := match sections
case Sections.SECTIONS() then convertAlgorithms(sections.algorithms, elems);
else elems;
elems := convertFunctionParams(func.inputs, {});
elems := convertFunctionParams(func.outputs, elems);
elems := convertFunctionParams(func.locals, elems);

def := match sections
// A function with an algorithm section.
case Sections.SECTIONS()
algorithm
elems := convertAlgorithms(sections.algorithms, elems);
then
DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));

// An external function.
case Sections.EXTERNAL()
then convertExternalDecl(sections, listReverse(elems));

// A function without either algorithm or external section.
else DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));
end match;

elems := listReverse(elems);

def := DAE.FunctionDefinition.FUNCTION_DEF(elems);
then
Function.toDAE(func, {def});

Expand All @@ -953,6 +948,15 @@ algorithm
end match;
end convertFunction;

function convertFunctionParams
input list<InstNode> params;
input output list<DAE.Element> elements;
algorithm
for p in params loop
elements := convertFunctionParam(p) :: elements;
end for;
end convertFunctionParams;

function convertFunctionParam
input InstNode node;
output DAE.Element element;
Expand Down Expand Up @@ -988,6 +992,67 @@ algorithm
end match;
end convertFunctionParam;

function convertExternalDecl
input Sections extDecl;
input list<DAE.Element> parameters;
output DAE.FunctionDefinition funcDef;
protected
DAE.ExternalDecl decl;
list<DAE.ExtArg> args;
DAE.ExtArg ret_arg;
algorithm
funcDef := match extDecl
case Sections.EXTERNAL()
algorithm
args := list(convertExternalDeclArg(e) for e in extDecl.args);
ret_arg := convertExternalDeclOutput(extDecl.outputRef);
decl := DAE.ExternalDecl.EXTERNALDECL(extDecl.name, args, ret_arg, extDecl.language, extDecl.ann);
then
DAE.FunctionDefinition.FUNCTION_EXT(parameters, decl);
end match;
end convertExternalDecl;

function convertExternalDeclArg
input Expression exp;
output DAE.ExtArg arg;
algorithm
arg := match exp
local
Absyn.Direction dir;
ComponentRef cref;
Expression e;

case Expression.CREF(cref = cref as ComponentRef.CREF())
algorithm
dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(cref.node)));
then
DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(exp.ty));

case Expression.SIZE(exp = Expression.CREF(cref = cref as ComponentRef.CREF()), dimIndex = SOME(e))
then DAE.ExtArg.EXTARGSIZE(ComponentRef.toDAE(cref), Type.toDAE(cref.ty), Expression.toDAE(e));

else DAE.ExtArg.EXTARGEXP(Expression.toDAE(exp), Type.toDAE(Expression.typeOf(exp)));

end match;
end convertExternalDeclArg;

function convertExternalDeclOutput
input ComponentRef cref;
output DAE.ExtArg arg;
algorithm
arg := match cref
local
Absyn.Direction dir;

case ComponentRef.CREF()
algorithm
dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(cref.node)));
then
DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(cref.ty));

else DAE.ExtArg.NOEXTARG();
end match;
end convertExternalDeclOutput;

annotation(__OpenModelica_Interface="frontend");
end NFConvertDAE;
14 changes: 14 additions & 0 deletions Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -1763,5 +1763,19 @@ public
end match;
end isZero;

function isScalarConst
input Expression exp;
output Boolean isScalar;
algorithm
isScalar := match exp
case INTEGER() then true;
case REAL() then true;
case STRING() then true;
case BOOLEAN() then true;
case ENUM_LITERAL() then true;
else false;
end match;
end isScalarConst;

annotation(__OpenModelica_Interface="frontend");
end NFExpression;
34 changes: 33 additions & 1 deletion Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -72,6 +72,8 @@ import ConnectEquations = NFConnectEquations;
import Connections = NFConnections;
import Face = NFConnector.Face;
import System;
import ComplexType = NFComplexType;
import NFInstNode.CachedData;

public
type FunctionTree = FunctionTreeImpl.Tree;
Expand Down Expand Up @@ -716,14 +718,44 @@ function collectComponentFuncs
input output FunctionTree funcs;
protected
Binding binding;
ComponentRef cref;
InstNode node;
Type ty;
algorithm
(_, binding) := component;
(cref, binding) := component;
ComponentRef.CREF(node = node, ty = ty) := cref;

// TODO: Collect functions from the component's type attributes.

() := match ty
case Type.COMPLEX(complexTy = ComplexType.EXTERNAL_OBJECT())
algorithm
funcs := collectExternalObjectStructors(ty.complexTy, funcs);
then
();

else ();
end match;

if Binding.isBound(binding) then
funcs := collectExpFuncs(Binding.getTypedExp(binding), funcs);
end if;
end collectComponentFuncs;

function collectExternalObjectStructors
input ComplexType ty;
input output FunctionTree funcs;
protected
InstNode constructor, destructor;
Function fn;
algorithm
ComplexType.EXTERNAL_OBJECT(constructor, destructor) := ty;
CachedData.FUNCTION(funcs = {fn}) := InstNode.getFuncCache(constructor);
funcs := flattenFunction(fn, funcs);
CachedData.FUNCTION(funcs = {fn}) := InstNode.getFuncCache(destructor);
funcs := flattenFunction(fn, funcs);
end collectExternalObjectStructors;

function collectEquationFuncs
input Equation eq;
input output FunctionTree funcs;
Expand Down

0 comments on commit 9085666

Please sign in to comment.