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

Commit

Permalink
[NF] Operator overloading improvements.
Browse files Browse the repository at this point in the history
- Only generate default constructors for operator records that has no
  overloaded constructor defined.
- Avoid generating duplicate operator functions that causes the matching
  to fail.
- Some other minor fixes.

Belonging to [master]:
  - #2504
  - OpenModelica/OpenModelica-testsuite#974
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jun 14, 2018
1 parent 9419b55 commit dc81059
Show file tree
Hide file tree
Showing 16 changed files with 377 additions and 248 deletions.
6 changes: 3 additions & 3 deletions Compiler/NFFrontEnd/NFBuiltinCall.mo
Expand Up @@ -383,9 +383,9 @@ protected

fn_ref := Function.instFunctionRef(fn_ref, InstNode.info(recopnode));
candidates := Function.typeRefCache(fn_ref);
for fn in candidates loop
TypeCheck.checkValidOperatorOverload("'String'", fn, recopnode);
end for;
//for fn in candidates loop
// TypeCheck.checkValidOperatorOverload("'String'", fn, recopnode);
//end for;

matchedFunctions := Function.matchFunctionsSilent(candidates, args, namedArgs, info);
exactMatches := MatchedFunction.getExactMatches(matchedFunctions);
Expand Down
8 changes: 4 additions & 4 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -343,11 +343,11 @@ algorithm
binding;

// A record field without an explicit binding, evaluate the parent's binding
// if it as one and fetch the binding from it instead.
// if it has one and fetch the binding from it instead.
case (_, _, InstNode.COMPONENT_NODE(parent = rec_node as InstNode.COMPONENT_NODE()))
guard Type.isRecord(InstNode.getType(rec_node))
algorithm
exp := evalComponentBinding(rec_node, Expression.EMPTY(), target);
exp := evalComponentBinding(rec_node, Expression.EMPTY(Type.UNKNOWN()), target);
exp := Expression.lookupRecordField(InstNode.name(node), exp);
binding := Binding.CEVAL_BINDING(exp);
InstNode.updateComponent(Component.setBinding(binding, component), node);
Expand Down Expand Up @@ -1766,7 +1766,7 @@ algorithm
case {e1, e2} then evalBuiltinMax2(e1, e2);
case {e1 as Expression.ARRAY(ty = ty)}
algorithm
result := Expression.fold(e1, evalBuiltinMax2, Expression.EMPTY());
result := Expression.fold(e1, evalBuiltinMax2, Expression.EMPTY(ty));

