Skip to content

Commit

Permalink
If expr is a constant or parametric expression, der(expr) is replaced…
Browse files Browse the repository at this point in the history
… during elaboration:

by 0.0 if expr is Real or Integer;
by an array of corresponding size filled by 0.0 if expr is an array of Real or Integer.

See http://openmodelica.ida.liu.se:8080/cb/issue/1233



git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@5635 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Alexey Lebedev committed Jun 10, 2010
1 parent 44088dd commit 25f8749
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 59 deletions.
23 changes: 23 additions & 0 deletions Compiler/DAEUtil.mo
Expand Up @@ -4758,6 +4758,29 @@ algorithm
end matchcontinue;
end isIfEquation;

public function makeZeroExpression
" creates a Real or array<Real> zero expression with given dimensions, also returns its type"
input list<Option<Integer>> inDims;
output DAE.Exp outExp;
output DAE.Type outType;
algorithm
(outExp,outType) := matchcontinue(inDims)
local
Integer d;
list<Option<Integer>> dims;
DAE.Exp e;
list<DAE.Exp> eLst;
DAE.Type ty;
case {} then (DAE.RCONST(0.0), DAE.T_REAL_DEFAULT);
case SOME(d)::dims
equation
(e, ty) = makeZeroExpression(dims);
eLst = Util.listFill(e,d);
then
(DAE.ARRAY(DAE.ET_ARRAY(DAE.ET_REAL(),SOME(d)::dims),false,eLst), (DAE.T_ARRAY(DAE.DIM(SOME(d)),ty),NONE));
end matchcontinue;
end makeZeroExpression;

public function splitElements_dispatch
"@author: adrpo
This function will split DAE elements into:
Expand Down
88 changes: 29 additions & 59 deletions Compiler/Static.mo
Expand Up @@ -5478,22 +5478,20 @@ algorithm
Env.Cache cache;
DAE.DAElist dae;

/* use elab_call_args to also try vectorized calls */
// Replace der of constant Real, Integer or array of Real/Integer by zero(s)
case (cache,env,{exp},_,impl)
local
DAE.Type ety,restype,ty;
DAE.Exp ee1;
String es1,es2,es3;
list<String> ls;
DAE.Type ety,ty;
list<Option<Integer>> dims;
equation
(_,ee1,DAE.PROP(ety,c),_,dae) = elabExp(cache,env, exp, impl, NONE,false);
false = Types.isRealOrSubTypeReal(ety);
ls = Util.listMap({exp}, Dump.printExpStr);
es1 = Util.stringDelimitList(ls, ", ");
es3 = Types.unparseType(ety);
Error.addMessage(Error.DERIVATIVE_NON_REAL, {es1,es1,es3});
(_,_,DAE.PROP(ety,c),_,_) = elabExp(cache, env, exp, impl, NONE,false);
failure(equality(c=DAE.C_VAR));
dims = Types.getRealOrIntegerDimensions(ety);
(e,ty) = DAEUtil.makeZeroExpression(dims);
then
fail();
(cache,e,DAE.PROP(ty,DAE.C_CONST),DAE.DAE({}, DAE.AVLTREENODE(NONE, 0, NONE, NONE)));

/* use elab_call_args to also try vectorized calls */
case (cache,env,{exp},_,impl)
local
DAE.Type ety,restype,ty;
Expand All @@ -5503,60 +5501,32 @@ algorithm
(_,ee1,DAE.PROP(ety,c),_,_) = elabExp(cache, env, exp, impl, NONE,true);
ety = Types.arrayElementType(ety);
true = Types.isRealOrSubTypeReal(ety);
(cache,e,(prop as DAE.PROP(ty,DAE.C_VAR())),dae) = elabCallArgs(cache,env, Absyn.IDENT("der"), {exp}, {}, impl, NONE);
(cache,e,(prop as DAE.PROP(ty,_)),dae) = elabCallArgs(cache,env, Absyn.IDENT("der"), {exp}, {}, impl, NONE);
then
(cache,e,prop,dae);

