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

Commit

Permalink
NFInst improvements.
Browse files Browse the repository at this point in the history
- Improved the type checking of bindings to handle binding dimensions.
- Improved deduction of array dimensions to handle binding dimensions.
- Improved flattening of array bindings.
- Implemented better detection of typenames during name lookup.
- Fixed prefixing of inherited redeclared elements.
- Implemented better support for enumeration ranges.
  • Loading branch information
perost authored and OpenModelica-Hudson committed Sep 12, 2017
1 parent e2dfbf6 commit 62dc75d
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 82 deletions.
20 changes: 2 additions & 18 deletions Compiler/FrontEnd/InstVar.mo
Original file line number Diff line number Diff line change
Expand Up @@ -811,23 +811,6 @@ algorithm
Absyn.Path path;
list<DAE.Var> vars;

/*
case (cache,env,ih,store,ci_state,mod,pre,n,cl,attr,pf,dims,idxs,inst_dims,impl,comment,info,graph,csets)
equation
true = SCode.isPartial(cl);
//Do not flatten because it is a function
dims_1 = InstUtil.instDimExpLst(dims, impl);
(cache,env_1,ih,ci_state,vars) = Inst.partialInstClassIn(cache, env, ih, mod, pre, ci_state, cl, SCode.PUBLIC(), inst_dims, 0);
dae = DAE.emptyDae;
(cache, path) = Inst.makeFullyQualified(cache, env, Absyn.IDENT(n));
ty = DAE.T_COMPLEX(ci_state, vars, NONE(), {path});
ty = InstUtil.makeArrayType(dims, ty);
then
(cache,env_1,ih,store,dae,csets,ty,graph);*/


// Rules for instantation of function variables (e.g. input and output

// Function variables with modifiers (outputs or local/protected variables)
Expand Down Expand Up @@ -1035,7 +1018,8 @@ algorithm
case (_,_,_,_,_,DAE.NOMOD(),_,n,_,_,_,
((DAE.DIM_UNKNOWN()) :: _),_,_,_,_,info,_,_)
equation
Error.addSourceMessage(Error.FAILURE_TO_DEDUCE_DIMS_NO_MOD,{n},info);
Error.addSourceMessage(Error.FAILURE_TO_DEDUCE_DIMS_NO_MOD,
{String(listLength(inSubscripts) + 1), n},info);
then
fail();

Expand Down
15 changes: 7 additions & 8 deletions Compiler/NFFrontEnd/NFBinding.mo
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,30 @@ public
record RAW_BINDING
Absyn.Exp bindingExp;
InstNode scope;
Integer propagatedDims;
Integer propagatedLevels;
SourceInfo info;
end RAW_BINDING;

record UNTYPED_BINDING
Expression bindingExp;
Boolean isProcessing;
InstNode scope;
Integer propagatedDims;
Integer propagatedLevels;
SourceInfo info;
end UNTYPED_BINDING;

record TYPED_BINDING
Expression bindingExp;
Type bindingType;
DAE.Const variability;
Integer propagatedDims;
Integer propagatedLevels;
SourceInfo info;
end TYPED_BINDING;

public
function fromAbsyn
input Option<Absyn.Exp> bindingExp;
input SCode.Each eachPrefix;
input Integer dimensions;
input InstNode scope;
input SourceInfo info;
output Binding binding;
Expand All @@ -83,7 +82,7 @@ public

case SOME(exp)
algorithm
pd := if SCode.eachBool(eachPrefix) then -1 else dimensions;
pd := if SCode.eachBool(eachPrefix) then -1 else 0;
then
RAW_BINDING(exp, scope, pd, info);

Expand Down Expand Up @@ -175,9 +174,9 @@ public
output Boolean isEach;
algorithm
isEach := match binding
case RAW_BINDING() then binding.propagatedDims == -1;
case UNTYPED_BINDING() then binding.propagatedDims == -1;
case TYPED_BINDING() then binding.propagatedDims == -1;
case RAW_BINDING() then binding.propagatedLevels == -1;
case UNTYPED_BINDING() then binding.propagatedLevels == -1;
case TYPED_BINDING() then binding.propagatedLevels == -1;
else false;
end match;
end isEach;
Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFClassTree.mo
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ public
// Make a new extends array, and recursively instantiate the extends nodes.
exts := arrayCopy(exts);
for i in 1:arrayLength(exts) loop
(node, _, cls_count, comp_count) := instantiate(exts[i]);
(node, _, cls_count, comp_count) := instantiate(exts[i], instance);
exts[i] := node;
// Add the inherited elements to the class/component counts.
classCount := cls_count + classCount;
Expand Down
13 changes: 9 additions & 4 deletions Compiler/NFFrontEnd/NFFlatten.mo
Original file line number Diff line number Diff line change
Expand Up @@ -314,19 +314,24 @@ function flattenFunctionParams
protected
InstNode node;
Component comp;
ComponentRef prefix;
Type ty;
algorithm
for i in arrayLength(components):-1:1 loop
node := components[i];
comp := InstNode.component(node);
ty := Component.getType(comp);
prefix := ComponentRef.fromNode(node, ty, {});

