Skip to content

Commit

Permalink
Basic handling of component conditions in nfinst.
Browse files Browse the repository at this point in the history
- Implemented handling of component conditions, including instantiation,
  typing and removal of component with a false condition, but not
  including removing connections to such components.

Belonging to [master]:
  - OpenModelica/OMCompiler#1992
  - OpenModelica/OpenModelica-testsuite#769
  • Loading branch information
perost authored and OpenModelica-Hudson committed Nov 7, 2017
1 parent 42bc0b1 commit cf74482
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 18 deletions.
16 changes: 15 additions & 1 deletion Compiler/NFFrontEnd/NFBinding.mo
Expand Up @@ -104,6 +104,16 @@ public
end match;
end isBound;

function isUnbound
input Binding binding;
output Boolean isUnbound;
algorithm
isUnbound := match binding
case UNBOUND() then true;
else false;
end match;
end isUnbound;

function untypedExp
input Binding binding;
output Option<Expression> exp;
Expand All @@ -120,6 +130,7 @@ public
algorithm
exp := match binding
case TYPED_BINDING() then SOME(binding.bindingExp);
case FLAT_BINDING() then SOME(binding.bindingExp);
else NONE();
end match;
end typedExp;
Expand All @@ -128,7 +139,10 @@ public
input Binding binding;
output Expression exp;
algorithm
TYPED_BINDING(bindingExp = exp) := binding;
exp := match binding
case TYPED_BINDING() then binding.bindingExp;
case FLAT_BINDING() then binding.bindingExp;
end match;
end getTypedExp;