if Expression.isEmpty(result) then
result := Expression.CALL(Call.makeTypedCall(fn,
Expand Down Expand Up @@ -1812,7 +1812,7 @@ algorithm
case {e1, e2} then evalBuiltinMin2(e1, e2);
case {e1 as Expression.ARRAY(ty = ty)}
algorithm
result := Expression.fold(e1, evalBuiltinMin2, Expression.EMPTY());
result := Expression.fold(e1, evalBuiltinMin2, Expression.EMPTY(ty));

if Expression.isEmpty(result) then
result := Expression.CALL(Call.makeTypedCall(fn,
Expand Down
12 changes: 12 additions & 0 deletions Compiler/NFFrontEnd/NFClass.mo
Expand Up @@ -536,6 +536,18 @@ uniontype Class
end match;
end setPrefixes;

function isEncapsulated
input Class cls;
output Boolean isEncapsulated;
algorithm
isEncapsulated := match cls
case PARTIAL_CLASS() then SCode.encapsulatedBool(cls.prefixes.encapsulatedPrefix);
case EXPANDED_CLASS() then SCode.encapsulatedBool(cls.prefixes.encapsulatedPrefix);
case EXPANDED_DERIVED() then SCode.encapsulatedBool(cls.prefixes.encapsulatedPrefix);
else false;
end match;
end isEncapsulated;

function lastBaseClass
input output InstNode node;
protected
Expand Down
7 changes: 4 additions & 3 deletions Compiler/NFFrontEnd/NFEvalFunction.mo
Expand Up @@ -125,7 +125,7 @@ algorithm
fn_body := Function.getBody(fn);
repl := createReplacements(fn, args);
// TODO: Also apply replacements to the replacements themselves, i.e. the
// bindings of the function parameters. But the probably need to be
// bindings of the function parameters. But they probably need to be
// sorted by dependencies first.
fn_body := applyReplacements(repl, fn_body);
ctrl := evaluateStatements(fn_body);
Expand Down Expand Up @@ -225,9 +225,10 @@ algorithm
ty := InstNode.getType(node);

result := match ty
case Type.ARRAY() guard Type.hasKnownSize(ty) then Expression.fillType(ty, Expression.EMPTY());
case Type.ARRAY() guard Type.hasKnownSize(ty)
then Expression.fillType(ty, Expression.EMPTY(Type.arrayElementType(ty)));
case Type.COMPLEX() then buildRecordBinding(ty.cls);
else Expression.EMPTY();
else Expression.EMPTY(ty);
end match;
end buildBinding;

Expand Down
2 changes: 2 additions & 0 deletions Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -199,6 +199,7 @@ public
end MUTABLE;

record EMPTY
Type ty;
end EMPTY;

function isCref
Expand Down Expand Up @@ -568,6 +569,7 @@ public
case TUPLE_ELEMENT() then exp.ty;
case BOX() then Type.METABOXED(typeOf(exp.exp));
case MUTABLE() then typeOf(Mutable.access(exp.exp));
case EMPTY() then exp.ty;
else Type.UNKNOWN();
end match;
end typeOf;
Expand Down
8 changes: 6 additions & 2 deletions Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -82,6 +82,7 @@ import Variable = NFVariable;
import ElementSource;
import Ceval = NFCeval;
import NFTyping.ExpOrigin;
import SimplifyExp = NFSimplifyExp;

public
type FunctionTree = FunctionTreeImpl.Tree;
Expand Down Expand Up @@ -309,7 +310,6 @@ algorithm
binding := flattenBinding(binding, prefix);
end if;


// If the component is an array component with a binding and at least discrete variability,
// move the binding into an equation. This avoids having to scalarize the binding.
if Type.isArray(ty) and Binding.isBound(binding) and
Expand Down Expand Up @@ -384,6 +384,7 @@ protected
Expression binding_exp;
Equation eq;
list<Expression> bindings;
Variability comp_var;
algorithm
dims := Type.arrayDims(ty);
binding := Component.getBinding(comp);
Expand All @@ -393,8 +394,11 @@ algorithm
binding := flattenBinding(binding, prefix);
binding_exp := Binding.getTypedExp(binding);

if Component.variability(comp) <= Variability.PARAMETER then
comp_var := Component.variability(comp);
if comp_var <= Variability.PARAMETER then
binding_exp := Ceval.evalExp(binding_exp);
else
binding_exp := SimplifyExp.simplify(binding_exp);
end if;

if not Expression.isRecord(binding_exp) then
Expand Down
16 changes: 14 additions & 2 deletions Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -70,6 +70,7 @@ import Dimension = NFDimension;
import Statement = NFStatement;
import Sections = NFSections;
import Algorithm = NFAlgorithm;
import OperatorOverloading = NFOperatorOverloading;


public
Expand Down Expand Up @@ -340,17 +341,24 @@ uniontype Function
list<Function> funcs;
list<FunctionDerivative> fn_ders;

case SCode.CLASS() guard SCode.isOperatorRecord(def)
algorithm
fnNode := instFunction3(fnNode);
fnNode := OperatorOverloading.instConstructor(fnPath, fnNode, info);
then
(fnNode, false);

case SCode.CLASS() guard SCode.isRecord(def)
algorithm
fnNode := instFunction3(fnNode);
fnNode := Record.instConstructors(fnPath, fnNode, info);
fnNode := Record.instDefaultConstructor(fnPath, fnNode, info);
then
(fnNode, false);

case SCode.CLASS(restriction = SCode.R_OPERATOR(), classDef = cdef as SCode.PARTS())
algorithm
fnNode := instFunction3(fnNode);
fnNode := Record.instOperatorFunctions(fnNode, info);
fnNode := OperatorOverloading.instOperatorFunctions(fnNode, info);
then
(fnNode, false);

Expand All @@ -368,6 +376,10 @@ uniontype Function

case SCode.CLASS()
algorithm
if SCode.isOperator(def) then
OperatorOverloading.checkOperatorRestrictions(fnNode);
end if;

fnNode := InstNode.setNodeType(NFInstNode.InstNodeType.ROOT_CLASS(), fnNode);
fnNode := instFunction3(fnNode);
fn := new(fnPath, fnNode);
Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFFunctionDerivative.mo
Expand Up @@ -213,7 +213,7 @@ protected
input Function fn;
input InstNode scope;
input SourceInfo info;
output Expression order = Expression.EMPTY();
output Expression order = Expression.EMPTY(Type.UNKNOWN());
output list<tuple<Integer, Condition>> conditions = {};
protected
String id;
Expand Down
32 changes: 20 additions & 12 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -97,6 +97,7 @@ import FlatModel = NFFlatModel;
import ElementSource;
import SimplifyModel = NFSimplifyModel;
import Record = NFRecord;
import OperatorOverloading = NFOperatorOverloading;

public
function instClassInProgram
Expand Down Expand Up @@ -1808,7 +1809,7 @@ algorithm
inst_cls := Class.INSTANCED_CLASS(ty, cls.elements, sections, cls.restriction);
InstNode.updateClass(inst_cls, node);

instComplexType(ty);
instRecordConstructor(cls.restriction, node);
then
();

Expand All @@ -1822,6 +1823,8 @@ algorithm
for i in 1:arrayLength(dims) loop
dims[i] := instDimension(dims[i], dim_scope, info);
end for;

instRecordConstructor(cls.restriction, node);
then
();

Expand Down Expand Up @@ -1875,15 +1878,15 @@ algorithm
ty := ComplexType.RECORD(cls_node, fields);
end makeRecordComplexType;

function instComplexType
input Type ty;
function instRecordConstructor
input Restriction restriction;
input InstNode node;
protected
CachedData cache;
Absyn.Path path;
algorithm
() := match ty
local
InstNode node;
CachedData cache;

case Type.COMPLEX(complexTy = ComplexType.RECORD(node))
() := match restriction
case Restriction.RECORD()
algorithm
cache := InstNode.getFuncCache(node);

Expand All @@ -1892,8 +1895,13 @@ algorithm
else
algorithm
InstNode.cacheInitFunc(node);
Record.instConstructors(
InstNode.scopePath(node, includeRoot = true), node, InstNode.info(node));
path := InstNode.scopePath(node, includeRoot = true);

if SCode.isOperatorRecord(InstNode.definition(node)) then
OperatorOverloading.instConstructor(path, node, InstNode.info(node));
else
Record.instDefaultConstructor(path, node, InstNode.info(node));
end if;
then
();

Expand All @@ -1903,7 +1911,7 @@ algorithm

else ();
end match;
end instComplexType;
end instRecordConstructor;

function instBuiltinAttribute
input output Modifier attribute;
Expand Down

0 comments on commit dc81059

Please sign in to comment.