(elements, funcs) :=
flattenFunctionParam(comp, InstNode.name(node), elements, funcs);
flattenFunctionParam(comp, InstNode.name(node), prefix, elements, funcs);
end for;
end flattenFunctionParams;

function flattenFunctionParam
input Component component;
input String name;
input ComponentRef prefix;
input output list<DAE.Element> elements;
input output DAE.FunctionTree funcs;
algorithm
Expand All @@ -350,7 +355,7 @@ algorithm
cref := DAE.CREF_IDENT(name, ty, {});
attr := component.attributes;
(binding_exp, funcs) :=
flattenBinding(component.binding, ComponentRef.EMPTY(), funcs);
flattenBinding(component.binding, prefix, funcs);

var_attr := match i
case Class.INSTANCED_BUILTIN()
Expand Down Expand Up @@ -416,10 +421,10 @@ algorithm

case Binding.TYPED_BINDING()
algorithm
if binding.propagatedDims <= 0 then
if binding.propagatedLevels < 0 then
e := binding.bindingExp;
else
subs := List.lastN(List.flatten(ComponentRef.allSubscripts(prefix)), binding.propagatedDims);
subs := List.flatten(List.lastN(ComponentRef.allSubscripts(prefix), binding.propagatedLevels + 1));
e := Expression.subscript(binding.bindingExp, subs);
end if;

Expand Down
12 changes: 6 additions & 6 deletions Compiler/NFFrontEnd/NFInst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -806,14 +806,14 @@ algorithm

dims := list(Dimension.RAW_DIM(d) for d in def.attributes.arrayDims);
Modifier.checkEach(comp_mod, listEmpty(dims), InstNode.name(node));
comp_mod := Modifier.propagate(comp_mod, listLength(dims));
binding := Modifier.binding(comp_mod);
comp_mod := Modifier.propagate(comp_mod);

// Instantiate the type of the component.
cls := instTypeSpec(def.typeSpec, comp_mod, scope, node, def.info);

// Instantiate attributes and create the untyped components.
attr := instComponentAttributes(def.attributes, def.prefixes);
binding := Modifier.binding(comp_mod);
inst_comp := Component.UNTYPED_COMPONENT(cls, listArray(dims), binding,
attr, SCode.isElementRedeclare(def), def.info);
InstNode.updateComponent(inst_comp, node);
Expand Down Expand Up @@ -909,7 +909,7 @@ algorithm
algorithm
// Instantiate expressions in the extends nodes.
sections := ClassTree.foldExtends(cls_tree,
function instExpressions(scope = node), sections);
function instExpressions(scope = scope), sections);

