Skip to content

Commit

Permalink
Cleaned up the handling of for loop iterators in Cevalfunc, Inst and …
Browse files Browse the repository at this point in the history
…Static a bit.

Added some more comments to the new array constructor code in Static.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@4787 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Jan 15, 2010
1 parent 88b81f3 commit 7eb1e7f
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 99 deletions.
40 changes: 16 additions & 24 deletions Compiler/Cevalfunc.mo
Expand Up @@ -35,8 +35,6 @@ protected import UnitAbsyn;
protected import ValuesUtil;
protected import ErrorExt;

protected constant String forScopeName="$for loop scope$";

public function cevalUserFunc "Function: cevalUserFunc
This is the main funciton for the class. It will take a userdefined function and \"try\" to
evaluate it. This is to prevent multiple compilation of c files.
Expand Down Expand Up @@ -600,8 +598,7 @@ algorithm
case(env, Absyn.ALG_FOR({(varName, SOME(Absyn.RANGE(start=ae1,step=NONE, stop=ae2)))},forBody = algitemlst),ht2)
equation
start = evaluateSingleExpression(ae1,env,NONE,ht2);
ty = Types.typeOfValue(start);
env1 = addForLoopScope(env,varName,ty);
env1 = addForLoopScope(env,varName,start);
stop = evaluateSingleExpression(ae2,env1,NONE,ht2);
step = Values.INTEGER(1);
env2 = evaluateForLoopRange(env1, varName, algitemlst, start, step, stop, ht2);
Expand All @@ -610,8 +607,7 @@ algorithm
case(env, Absyn.ALG_FOR({(varName, SOME(Absyn.RANGE(start=ae1, step=SOME(ae2), stop=ae3)))},forBody = algitemlst),ht2)
equation
start = evaluateSingleExpression(ae1,env,NONE,ht2);
ty = Types.typeOfValue(start);
env1 = addForLoopScope(env,varName,ty);
env1 = addForLoopScope(env,varName,start);
stop = evaluateSingleExpression(ae3,env1,NONE,ht2);
step = evaluateSingleExpression(ae2,env1,NONE,ht2);
env2 = evaluateForLoopRange(env1, varName, algitemlst, start, step, stop, ht2);
Expand All @@ -621,8 +617,7 @@ algorithm
equation
(Values.ARRAY(values)) = evaluateSingleExpression(ae1, env,NONE,ht2);
start = listNth(values,0);
ty = Types.typeOfValue(start);
env1 = addForLoopScope(env,varName,ty);
env1 = addForLoopScope(env,varName,start);
env2 = evaluateForLoopArray(env1, varName, values, algitemlst, ht2);
then
env2;
Expand Down Expand Up @@ -989,22 +984,19 @@ algorithm outVal := matchcontinue(inVal,env,toAssign)
end matchcontinue;
end setValue;

protected function addForLoopScope "function: addForLoopScope
Adds a scope on the environment used in for loops.
The name of the scope is for_scope_name, defined as a value.
"
input Env.Env env;
input String i;
input DAE.Type typ;
output Env.Env env_2;
list<Env.Frame> env_1,env_2;
Values.Value baseValue;
algorithm
baseValue := typeOfValue(typ);
env_1 := Env.openScope(env, false, SOME(forScopeName));
env_2 := Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RW(),SCode.VAR(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,typ,DAE.VALBOUND(baseValue)), NONE, Env.VAR_UNTYPED(), {}) "comp env" ;
protected function addForLoopScope
"Adds a scope in the environment used in for loops."
input Env.Env env;
input String iterName;
input Values.Value startValue;
output Env.Env newEnv;
DAE.Type baseType;
Values.Value baseValue;
algorithm
baseType := Types.typeOfValue(startValue);
baseValue := typeOfValue(baseType);
newEnv := Env.openScope(env, false, SOME(Env.forScopeName));
newEnv := Env.extendFrameForIterator(newEnv, iterName, baseType, DAE.VALBOUND(baseValue), SCode.VAR);
end addForLoopScope;

protected function setQualValue "Function: setQualValue
Expand Down
42 changes: 41 additions & 1 deletion Compiler/Env.mo
Expand Up @@ -193,6 +193,9 @@ algorithm
cache := CACHE(arr,NONE);
end emptyCache;

public
constant String forScopeName="$for loop scope$" "a unique scope used in for equations";

// functions for dealing with the environment

