Skip to content

Commit

Permalink
Changed how elaboration of multiple iterators in array constructors a…
Browse files Browse the repository at this point in the history
…re handled

(multiple iterators give multi-dimensional arrays, not a flattened
one-dimensional array).


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@4824 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Jan 20, 2010
1 parent c59eb1d commit 392e019
Showing 1 changed file with 57 additions and 49 deletions.
106 changes: 57 additions & 49 deletions Compiler/Static.mo
Expand Up @@ -1360,19 +1360,19 @@ algorithm
local
list<list<Values.Value>> vals;
list<Ident> iter_names;
DAE.Type array_type;
equation
(cache, env, iterconst, vals, iter_names, arraydim)
(cache, env, iterconst, vals, iter_names, array_type)
= elabArrayIterators(cache, env, iterators, impl, st, doVect);
(cache, exp_1, DAE.PROP(expty, expconst), st)
= elabExp(cache, env, exp, impl, st, doVect);
expl = expandArray(vals, iter_names, {exp_1});
ty = (DAE.T_ARRAY(arraydim, expty), NONE);
(cache, exp_1, DAE.PROP(expty, expconst), st) = elabExp(cache, env, exp, impl, st, doVect);
b = not Types.isArray(expty);
etp = Types.elabType(ty);
ty = constructArrayType(array_type, expty);
etp = Types.elabType(ty);
exp_1 = expandArray(exp_1, vals, iter_names, b, etp);
const = Types.constAnd(expconst, iterconst);
prop = DAE.PROP(ty, const);
then
(cache, DAE.ARRAY(etp, b, expl), prop, st);
(cache, exp_1, prop, st);
case (cache,env,fn,exp,{(iter,SOME(iterexp))},impl,st,doVect)
equation
(cache,iterexp_1,DAE.PROP((DAE.T_ARRAY((arraydim as DAE.DIM(_)),iterty),_),iterconst),_)
Expand Down Expand Up @@ -1405,7 +1405,7 @@ protected function elabArrayIterators
output DAE.Const const;
output list<list<Values.Value>> iteratorValues;
output list<Ident> iteratorNames;
output DAE.ArrayDim arrayDim;
output DAE.Type arrayType;
algorithm
(newCache, newEnv, const, iteratorValues, iteratorNames, arrayDim) :=
matchcontinue(cache, env, iterators, implicitInstantiation, st, performVectorization)
Expand All @@ -1417,75 +1417,58 @@ algorithm
Env.Cache new_cache;
Env.Env new_env;
DAE.Const iter_const, iters_const;
DAE.ArrayDim array_dim, arrays_dim;
DAE.Type iter_type;
DAE.ArrayDim array_dim;
DAE.Type array_type, iter_type;
list<Values.Value> iter_values;
list<list<Values.Value>> iter_values_list;
case (_, _, {}, _, _, _)
equation
new_env = Env.openScope(env, false, SOME(Env.forScopeName));
then (cache, new_env, DAE.C_CONST(), {}, {}, DAE.DIM(SOME(1)));
// Return the type T_NOTYPE as a placeholder. constructArrayType is
// later used by cevalCallReduction to replace it with the correct type.
then (cache, new_env, DAE.C_CONST(), {}, {}, (DAE.T_NOTYPE(), NONE));
case (_, _, (iter_name, SOME(iter_exp)) :: rest_iters, _, _, _)
equation
(new_cache, new_env, iters_const, iter_values_list, iter_names, arrays_dim)
(new_cache, new_env, iters_const, iter_values_list, iter_names, array_type)
= elabArrayIterators(cache, env, rest_iters, implicitInstantiation, st, performVectorization);
(new_cache, iter_exp, DAE.PROP(
type_ = (DAE.T_ARRAY(arrayDim = array_dim, arrayType = iter_type), _),
constFlag = iter_const), _)
// Elaborate the iterator expression to get the iterators type and dimension of the generated array.
(new_cache, iter_exp, DAE.PROP((DAE.T_ARRAY(arrayDim = array_dim, arrayType = iter_type), _), constFlag = iter_const), _)
= elabExp(cache, env, iter_exp, implicitInstantiation, st, performVectorization);
// Use ceval to get a list of values generated by the iterator expression.
(new_cache, Values.ARRAY(iter_values), _)
= Ceval.ceval(new_cache, env, iter_exp, implicitInstantiation, NONE, NONE, Ceval.MSG());
true = Types.isParameterOrConstant(iter_const);
// Add the iterator to the environment so that the array constructor
// expression can be elaborated later.
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);
then (new_cache, new_env, iters_const, iter_values :: iter_values_list, iter_name :: iter_names, (DAE.T_ARRAY(array_dim, array_type), NONE));
end matchcontinue;
end elabArrayIterators;