// Instantiate expressions in the local components.
ClassTree.applyLocalComponents(cls_tree,
Expand Down Expand Up @@ -1036,7 +1036,7 @@ algorithm
algorithm
bind_exp := instExp(binding.bindingExp, binding.scope, binding.info, allowTypename);
then
Binding.UNTYPED_BINDING(bind_exp, false, binding.scope, binding.propagatedDims, binding.info);
Binding.UNTYPED_BINDING(bind_exp, false, binding.scope, binding.propagatedLevels, binding.info);

else binding;
end match;
Expand Down Expand Up @@ -1385,7 +1385,7 @@ algorithm

case SCode.EEquation.EQ_FOR(info = info)
algorithm
binding := Binding.fromAbsyn(scodeEq.range, SCode.NOT_EACH(), 0, scope, info);
binding := Binding.fromAbsyn(scodeEq.range, SCode.NOT_EACH(), scope, info);
binding := instBinding(binding, allowTypename = true);

(for_scope, iter) := addIteratorToScope(scodeEq.index, binding, info, scope);
Expand Down Expand Up @@ -1513,7 +1513,7 @@ algorithm

case SCode.Statement.ALG_FOR(info = info)
algorithm
binding := Binding.fromAbsyn(scodeStmt.range, SCode.NOT_EACH(), 0, scope, info);
binding := Binding.fromAbsyn(scodeStmt.range, SCode.NOT_EACH(), scope, info);
binding := instBinding(binding, allowTypename = true);

(for_scope, iter) := addIteratorToScope(scodeStmt.index, binding, info, scope);
Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFLookup.mo
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ protected
Type ty;
algorithm
if InstNode.isClass(component) then
ty := Class.getType(InstNode.getClass(component));
ty := Class.getType(InstNode.getClass(Inst.expand(component)));

state := match ty
case Type.ENUMERATION() then LookupState.STATE_COMP();
Expand Down
47 changes: 24 additions & 23 deletions Compiler/NFFrontEnd/NFMod.mo
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public

case SCode.MOD()
algorithm
binding := Binding.fromAbsyn(mod.binding, mod.eachPrefix, 0, scope, mod.info);
binding := Binding.fromAbsyn(mod.binding, mod.eachPrefix, scope, mod.info);
submod_lst := list((m.ident, createSubMod(m, modScope, scope)) for m in mod.subModLst);
submod_table := ModTable.fromList(submod_lst,
function mergeLocal(scope = modScope, prefix = {}));
Expand Down Expand Up @@ -326,34 +326,39 @@ public
checking, so that it matches the binding. To do this we need to now how many
dimensions the binding has been propagated through. In this case it's been
propagated from B.a to A.x, and since B.a has one dimension we should add
that dimension to A.x to make it match the binding. The number of dimensions
that a binding is propagated through is therefore saved in a binding. A
binding can also have the 'each' prefix, meaning that the binding should be
applied as it is. In that case we set the dimension counter to -1 and don't
increment it when the binding is propagated.
that dimension to A.x to make it match the binding. The number of levels a
binding is propagated through is therefore saved in each binding. A binding
can also have the 'each' prefix, meaning that the binding should be applied
as it is. In that case we set the level counter to -1 and don't increment
it when the binding is propagated.

This function simply goes through a modifier recursively and increments the
dimension counter by the number of dimensions that an element has."
level counter by 1 for all bindings in the modifier, but will not traverse
into submodifiers that have the 'each' prefix."
input output Modifier modifier;
input Integer dimensions;
algorithm
if dimensions == 0 then
return;
end if;

_ := match modifier
case MODIFIER()
algorithm
modifier.binding := propagateBinding(modifier.binding, dimensions);
modifier.subModifiers := ModTable.map(modifier.subModifiers,
function propagateSubMod(dimensions = dimensions));
modifier.binding := propagateBinding(modifier.binding);
modifier.subModifiers := ModTable.map(modifier.subModifiers, propagateSubMod);
then
();

else ();
end match;
end propagate;

function isEach
input Modifier mod;
output Boolean isEach;
algorithm
isEach := match mod
case MODIFIER(eachPrefix = SCode.EACH()) then true;
else false;
end match;
end isEach;

function checkEach
input Modifier mod;
input Boolean isScalar;
Expand Down Expand Up @@ -489,23 +494,19 @@ protected
function propagateSubMod
input String name;
input output Modifier modifier;
input Integer dimensions;
algorithm
modifier := propagate(modifier, dimensions);
if not isEach(modifier) then
modifier := propagate(modifier);
end if;
end propagateSubMod;

function propagateBinding
input output Binding binding;
input Integer dimensions;
algorithm
_ := match binding
// Special case for the each prefix, don't do anything.
case Binding.RAW_BINDING(propagatedDims = -1) then ();

// A normal binding, increment with the dimension count.
case Binding.RAW_BINDING()
algorithm
binding.propagatedDims := binding.propagatedDims + dimensions;
binding.propagatedLevels := binding.propagatedLevels + 1;
then
();

Expand Down
25 changes: 25 additions & 0 deletions Compiler/NFFrontEnd/NFRangeIterator.mo
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public
Integer istart, istep, istop;
Real rstart, rstep, rstop;
Type ty;
list<String> literals;
Absyn.Path path;
list<Expression> values;

case Expression.ARRAY() then ARRAY_RANGE(exp.elements);

Expand All @@ -86,6 +89,28 @@ public
stop = Expression.REAL(rstop))
then REAL_RANGE(rstart, 1.0, rstop);

case Expression.RANGE(start = Expression.ENUM_LITERAL(ty = ty, index = istart),
step = NONE(),
stop = Expression.ENUM_LITERAL(index = istop))
algorithm
Type.ENUMERATION(typePath = path, literals = literals) := ty;
values := {};

if istart <= istop then
for i in 2:istart loop
literals := listRest(literals);
end for;

for i in istart:istop loop
values := Expression.ENUM_LITERAL(ty, listHead(literals), i) :: values;
literals := listRest(literals);
end for;

values := listReverse(values);
end if;
then
ARRAY_RANGE(values);

else
algorithm
assert(false, getInstanceName() + " got unknown range");
Expand Down
32 changes: 21 additions & 11 deletions Compiler/NFFrontEnd/NFType.mo
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ public
end if;
end unliftArray;

function unliftArrayN
input Integer N;
input output Type ty;
protected
Type el_ty;
list<Dimension> dims;
algorithm
ARRAY(el_ty, dims) := ty;

for i in 1:N loop
dims := listRest(dims);
end for;

if listEmpty(dims) then
ty := el_ty;
else
ty := ARRAY(el_ty, dims);
end if;
end unliftArrayN;

function isInteger
input Type ty;
output Boolean isInteger;
Expand Down Expand Up @@ -321,20 +341,10 @@ public
dims := match ty
case ARRAY() then ty.dimensions;
case FUNCTION() then arrayDims(ty.resultType);
else {};
end match;
end arrayDims;

function getTypeDims
input Type ty;
output list<Dimension> dims;
algorithm
try
dims := arrayDims(ty);
else
dims := {};
end try;
end getTypeDims;

function nthDimension
input Type ty;
input Integer index;
Expand Down

0 comments on commit 62dc75d

Please sign in to comment.