public function newFrame "function: newFrame
Expand Down Expand Up @@ -292,7 +295,7 @@ algorithm
outEnv := matchcontinue(env)
local String name;
case(FRAME(optName = SOME(name))::env) equation
equality(name=Inst.forScopeName);
equality(name=forScopeName);
env = stripForLoopScope(env);
then env;
case(env) then env;
Expand Down Expand Up @@ -654,6 +657,43 @@ algorithm
end matchcontinue;
end extendFrameDefunit;

public function extendFrameForIterator
"Adds a for loop iterator to the environment."
input Env env;
input String name;
input DAE.Type type_;
input DAE.Binding binding;
input SCode.Variability variability;
output Env new_env;
algorithm
new_env := matchcontinue(env, name, type_, binding, variability)
local
Env new_env_1;
case (_, _, _, _, SCode.VAR())
equation
new_env_1 = extendFrameV(env,
DAE.TYPES_VAR(
name,
DAE.ATTR(false, false, SCode.RW(), SCode.VAR(), Absyn.BIDIR(), Absyn.UNSPECIFIED()),
false,
type_,
binding),
NONE, VAR_UNTYPED(), {});
then new_env_1;
case (_, _, _, _, SCode.CONST())
equation
new_env_1 = extendFrameV(env,
DAE.TYPES_VAR(
name,
DAE.ATTR(false, false, SCode.RO(), SCode.CONST(), Absyn.BIDIR(), Absyn.UNSPECIFIED()),
true,
type_,
binding),
NONE, VAR_UNTYPED(), {});
then new_env_1;
end matchcontinue;
end extendFrameForIterator;

protected function memberImportList "Returns true if import exist in imps"
input list<Item> imps;
input Absyn.Import imp;
Expand Down
39 changes: 13 additions & 26 deletions Compiler/Inst.mo
Expand Up @@ -129,9 +129,6 @@ uniontype DimExp "a dimension expresion"
end DIMEXP;
end DimExp;

public
constant String forScopeName="$for loop scope$" "a unique scope used in for equations";

// protected imports
protected import Algorithm;
protected import Builtin;
Expand Down Expand Up @@ -11429,21 +11426,15 @@ algorithm
end matchcontinue;
end instEquationCommonCiTrans;

protected function addForLoopScope
"function: addForLoopScope
author: HJ
Adds a scope on the environment used in for loops.
The name of the scope is for_scope_name, defined as a value."
input Env env;
input Ident i;
input DAE.Type typ;
output Env env_2;
list<Env.Frame> env_1,env_2;
algorithm
env_1 := Env.openScope(env, false, SOME(forScopeName));
env_2 := Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RW(),SCode.VAR(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,typ,DAE.UNBOUND()), NONE, Env.VAR_UNTYPED(), {}) "comp env" ;
protected function addForLoopScope
"Adds a scope to the environment used in for loops."
input Env env;
input Ident iterName;
input DAE.Type iterType;
output Env newEnv;
algorithm
newEnv := Env.openScope(env, false, SOME(Env.forScopeName));
newEnv := Env.extendFrameForIterator(newEnv, iterName, iterType, DAE.UNBOUND(), SCode.VAR());
end addForLoopScope;