protected function arrayDimMultiply
"Multiplies two array dimensions, or fails if either of the dimensions are
unspecified."
input DAE.ArrayDim dim1;
input DAE.ArrayDim dim2;
output DAE.ArrayDim res;
algorithm
res := matchcontinue(dim1, dim2)
local
Integer d1, d2, r;
case (DAE.DIM(SOME(d1)), DAE.DIM(SOME(d2)))
equation
r = d1 * d2;
then DAE.DIM(SOME(r));
case (_, _) then fail();
end matchcontinue;
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 DAE.Exp expr;
input list<list<Values.Value>> valLists;
input list<Ident> iteratorNames;
input list<DAE.Exp> expl;
output list<DAE.Exp> expandedExpl;
input Boolean isArray;
input DAE.ExpType arrayType;
output DAE.Exp expandedExp;
algorithm
expandedExpl := matchcontinue(valLists, iteratorNames, expl)
expandedExp := matchcontinue(expr, valLists, iteratorNames, isArray, arrayType)
local
list<Values.Value> values;
list<list<Values.Value>> rest_values;
Ident iterator_name;
list<Ident> rest_iterators;
list<list<DAE.Exp>> new_expl;
list<DAE.Exp> flattened_expl, expanded_expl;
case ({}, {}, _) then expl;
case (values :: rest_values, iterator_name :: rest_iterators, _)
list<DAE.Exp> new_expl, expanded_expl;
case (_, {}, {}, _, _) then expr;
case (_, values :: rest_values, iterator_name :: rest_iterators, _, _)
equation
new_expl = Util.listMap2(expl, elabCallReduction2, values, iterator_name);
flattened_expl = Util.listFlatten(new_expl);
expanded_expl = expandArray(rest_values, rest_iterators, flattened_expl);
then expanded_expl;
end matchcontinue;
expanded_expl = elabCallReduction2(expr, values, iterator_name);
new_expl = Util.listMap4(expanded_expl, expandArray, rest_values, rest_iterators, isArray, arrayType);
then DAE.ARRAY(arrayType, isArray, new_expl);
end matchcontinue;
end expandArray;

protected function elabCallReduction2 "help function to elabCallReduction. symbolically expands arrays"
Expand All @@ -1505,6 +1488,31 @@ algorithm
end matchcontinue;
end elabCallReduction2;

protected function constructArrayType
"Helper function for elabCallReduction. Combines the type of the expression in
an array constructor with the type of the generated array by replacing the
placeholder T_NOTYPE in arrayType with expType. Example:
r[i] for i in 1:5 =>
arrayType = type(i in 1:5) = (T_ARRAY(DIM(5), T_NOTYPE), NONE)
expType = type(r[i]) = (T_REAL, NONE)
=> resType = (T_ARRAY(DIM(5), (T_REAL, NONE)), NONE)"
input DAE.Type arrayType;
input DAE.Type expType;
output DAE.Type resType;
algorithm
resType := matchcontinue(arrayType, expType)
local
DAE.Type ty;
DAE.ArrayDim dim;
Option<Absyn.Path> path;
case ((DAE.T_NOTYPE(), _), _) then expType;
case ((DAE.T_ARRAY(dim, ty), path), _)
equation
ty = constructArrayType(ty, expType);
then
((DAE.T_ARRAY(dim, ty), path));
end matchcontinue;
end constructArrayType;

protected function replaceOperatorWithFcall "function: replaceOperatorWithFcall

Expand Down

0 comments on commit 392e019

Please sign in to comment.