diff --git a/OMCompiler/Compiler/NFFrontEnd/NFCeval.mo b/OMCompiler/Compiler/NFFrontEnd/NFCeval.mo index 3d0fae4c5f8..f614194e409 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFCeval.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFCeval.mo @@ -67,6 +67,7 @@ import ElementSource; import Flags; import Prefixes = NFPrefixes; import UnorderedMap; +import ErrorExt; public uniontype EvalTarget @@ -150,6 +151,19 @@ uniontype EvalTarget end getInfo; end EvalTarget; +function tryEvalExp + input output Expression exp; +algorithm + ErrorExt.setCheckpoint(getInstanceName()); + + try + exp := evalExp(exp); + else + end try; + + ErrorExt.rollBack(getInstanceName()); +end tryEvalExp; + function evalExp input output Expression exp; input EvalTarget target = EvalTarget.IGNORE_ERRORS(); diff --git a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo index 09f647a96ac..19d95e62fd8 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo @@ -225,7 +225,7 @@ public input output ComponentRef cref; algorithm () := match cref - case CREF() + case CREF() guard InstNode.isComponent(cref.node) algorithm cref.ty := InstNode.getType(cref.node); then diff --git a/OMCompiler/Compiler/NFFrontEnd/NFDimension.mo b/OMCompiler/Compiler/NFFrontEnd/NFDimension.mo index 096ab535f81..6c2c8423c89 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFDimension.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFDimension.mo @@ -435,7 +435,7 @@ public algorithm e2 := Expression.map(e1, func); then - if referenceEq(e1, e2) then dim else EXP(e2, dim.var); + if referenceEq(e1, e2) then dim else fromExp(e2, dim.var); else dim; end match; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo b/OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo index 71603543c2f..46c771ab880 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo @@ -133,6 +133,19 @@ algorithm outExp := evaluateExpTraverser(exp, info); end evaluateExp; +function evaluateExpOpt + input Option exp; + input SourceInfo info; + output Option outExp; +protected + Expression e; +algorithm + outExp := match exp + case SOME(e) then SOME(evaluateExp(e, info)); + else exp; + end match; +end evaluateExpOpt; + function evaluateExpTraverser input Expression exp; input SourceInfo info; @@ -184,6 +197,9 @@ algorithm then outExp; + case Expression.SIZE() + then Expression.SIZE(exp.exp, evaluateExpOpt(exp.dimIndex, info)); + else algorithm (outExp, outChanged) := Expression.mapFoldShallow(exp, @@ -227,12 +243,7 @@ algorithm case Dimension.EXP() algorithm - if dim.var <= Variability.STRUCTURAL_PARAMETER and not - Expression.containsAnyIterator(dim.exp, NFInstContext.FOR) then - e := Ceval.evalExp(dim.exp, Ceval.EvalTarget.GENERIC(info)); - else - e := evaluateExp(dim.exp, info); - end if; + e := evaluateExp(dim.exp, info); then if referenceEq(e, dim.exp) then dim else Dimension.fromExp(e, dim.var); @@ -522,7 +533,11 @@ protected algorithm if not Function.isEvaluated(func) then Function.markEvaluated(func); - func := Function.mapExp(func, function evaluateFuncExp(fnNode = func.node)); + + func := Function.mapExp(func, function evaluateFuncExp(fnNode = func.node), + mapBody = Function.isExternal(func)); + + func := Function.mapBody(func, evaluateAlgorithm); for fn_der in func.derivatives loop for der_fn in Function.getCachedFuncs(fn_der.derivativeFn) loop diff --git a/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo b/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo index d45550c7098..75b5c18f7ad 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo @@ -1907,6 +1907,23 @@ uniontype Function end if; end mapExpParameter; + function mapBody + input output Function fn; + input MapFn mapFn; + + partial function MapFn + input output Algorithm alg; + end MapFn; + protected + Class cls; + Sections sections; + algorithm + cls := InstNode.getClass(fn.node); + sections := Sections.map(Class.getSections(cls), algFn = mapFn); + cls := cls.setSections(sections, cls); + InstNode.updateClass(cls, fn.node); + end mapBody; + function foldExp input Function fn; input FoldFunc foldFn; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFSections.mo b/OMCompiler/Compiler/NFFrontEnd/NFSections.mo index de86c49c175..7f5d8d65141 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFSections.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFSections.mo @@ -194,8 +194,8 @@ public function map input output Sections sections; - input EquationFn eqFn; - input AlgorithmFn algFn; + input EquationFn eqFn = eqId; + input AlgorithmFn algFn = algId; input EquationFn ieqFn = eqFn; input AlgorithmFn ialgFn = algFn; @@ -206,6 +206,14 @@ public partial function AlgorithmFn input output Algorithm alg; end AlgorithmFn; + + function eqId + input output Equation eq; + end eqId; + + function algId + input output Algorithm alg; + end algId; protected list eq, ieq; list alg, ialg; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo index 5e0a8fbdf30..46456ccc81f 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo @@ -550,7 +550,7 @@ algorithm else // For functions, only evaluate constant and structural parameter expressions. if var <= Variability.STRUCTURAL_PARAMETER then - exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info)); + exp := Ceval.tryEvalExp(exp); end if; end if; diff --git a/testsuite/flattening/modelica/scodeinst/FunctionRecordArg3.mo b/testsuite/flattening/modelica/scodeinst/FunctionRecordArg3.mo new file mode 100644 index 00000000000..8046dce1267 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/FunctionRecordArg3.mo @@ -0,0 +1,52 @@ +// name: FunctionRecordArg3 +// keywords: +// status: correct +// cflags: -d=newInst +// + +record BaseR + constant Integer n; + parameter Real x[n]; +end BaseR; + +function f + input BaseR r; + output Real x; +algorithm + x := r.x * r.x; +end f; + +record R = BaseR(n = 2); + +model FunctionRecordArg3 + R r(x = {1, 2}); + Real x = f(r); +end FunctionRecordArg3; + +// Result: +// function BaseR "Automatically generated record constructor for BaseR" +// constant Integer n; +// input Real[n] x; +// output BaseR res; +// end BaseR; +// +// function R "Automatically generated record constructor for R" +// protected Integer n = 2; +// input Real[2] x; +// output R res; +// end R; +// +// function f +// input BaseR r; +// output Real x; +// algorithm +// x := r.x * r.x; +// end f; +// +// class FunctionRecordArg3 +// constant Integer r.n = 2; +// parameter Real r.x[1] = 1.0; +// parameter Real r.x[2] = 2.0; +// Real x = f(r); +// end FunctionRecordArg3; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 7ef924bcedb..8008363679c 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -572,6 +572,7 @@ FunctionNoOutput1.mo \ FunctionNonInputOutputParameter.mo \ FunctionRecordArg1.mo \ FunctionRecordArg2.mo \ +FunctionRecordArg3.mo \ FunctionRecursive1.mo \ FunctionRecursive2.mo \ FunctionSections1.mo \ diff --git a/testsuite/openmodelica/xml/XmlDumpComment.mos b/testsuite/openmodelica/xml/XmlDumpComment.mos index 686069da36b..83293e62cef 100644 --- a/testsuite/openmodelica/xml/XmlDumpComment.mos +++ b/testsuite/openmodelica/xml/XmlDumpComment.mos @@ -21686,13 +21686,13 @@ readFile("Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum.xml"); // protected Real c3; // protected Real c4; // protected constant Real p4limit = 0.1; -// protected constant Real c4limit = 4.0 * p4limit * p4limit; +// protected constant Real c4limit = 0.04000000000000001; // algorithm // c1 := 1.0 + T[1,1] - T[2,2] - T[3,3]; // c2 := 1.0 + T[2,2] - T[1,1] - T[3,3]; // c3 := 1.0 + T[3,3] - T[1,1] - T[2,2]; // c4 := 1.0 + T[1,1] + T[2,2] + T[3,3]; -// if c4 > c4limit or c4 > c1 and c4 > c2 and c4 > c3 then +// if c4 > 0.04000000000000001 or c4 > c1 and c4 > c2 and c4 > c3 then // paux := sqrt(c4) / 2.0; // paux4 := 4.0 * paux; // Q := {(T[2,3] - T[3,2]) / paux4, (T[3,1] - T[1,3]) / paux4, (T[1,2] - T[2,1]) / paux4, paux};