protected function instEqEquation
Expand Down Expand Up @@ -11847,21 +11838,17 @@ algorithm
case (cache,_,_,_,csets,_,_,Values.ARRAY(valueLst = {}),_,_,_,graph) then (cache,{},csets,graph); /* impl */
case (cache,env,mods,pre,csets,ci_state,i,Values.ARRAY(valueLst = (fst :: rest)),eqs,(initial_ as SCode.NON_INITIAL()),impl,graph)
equation
env_1 = Env.openScope(env, false, SOME(forScopeName));
env_2 = Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RO(),SCode.CONST(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
true,(DAE.T_INTEGER({}),NONE),DAE.VALBOUND(fst)), NONE, Env.VAR_UNTYPED(), {}) "comp env" ;
env_1 = Env.openScope(env, false, SOME(Env.forScopeName));
env_2 = Env.extendFrameForIterator(env_1, i, (DAE.T_INTEGER({}), NONE), DAE.VALBOUND(fst), SCode.CONST());
(cache,env_3,_,dae1,csets_1,ci_state_1,graph) = instList(cache,env_2,InstanceHierarchy.emptyInstanceHierarchy, mods, pre, csets, ci_state, instEEquation, eqs, impl,graph);
(cache,dae2,csets_2,graph) = unroll(cache,env, mods, pre, csets_1, ci_state_1, i, Values.ARRAY(rest), eqs, initial_, impl,graph);
dae = listAppend(dae1, dae2);
then
(cache,dae,csets_2,graph);
case (cache,env,mods,pre,csets,ci_state,i,Values.ARRAY(valueLst = (fst :: rest)),eqs,(initial_ as SCode.INITIAL()),impl,graph)
equation
env_1 = Env.openScope(env, false, SOME(forScopeName));
env_2 = Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RO(),SCode.CONST(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
true,(DAE.T_INTEGER({}),NONE),DAE.VALBOUND(fst)), NONE, Env.VAR_UNTYPED(), {}) "comp env" ;
env_1 = Env.openScope(env, false, SOME(Env.forScopeName));
env_2 = Env.extendFrameForIterator(env_1, i, (DAE.T_INTEGER({}), NONE), DAE.VALBOUND(fst), SCode.CONST());
(cache,env_3,_,dae1,csets_1,ci_state_1,graph) = instList(cache,env_2,InstanceHierarchy.emptyInstanceHierarchy, mods, pre, csets, ci_state, instEInitialequation, eqs, impl,graph);
(cache,dae2,csets_2,graph) = unroll(cache,env, mods, pre, csets_1, ci_state_1, i, Values.ARRAY(rest), eqs, initial_, impl,graph);
dae = listAppend(dae1, dae2);
Expand Down
65 changes: 17 additions & 48 deletions Compiler/Static.mo
Expand Up @@ -1293,48 +1293,6 @@ algorithm
end matchcontinue;
end matrixConstrMaxDim;

protected function addForLoopScopeConst "function: addForLoopScopeConst

