Skip to content

Commit

Permalink
[NF] Initial handling of ragged dimensions.
Browse files Browse the repository at this point in the history
  • Loading branch information
perost committed Jun 4, 2020
1 parent d2bb767 commit 470bccf
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 21 deletions.
7 changes: 7 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -145,6 +145,13 @@ algorithm
exp := Expression.getBindingExp(evalExp_impl(exp, target));
end evalExp;

function evalExpBinding
input output Expression exp;
input EvalTarget target = EvalTarget.IGNORE_ERRORS();
algorithm
exp := evalExp_impl(exp, target);
end evalExpBinding;

function evalExp_impl
input output Expression exp;
input EvalTarget target;
Expand Down
19 changes: 19 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -4407,6 +4407,25 @@ public
end match;
end getBindingExp;

function setBindingExp
"Replaces the expression contained in a binding expression with the given
expression. The given expression is assumed to have the same type as the
old expression, and only the innermost expression in a nested binding will
be replaced."
input Expression exp;
input output Expression bindingExp;
algorithm
bindingExp := match bindingExp
case BINDING_EXP()
algorithm
bindingExp.exp := setBindingExp(exp, bindingExp.exp);
then
bindingExp;

else exp;
end match;
end setBindingExp;

function stripBindingInfo
"Replaces all binding expressions in the given expression with the
expressions they contain."
Expand Down
21 changes: 21 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -432,6 +432,7 @@ algorithm
end if;
end if;

ty := flattenType(ty, prefix);
name := ComponentRef.prefixScope(comp_node, ty, {}, prefix);
ty_attrs := list(flattenTypeAttribute(m, name) for m in typeAttrs);

Expand Down Expand Up @@ -572,6 +573,7 @@ algorithm
if listEmpty(dims) then
(vars, sections) := flattenClass(cls, name, visibility, opt_binding, vars, sections, scalarize);
elseif scalarize then
dims := list(flattenDimension(d, name) for d in dims);
(vars, sections) := flattenArray(cls, dims, name, visibility, opt_binding, vars, sections);
else
(vars, sections) := vectorizeArray(cls, dims, name, visibility, opt_binding, vars, sections);
Expand Down Expand Up @@ -942,6 +944,25 @@ algorithm
end if;
end flattenConditionalArrayIfExp;

function flattenType
input output Type ty;
input ComponentRef prefix;
algorithm
ty := Type.mapDims(ty, function flattenDimension(prefix = prefix));
end flattenType;

function flattenDimension
input output Dimension dim;
input ComponentRef prefix;
algorithm
dim := match dim
case Dimension.EXP()
then Dimension.fromExp(flattenExp(dim.exp, prefix), dim.var);

else dim;
end match;
end flattenDimension;

function flattenSections
input Sections sections;
input ComponentRef prefix;
Expand Down
49 changes: 36 additions & 13 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -573,7 +573,7 @@ function typeDimension
algorithm
dimension := match dimension
local
Expression exp;
Expression exp, dim_exp;
Option<Expression> oexp;
Variability var;
Dimension dim;
Expand Down Expand Up @@ -617,31 +617,35 @@ algorithm
if ExpOrigin.flagNotSet(origin, ExpOrigin.FUNCTION) then
// Dimensions must be parameter expressions in a non-function class.
if var <= Variability.PARAMETER then
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
dim_exp := Ceval.evalExpBinding(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
else
Error.addSourceMessage(Error.DIMENSION_NOT_KNOWN,
{Expression.toString(exp)}, info);
fail();
Error.addSourceMessage(Error.DIMENSION_NOT_KNOWN, {Expression.toString(exp)}, info);
fail();
end if;
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));
dim_exp := Ceval.evalExpBinding(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
else
dim_exp := exp;
end if;
end if;

// It's possible to get an array expression here, for example if the
// dimension expression is a parameter whose binding comes from a
// modifier on an array component. If all the elements are equal we can
// just take one of them and use that, but we don't yet support the case
// where they are different. Creating a dimension from an array leads to
// weird things happening, so for now we print an error instead.
if not Expression.arrayAllEqual(exp) then
Error.addSourceMessage(Error.RAGGED_DIMENSION, {Expression.toString(exp)}, info);
fail();
// just take on of them and use that, otherwise we use the binding
// expression but replace the expression in it with the evaluated one.
exp := Expression.getBindingExp(dim_exp);
if Expression.isArray(exp) then
if Expression.arrayAllEqual(exp) then
exp := Expression.arrayFirstScalar(exp);
else
exp := Expression.setBindingExp(exp, dim_exp);
end if;
end if;

dim := Dimension.fromExp(Expression.arrayFirstScalar(exp), var);
dim := Dimension.fromExp(exp, var);
arrayUpdate(dimensions, index, dim);
then
dim;
Expand Down Expand Up @@ -771,6 +775,25 @@ algorithm
end match;
end verifyDimension;

function makeDimension
input Expression dimExp;
input Expression unevaledExp;
input Variability variability;
output Dimension outDimension;
protected
Expression exp = dimExp;
algorithm
if Expression.isArray(exp) then
if Expression.arrayAllEqual(exp) then
exp := Expression.arrayFirstScalar(exp);
else

end if;
end if;

outDimension := Dimension.fromExp(exp, variability);
end makeDimension;

function getRecordElementBinding
"Tries to fetch the binding for a given record field by using the binding of
the record instance."
Expand Down
18 changes: 10 additions & 8 deletions testsuite/flattening/modelica/scodeinst/DimRagged1.mo
@@ -1,6 +1,6 @@
// name: DimRagged1
// keywords:
// status: incorrect
// status: correct
// cflags: -d=newInst
//

Expand All @@ -14,11 +14,13 @@ model DimRagged1
end DimRagged1;

// Result:
// Error processing file: DimRagged1.mo
// [flattening/modelica/scodeinst/DimRagged1.mo:9:3-9:12:writable] Error: Ragged dimensions are not yet supported (from dimension '{2, 3}')
//
// # Error encountered! Exiting...
// # Please check the error message and the flags.
//
// Execution failed!
// class DimRagged1
// final parameter Integer arr[1].n = 2;
// Real arr[1].a[1];
// Real arr[1].a[2];
// final parameter Integer arr[2].n = 3;
// Real arr[2].a[1];
// Real arr[2].a[2];
// Real arr[2].a[3];
// end DimRagged1;
// endResult

0 comments on commit 470bccf

Please sign in to comment.