function setTypedExp
Expand Down
6 changes: 6 additions & 0 deletions Compiler/NFFrontEnd/NFBuiltin.mo
Expand Up @@ -233,6 +233,7 @@ constant InstNode STATESELECT_NEVER =
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE,
Binding.UNBOUND(),
STATESELECT_NEVER_BINDING,
NFComponent.CONSTANT_ATTR,
Absyn.dummyInfo)),
Expand All @@ -247,6 +248,7 @@ constant InstNode STATESELECT_AVOID =
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE,
Binding.UNBOUND(),
STATESELECT_AVOID_BINDING,
NFComponent.CONSTANT_ATTR,
Absyn.dummyInfo)),
Expand All @@ -261,6 +263,7 @@ constant InstNode STATESELECT_DEFAULT =
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE,
Binding.UNBOUND(),
STATESELECT_DEFAULT_BINDING,
NFComponent.CONSTANT_ATTR,
Absyn.dummyInfo)),
Expand All @@ -275,6 +278,7 @@ constant InstNode STATESELECT_PREFER =
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE,
Binding.UNBOUND(),
STATESELECT_PREFER_BINDING,
NFComponent.CONSTANT_ATTR,
Absyn.dummyInfo)),
Expand All @@ -289,6 +293,7 @@ constant InstNode STATESELECT_ALWAYS =
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE,
Binding.UNBOUND(),
STATESELECT_ALWAYS_BINDING,
NFComponent.CONSTANT_ATTR,
Absyn.dummyInfo)),
Expand All @@ -313,6 +318,7 @@ constant InstNode TIME =
REAL_NODE,
Type.REAL(),
Binding.UNBOUND(),
Binding.UNBOUND(),
NFComponent.INPUT_ATTR,
Absyn.dummyInfo)),
InstNode.EMPTY_NODE());
Expand Down
10 changes: 5 additions & 5 deletions Compiler/NFFrontEnd/NFBuiltinFuncs.mo
Expand Up @@ -60,39 +60,39 @@ constant SCode.Element DUMMY_ELEMENT = SCode.COMPONENT("dummy",

// Default Integer parameter.
constant Component INT_COMPONENT = Component.TYPED_COMPONENT(NFInstNode.EMPTY_NODE(),
Type.INTEGER(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);
Type.INTEGER(), Binding.UNBOUND(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);

constant InstNode INT_PARAM = InstNode.COMPONENT_NODE("i",
Visibility.PUBLIC,
Pointer.createImmutable(INT_COMPONENT), InstNode.EMPTY_NODE());

// Default Real parameter.
constant Component REAL_COMPONENT = Component.TYPED_COMPONENT(NFInstNode.EMPTY_NODE(),
Type.REAL(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);
Type.REAL(), Binding.UNBOUND(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);

constant InstNode REAL_PARAM = InstNode.COMPONENT_NODE("r",
Visibility.PUBLIC,
Pointer.createImmutable(REAL_COMPONENT), InstNode.EMPTY_NODE());

// Default Boolean parameter.
constant Component BOOL_COMPONENT = Component.TYPED_COMPONENT(NFInstNode.EMPTY_NODE(),
Type.BOOLEAN(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);
Type.BOOLEAN(), Binding.UNBOUND(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);

constant InstNode BOOL_PARAM = InstNode.COMPONENT_NODE("b",
Visibility.PUBLIC,
Pointer.createImmutable(BOOL_COMPONENT), InstNode.EMPTY_NODE());

// Default String parameter.
constant Component STRING_COMPONENT = Component.TYPED_COMPONENT(NFInstNode.EMPTY_NODE(),
Type.STRING(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);
Type.STRING(), Binding.UNBOUND(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);

constant InstNode STRING_PARAM = InstNode.COMPONENT_NODE("s",
Visibility.PUBLIC,
Pointer.createImmutable(STRING_COMPONENT), InstNode.EMPTY_NODE());

// Default enumeration(:) parameter.
constant Component ENUM_COMPONENT = Component.TYPED_COMPONENT(NFInstNode.EMPTY_NODE(),
Type.ENUMERATION_ANY(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);
Type.ENUMERATION_ANY(), Binding.UNBOUND(), Binding.UNBOUND(), Component.Attributes.DEFAULT(), Absyn.dummyInfo);

constant InstNode ENUM_PARAM = InstNode.COMPONENT_NODE("e",
Visibility.PUBLIC,
Expand Down
11 changes: 11 additions & 0 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -60,6 +60,10 @@ uniontype EvalTarget
SourceInfo info;
end RANGE;

record CONDITION
SourceInfo info;
end CONDITION;

record IGNORE_ERRORS end IGNORE_ERRORS;

function isRange
Expand Down Expand Up @@ -239,6 +243,13 @@ algorithm
then
fail();

case EvalTarget.CONDITION()
algorithm
Error.addSourceMessage(Error.CONDITIONAL_EXP_WITHOUT_VALUE,
{Expression.toString(exp)}, target.info);
then
fail();

else ();
end match;
end printUnboundError;
Expand Down
5 changes: 4 additions & 1 deletion Compiler/NFFrontEnd/NFComponent.mo
Expand Up @@ -109,6 +109,7 @@ uniontype Component
InstNode classInst;
array<Dimension> dimensions;
Binding binding;
Binding condition;
Component.Attributes attributes;
SourceInfo info;
end UNTYPED_COMPONENT;
Expand All @@ -117,6 +118,7 @@ uniontype Component
InstNode classInst;
Type ty;
Binding binding;
Binding condition;
Component.Attributes attributes;
SourceInfo info;
end TYPED_COMPONENT;
Expand Down Expand Up @@ -250,7 +252,8 @@ uniontype Component
algorithm
component := match component
case UNTYPED_COMPONENT()
then TYPED_COMPONENT(component.classInst, ty, component.binding, component.attributes, component.info);
then TYPED_COMPONENT(component.classInst, ty, component.binding,
component.condition, component.attributes, component.info);

case TYPED_COMPONENT()
algorithm
Expand Down
1 change: 1 addition & 0 deletions Compiler/NFFrontEnd/NFExpOrigin.mo
Expand Up @@ -18,6 +18,7 @@ public
record RHS "rhs of equation/assignment" end RHS;
record ITERATION_RANGE end ITERATION_RANGE;
record BINDING end BINDING;
record CONDITION end CONDITION;
record NO_ORIGIN end NO_ORIGIN;

function next
Expand Down
9 changes: 7 additions & 2 deletions Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -192,7 +192,7 @@ protected
Component c;
Type ty;
ComponentRef new_pre;
Binding binding;
Binding binding, condition;
list<Dimension> dims;
Class cls;
algorithm
Expand All @@ -205,8 +205,13 @@ algorithm
c := InstNode.component(comp_node);

() := match c
case Component.TYPED_COMPONENT(ty = ty)
case Component.TYPED_COMPONENT(ty = ty, condition = condition)
algorithm
// Don't add the component if it has a condition that's false.
if Binding.isBound(condition) and Expression.isFalse(Binding.getTypedExp(condition)) then
return;
end if;

new_pre := ComponentRef.prefixCref(comp_node, ty, {}, prefix);
cls := InstNode.getClass(c.classInst);

Expand Down
9 changes: 6 additions & 3 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -925,10 +925,11 @@ protected
SCode.Element def;
InstNode scp, cls, comp_node;
Modifier mod, comp_mod;
Binding binding;
Binding binding, condition;
DAE.Type ty;
Component.Attributes attr, cls_attr;
list<Dimension> dims;
SourceInfo info;
algorithm
comp_node := InstNode.resolveOuter(node);
comp := InstNode.component(comp_node);
Expand All @@ -955,7 +956,7 @@ algorithm
then
();

case (_, Component.COMPONENT_DEF(definition = def as SCode.COMPONENT()))
case (_, Component.COMPONENT_DEF(definition = def as SCode.COMPONENT(info = info)))
algorithm
comp_mod := Modifier.fromElement(def, parent);
comp_mod := Modifier.merge(comp.modifier, comp_mod);
Expand All @@ -965,11 +966,12 @@ algorithm
Modifier.checkEach(comp_mod, listEmpty(dims), InstNode.name(comp_node));
binding := Modifier.binding(comp_mod);
comp_mod := Modifier.propagate(comp_mod);
condition := Binding.fromAbsyn(def.condition, SCode.Each.NOT_EACH(), parent, info);

// Instantiate attributes and create the untyped components.
attr := instComponentAttributes(def.attributes, def.prefixes, attributes, comp_node);
inst_comp := Component.UNTYPED_COMPONENT(InstNode.EMPTY_NODE(), listArray(dims),
binding, attr, def.info);
binding, condition, attr, def.info);
InstNode.updateComponent(inst_comp, comp_node);

// Instantiate the type of the component.
Expand Down Expand Up @@ -1239,6 +1241,7 @@ algorithm
case Component.UNTYPED_COMPONENT(dimensions = dims)
algorithm
c.binding := instBinding(c.binding);
c.condition := instBinding(c.condition);
instExpressions(c.classInst, node);

cls_dims := Class.getDimensions(InstNode.getClass(c.classInst));
Expand Down
1 change: 1 addition & 0 deletions Compiler/NFFrontEnd/NFRecord.mo
Expand Up @@ -92,6 +92,7 @@ algorithm
node,
Type.COMPLEX(node, ComplexType.CLASS()),
Binding.UNBOUND(),
Binding.UNBOUND(),
NFComponent.OUTPUT_ATTR,
Absyn.dummyInfo)),
node);
Expand Down
46 changes: 40 additions & 6 deletions Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -456,7 +456,7 @@ algorithm
end typeDimension;

function typeBindings
input output InstNode cls;
input InstNode cls;
protected
Class c;
ClassTree cls_tree;
Expand Down Expand Up @@ -524,12 +524,10 @@ algorithm
c.binding := binding;
end if;

cls := typeBindings(c.classInst);
typeBindings(c.classInst);

// The component's type can change, e.g. if it was a derived class that
// was resolved to its base class.
if not referenceEq(cls, c.classInst) then
c.classInst := cls;
if Binding.isBound(c.condition) then
c.condition := typeComponentCondition(c.condition);
dirty := true;
end if;

Expand Down Expand Up @@ -577,6 +575,42 @@ algorithm
end match;
end typeBinding;

function typeComponentCondition
input output Binding condition;
algorithm
condition := match condition
local
Expression exp;
Type ty;
Variability var;
SourceInfo info;
MatchKind mk;

case Binding.UNTYPED_BINDING(bindingExp = exp, info = info)
algorithm
(exp, ty, var) := typeExp(exp, info, ExpOrigin.CONDITION());
(exp, _, mk) := TypeCheck.matchTypes(ty, Type.BOOLEAN(), exp);

if TypeCheck.isIncompatibleMatch(mk) then
Error.addSourceMessage(Error.IF_CONDITION_TYPE_ERROR,
{Expression.toString(exp), Type.toString(ty)}, info);
fail();
end if;

if var > Variability.PARAMETER then
Error.addSourceMessage(Error.COMPONENT_CONDITION_VARIABILITY,
{Expression.toString(exp)}, info);
fail();
end if;

exp := Ceval.evalExp(exp, Ceval.EvalTarget.CONDITION(info));
exp := SimplifyExp.simplifyExp(exp);
then
Binding.FLAT_BINDING(exp);

end match;
end typeComponentCondition;

function typeTypeAttributes
input output list<Modifier> attributes;
input Type ty;
Expand Down

0 comments on commit cf74482

Please sign in to comment.