Creates a new scope on the environment used for loops and adds a loop
variable which is named by the second argument. The variable is given
the value 1 (one) such that elaboration of expressions of containing the
loop variable become constant.
"
input Env.Env env;
input Ident i;
input DAE.Type typ;
output Env.Env env_2;
list<Env.Frame> env_1,env_2; // Two env_2?
algorithm
env_1 := Env.openScope(env, false, SOME("$for loop scope$")) "encapsulated?" ;
// Defining the iterator as a parameter causes it to be constant evaluated in
// cases such as 'r[i] for i in 1:n' => 'r[1]', so it should probably be a
// variable instead.
/*env_2 := Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RW(),SCode.PARAM(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,typ,DAE.VALBOUND(Values.INTEGER(1))), NONE, Env.VAR_UNTYPED(), {});*/
env_2 := Env.extendFrameV(env_1,
DAE.TYPES_VAR(i,DAE.ATTR(false,false,SCode.RW(),SCode.VAR(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,typ,DAE.UNBOUND()), NONE, Env.VAR_UNTYPED(), {});
end addForLoopScopeConst;

protected function addForLoopIterator
"Adds an iterator variable to the current scope."
input Env.Env env;
input Ident iterName;
input DAE.Type iterType;
output Env.Env new_env;
algorithm
new_env := Env.extendFrameV(env,
DAE.TYPES_VAR(
iterName,
DAE.ATTR(false, false, SCode.RW(), SCode.VAR(), Absyn.BIDIR(), Absyn.UNSPECIFIED()),
false,
iterType,
DAE.UNBOUND()),
NONE, Env.VAR_UNTYPED(), {});
end addForLoopIterator;

protected function elabCallReduction
"function: elabCallReduction
This function elaborates reduction expressions, that look like function
Expand Down Expand Up @@ -1374,14 +1332,20 @@ algorithm
list<Values.Value> vallst;
/*Symbolically expand arrays if iterator is parameter or constant
*/
case (cache,env,Absyn.CREF_IDENT("array",{}),exp,(afis as (iter,SOME(iterexp))::{}),impl,st,doVect)
/* peros - 2010-01-15
* This case only works for one iterator, but since the next case that takes
* care of any number of iterators was implemented it should no longer be
* needed. This case might be slightly faster than the general case though,
* so I'm leaving it here for a while to see if someone complains. */
/*case (cache,env,Absyn.CREF_IDENT("array",{}),exp,(afis as (iter,SOME(iterexp))::{}),impl,st,doVect)
local
Absyn.ForIterators afis;
equation
(cache,iterexp_1,DAE.PROP((DAE.T_ARRAY((arraydim as DAE.DIM(_)),iterty),_),iterconst),_)
= elabExp(cache,env, iterexp, impl, st,doVect);
true = Types.isParameterOrConstant(iterconst);
env_1 = addForLoopScopeConst(env, iter, iterty);
env_1 = Env.openScope(env, false, SOME(Env.forScopeName));
env_1 = Env.extendFrameForIterator(env_1, iter, iterty, DAE.UNBOUND(), SCode.VAR());
(cache,Values.ARRAY(vallst),_) = Ceval.ceval(cache,env, iterexp_1, impl, NONE, NONE, Ceval.MSG());
(cache,exp_1,DAE.PROP(expty,expconst),st) = elabExp(cache,env_1, exp, impl, st,doVect) "const so that expr is elaborated to const" ;
expl = elabCallReduction2(exp_1, vallst, iter);
Expand All @@ -1391,7 +1355,7 @@ algorithm
const = Types.constAnd(expconst, iterconst);
prop = DAE.PROP(ty,const);
then
(cache,DAE.ARRAY(etp,b,expl),prop,st);
(cache,DAE.ARRAY(etp,b,expl),prop,st);*/
case (cache, env, Absyn.CREF_IDENT("array", {}), exp, iterators, impl, st, doVect)
local
list<list<Values.Value>> vals;
Expand All @@ -1413,7 +1377,8 @@ algorithm
equation
(cache,iterexp_1,DAE.PROP((DAE.T_ARRAY((arraydim as DAE.DIM(_)),iterty),_),iterconst),_)
= elabExp(cache,env, iterexp, impl, st,doVect);
env_1 = addForLoopScopeConst(env, iter, iterty);
env_1 = Env.openScope(env, false, SOME(Env.forScopeName));
env_1 = Env.extendFrameForIterator(env_1, iter, iterty, DAE.UNBOUND(), SCode.VAR());
(cache,exp_1,DAE.PROP(expty,expconst),st) = elabExp(cache,env_1, exp, impl, st,doVect) "const so that expr is elaborated to const" ;
const = Types.constAnd(expconst, iterconst);
prop = DAE.PROP((DAE.T_ARRAY(arraydim,expty),NONE),const);
Expand All @@ -1428,6 +1393,7 @@ algorithm
end elabCallReduction;

protected function elabArrayIterators
"Elaborates array constructors such as 'array(i for i in 1:5)'"
input Env.Cache cache;
input Env.Env env;
input Absyn.ForIterators iterators;
Expand Down Expand Up @@ -1457,7 +1423,7 @@ algorithm
list<list<Values.Value>> iter_values_list;
case (_, _, {}, _, _, _)
equation
new_env = Env.openScope(env, false, SOME("$for loop scope$"));
new_env = Env.openScope(env, false, SOME(Env.forScopeName));
then (cache, new_env, DAE.C_CONST(), {}, {}, DAE.DIM(SOME(1)));
case (_, _, (iter_name, SOME(iter_exp)) :: rest_iters, _, _, _)
equation
Expand All @@ -1470,7 +1436,7 @@ algorithm
(new_cache, Values.ARRAY(iter_values), _)
= Ceval.ceval(new_cache, env, iter_exp, implicitInstantiation, NONE, NONE, Ceval.MSG());
true = Types.isParameterOrConstant(iter_const);
new_env = addForLoopIterator(new_env, iter_name, iter_type);
new_env = Env.extendFrameForIterator(new_env, iter_name, iter_type, DAE.UNBOUND(), SCode.VAR());
iters_const = Types.constAnd(iters_const, iter_const);
arrays_dim = arrayDimMultiply(arrays_dim, array_dim);
then (new_cache, new_env, iters_const, iter_values :: iter_values_list, iter_name :: iter_names, arrays_dim);
Expand All @@ -1496,6 +1462,9 @@ algorithm
end arrayDimMultiply;

protected function expandArray
"Symbolically expands an array with the help of elabCallReduction2."
/* Example: expandArray({{1, 2, 3}, {4, 5}}, {"i", "j"}, i + j) =
{1 + 4, 1 + 5, 2 + 4, 2 + 5, 3 + 4, 3 + 5} */
input list<list<Values.Value>> valLists;
input list<Ident> iteratorNames;
input list<DAE.Exp> expl;
Expand Down

0 comments on commit 7eb1e7f

Please sign in to comment.