Skip to content

Commit

Permalink
[NF] Improve dimension typing.
Browse files Browse the repository at this point in the history
- Try harder to deduce unknown dimensions by evaluating the
  corresponding binding if needed.
  • Loading branch information
perost committed Jan 20, 2020
1 parent 0c802bd commit c6029d1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
27 changes: 23 additions & 4 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -542,12 +542,13 @@ algorithm
dimension := match dimension
local
Expression exp;
Option<Expression> oexp;
Variability var;
Dimension dim;
Binding b;
Type ty;
TypingError ty_err;
Integer parent_dims;
Integer parent_dims, dim_index;

// Print an error when a dimension that's currently being processed is
// found, which indicates a dependency loop. Another way of handling this
Expand Down Expand Up @@ -649,14 +650,32 @@ algorithm
// to get the dimension we're looking for.
case Binding.UNTYPED_BINDING()
algorithm
(dim, _, ty_err) := typeExpDim(b.bindingExp, index + Binding.propagatedDimCount(b) + parent_dims,
ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info);
dim_index := index + Binding.propagatedDimCount(b) + parent_dims;
(dim, oexp, ty_err) := typeExpDim(b.bindingExp, dim_index, ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info);

// If the deduced dimension is unknown, evaluate the binding and try again.
if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then
exp := if isSome(oexp) then Util.getOption(oexp) else b.bindingExp;
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
(dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index);
end if;
then
(dim, ty_err);

// A typed binding, get the dimension from the binding's type.
case Binding.TYPED_BINDING()
then nthDimensionBoundsChecked(b.bindingType, index + Binding.propagatedDimCount(b) + parent_dims);
algorithm
dim_index := index + Binding.propagatedDimCount(b) + parent_dims;
(dim, ty_err) := nthDimensionBoundsChecked(b.bindingType, dim_index);

// If the deduced dimension is unknown, evaluate the binding and try again.
if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then
exp := Ceval.evalExp(b.bindingExp, Ceval.EvalTarget.DIMENSION(component, index, b.bindingExp, info));
(dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index);
end if;
then
(dim, ty_err);

end match;

() := match ty_err
Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -710,6 +710,7 @@ RecordConstructor1.mo \
RecordConstructor2.mo \
RecordExtends1.mo \
RecordExtends2.mo \
RecordUnknownDim1.mo \
RecursiveExtends1.mo \
RecursiveExtends3.mo \
RecursiveInst1.mo \
Expand Down
33 changes: 33 additions & 0 deletions testsuite/flattening/modelica/scodeinst/RecordUnknownDim1.mo
@@ -0,0 +1,33 @@
// name: RecordUnknownDim1
// keywords:
// status: correct
// cflags: -d=newInst
//
//

record R2
Integer i[:];
end R2;

record R
R2 r;
end R;

function f
output R2 r;
algorithm
r := R2({1, 2});
end f;

model RecordUnknownDim1
R r = R(f());
end RecordUnknownDim1;

// Result:
// class RecordUnknownDim1
// Integer r.r.i[1];
// Integer r.r.i[2];
// equation
// r.r.i = {1, 2};
// end RecordUnknownDim1;
// endResult

0 comments on commit c6029d1

Please sign in to comment.