case(cache,env,expl,_,impl)
case (cache,env,{exp},_,impl)
local
DAE.Type ety;
String es3;
equation
setUniqueErrorMessageForDer(cache,env,expl,impl);
then
fail();
(_,_,DAE.PROP(ety,_),_,_) = elabExp(cache,env, exp, impl, NONE,false);
false = Types.isRealOrSubTypeReal(ety);
s = Dump.printExpStr(exp);
es3 = Types.unparseType(ety);
Error.addMessage(Error.DERIVATIVE_NON_REAL, {s,s,es3});
then
fail();
case (cache,env,expl,_,_)
equation
lst = Util.listMap(expl, Dump.printExpStr);
s = Util.stringDelimitList(lst, ", ");
s = Util.stringAppendList({"der(",s,")"});
Error.addMessage(Error.WRONG_TYPE_OR_NO_OF_ARGS, {s});
then fail();
end matchcontinue;
end elabBuiltinDer;

protected function setUniqueErrorMessageForDer "
Author: BZ, 2009-02
Function to set correct error message for der.
(if we have an error with constant arguments to der() then do not give Error.WRONG_TYPE_OR_NO_OF_ARGS
"
input Env.Cache cache;
input Env.Env env;
input list<Absyn.Exp> expl;
input Boolean impl;
algorithm _ := matchcontinue(cache,env,expl,impl)
local
Absyn.Exp exp;
list<Ident> lst;
Ident s;
case (cache,env,{(exp as Absyn.CREF(componentRef = _))},impl)
equation
failure((cache,_,DAE.PROP(_,DAE.C_VAR),_,_) = elabExp(cache,env, exp, impl, NONE,true));
lst = Util.listMap({exp}, Dump.printExpStr);
s = Util.stringDelimitList(lst, ", ");
s = Util.stringAppendList({"der(",s,")'.\n"});
Error.addMessage(Error.DER_APPLIED_TO_CONST, {s});
then ();
case (cache,env,{exp},impl)
equation
(_,_,DAE.PROP(_,DAE.C_CONST),_,_) = elabExp(cache,env, exp, impl, NONE,true);
lst = Util.listMap({exp}, Dump.printExpStr);
s = Util.stringDelimitList(lst, ", ");
s = Util.stringAppendList({"der(",s,")'.\n"});
Error.addMessage(Error.DER_APPLIED_TO_CONST, {s});
then ();
/*
case (cache,env,expl,_)
equation
lst = Util.listMap(expl, Dump.printExpStr);
s = Util.stringDelimitList(lst, ", ");
s = Util.stringAppendList({"der(",s,")'.\n"});
Error.addMessage(Error.WRONG_TYPE_OR_NO_OF_ARGS, {s});
then ();
*/
end matchcontinue;
end setUniqueErrorMessageForDer;

protected function elabBuiltinSample "function: elabBuiltinSample
author: PA

Expand Down
28 changes: 28 additions & 0 deletions Compiler/Types.mo
Expand Up @@ -5589,4 +5589,32 @@ algorithm
end matchcontinue;
end resTypeToListTypes;

public function getRealOrIntegerDimensions
"If the type is a Real, Integer or an array of Real or Integer, the function returns
list of dimensions; otherwise, it fails."
input Type inType;
output list<Option<Integer>> outDims;
algorithm
outType := matchcontinue (inType)
local
Type ty;
Option<Integer> d;
list<Option<Integer>> dims;

case ((DAE.T_REAL(varLstReal=_),_))
then
{};
case ((DAE.T_INTEGER(varLstInt=_),_))
then
{};
case ((DAE.T_COMPLEX(_,_,SOME(ty),_),_))
then getRealOrIntegerDimensions(ty);
case ((DAE.T_ARRAY(arrayDim=DAE.DIM(d),arrayType=ty),_))
equation
dims = getRealOrIntegerDimensions(ty);
then
d::dims;
end matchcontinue;
end getRealOrIntegerDimensions;

end Types;

0 comments on commit 25f8749

Please sign in to comment.