Skip to content

Commit

Permalink
Fix for #2556:
Browse files Browse the repository at this point in the history
- Implemented support for qualified crefs as external function arguments.
- Removed Static.isTuple (duplicate of Types.isTuple).


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@20049 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Apr 8, 2014
1 parent 62ae247 commit 0d2aecd
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 53 deletions.
5 changes: 3 additions & 2 deletions Compiler/BackEnd/SimCodeUtil.mo
Expand Up @@ -1007,7 +1007,7 @@ algorithm
simExtArgOut :=
matchcontinue (simExtArgIn, outVars)
local
DAE.ComponentRef cref;
DAE.ComponentRef cref, fcref;
Boolean isInput;
Integer outputIndex; // > 0 if output
Boolean isArray, hasBinding;
Expand All @@ -1018,7 +1018,8 @@ algorithm
case (SimCode.SIMEXTARG(cref, isInput, outputIndex, isArray, _, type_), _)
equation
true = outputIndex == -1;
(newOutputIndex, hasBinding) = findIndexInList(cref, outVars, 1);
fcref = ComponentReference.crefFirstCref(cref);
(newOutputIndex, hasBinding) = findIndexInList(fcref, outVars, 1);
then
SimCode.SIMEXTARG(cref, isInput, newOutputIndex, isArray, hasBinding, type_);

Expand Down
26 changes: 26 additions & 0 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -1772,6 +1772,32 @@ algorithm
ocr := joinCrefs(cr,DAE.CREF_IDENT(str,DAE.T_UNKNOWN_DEFAULT,{}));
end appendStringCref;

public function appendStringFirstIdent
"Appends a string to the first identifier of a cref."
input String inString;
input DAE.ComponentRef inCref;
output DAE.ComponentRef outCref;
algorithm
outCref := match(inString, inCref)
local
DAE.Ident id;
list<DAE.Subscript> subs;
DAE.ComponentRef cr;
DAE.Type ty;
Integer idx;

case (_, DAE.CREF_QUAL(id, ty, subs, cr))
then DAE.CREF_QUAL(stringAppend(id, inString), ty, subs, cr);

case (_, DAE.CREF_IDENT(id, ty, subs))
then DAE.CREF_IDENT(stringAppend(id, inString), ty, subs);

case (_, DAE.CREF_ITER(id, idx, ty, subs))
then DAE.CREF_ITER(stringAppend(id, inString), idx, ty, subs);

end match;
end appendStringFirstIdent;

public function joinCrefs
"Join two component references by concatenating them.
Expand Down
23 changes: 23 additions & 0 deletions Compiler/FrontEnd/DAEUtil.mo
Expand Up @@ -6083,6 +6083,29 @@ algorithm
DAE.ATTR(variability = outVar) := inAttr;
end getAttrVariability;

public function setAttrDirection
"Sets the direction attribute in an Attributes record."
input DAE.Attributes inAttr;
input Absyn.Direction inDir;
output DAE.Attributes outAttr;
protected
SCode.ConnectorType ct;
SCode.Parallelism prl;
SCode.Variability var;
Absyn.InnerOuter io;
SCode.Visibility vis;
algorithm
DAE.ATTR(ct, prl, var, _, io, vis) := inAttr;
outAttr := DAE.ATTR(ct, prl, var, inDir, io, vis);
end setAttrDirection;

public function getAttrDirection
input DAE.Attributes inAttr;
output Absyn.Direction outDir;
algorithm
DAE.ATTR(direction = outDir) := inAttr;
end getAttrDirection;

public function addSymbolicTransformation
input DAE.ElementSource source;
input DAE.SymbolicOperation op;
Expand Down
15 changes: 15 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -7494,6 +7494,21 @@ algorithm
end match;
end isTuple;

public function isScalarConst
"Returns true if the given expression is a scalar constant, otherwise false."
input DAE.Exp inExp;
output Boolean outIsScalar;
algorithm
outIsScalar := match(inExp)
case DAE.ICONST(integer = _) then true;
case DAE.RCONST(real = _) then true;
case DAE.SCONST(string = _) then true;
case DAE.BCONST(bool = _) then true;
case DAE.ENUM_LITERAL(name = _) then true;
else false;
end match;
end isScalarConst;

public function expIsPositive "Returns true if an expression is positive,
Returns true in the following cases:
constant >= 0
Expand Down
74 changes: 52 additions & 22 deletions Compiler/FrontEnd/InstUtil.mo
Expand Up @@ -5495,13 +5495,26 @@ algorithm
local
DAE.ComponentRef cr1,cr2;
DAE.Exp exp;
case (DAE.VAR(componentRef=cr1),DAE.EXTARG(componentRef=cr2))
then ComponentReference.crefEqualNoStringCompare(cr1,cr2);
case (DAE.VAR(direction=DAE.OUTPUT()),_) then false;
case (DAE.VAR(componentRef=cr1),DAE.EXTARGSIZE(componentRef=cr2))
then ComponentReference.crefEqualNoStringCompare(cr1,cr2);
case (DAE.VAR(componentRef=cr1),DAE.EXTARGEXP(exp=exp))

case (DAE.VAR(componentRef=cr1), DAE.EXTARG(componentRef=cr2))
equation
// If the external argument refers to a record member, i.e. a qualified
// cref, consider the whole record to be used.
cr2 = ComponentReference.crefFirstCref(cr2);
then
ComponentReference.crefEqualNoStringCompare(cr1,cr2);

case (DAE.VAR(direction=DAE.OUTPUT()), _) then false;

case (DAE.VAR(componentRef=cr1), DAE.EXTARGSIZE(componentRef=cr2))
equation
cr2 = ComponentReference.crefFirstCref(cr2);
then
ComponentReference.crefEqualNoStringCompare(cr1,cr2);

case (DAE.VAR(componentRef=cr1), DAE.EXTARGEXP(exp=exp))
then Expression.expHasCref(exp,cr1);

else false;
end match;
end extArgCrefEq;
Expand Down Expand Up @@ -5871,7 +5884,7 @@ algorithm
case (cache,_,{},_,_,_) then (cache,{});
case (cache,env,(e :: exps),(p :: props),_,_)
equation
(cache,extarg) = instExtGetFargsSingle(cache, env, e, p, lang, info);
(cache,SOME(extarg)) = instExtGetFargsSingle(cache, env, e, p, lang, info);
(cache,extargs) = instExtGetFargs2(cache, env, exps, props, lang, info);
then
(cache,extarg :: extargs);
Expand All @@ -5888,15 +5901,15 @@ protected function instExtGetFargsSingle
input Option<String> lang;
input Absyn.Info info;
output Env.Cache outCache;
output DAE.ExtArg outExtArg;
output Option<DAE.ExtArg> outExtArg;
algorithm
(outCache,outExtArg) := matchcontinue (inCache,inEnv,inExp,inProperties,lang,info)
local
DAE.Attributes attr;
DAE.Attributes attr, fattr;
DAE.Type ty,varty;
DAE.Binding bnd;
list<Env.Frame> env;
DAE.ComponentRef cref;
DAE.ComponentRef cref, fcr;
DAE.Type crty;
DAE.Const cnst;
String crefstr,scope;
Expand All @@ -5907,44 +5920,61 @@ algorithm
Values.Value val;
String str;

case (cache,env,DAE.CREF(componentRef = cref as DAE.CREF_IDENT(ident=_),ty = _),DAE.PROP(type_ = ty,constFlag = DAE.C_VAR()),_,_)
case (_, _, DAE.CREF(componentRef = cref as DAE.CREF_QUAL(ident = _)),
DAE.PROP(constFlag = DAE.C_VAR()), _, _)
equation
(cache, attr, ty, bnd, _, _, _, _, _) = Lookup.lookupVarLocal(inCache, inEnv, cref);
// For qualified crefs, copy input/output from the first part of the
// cref. This is done so that the correct code can be generated when
// using qualified crefs in external function definitions.
fcr = ComponentReference.crefFirstCref(cref);
(cache, fattr, _, _, _, _, _, _, _) = Lookup.lookupVarLocal(cache, inEnv, fcr);
attr = DAEUtil.setAttrDirection(attr, DAEUtil.getAttrDirection(fattr));
then
(cache, SOME(DAE.EXTARG(cref, attr, ty)));

case (_, _, DAE.CREF(componentRef = cref as DAE.CREF_IDENT(ident = _)),
DAE.PROP(constFlag = DAE.C_VAR()), _, _)
equation
(cache,attr,ty,bnd,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env,cref);
(cache, attr, ty, bnd, _, _, _, _, _) = Lookup.lookupVarLocal(inCache, inEnv, cref);
then
(cache,DAE.EXTARG(cref,attr,ty));
(cache,SOME(DAE.EXTARG(cref, attr, ty)));

case (cache,env,DAE.CREF(componentRef = cref,ty = _),DAE.PROP(type_ = ty,constFlag = _),_,_)
equation
failure((_,_,_,_,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env,cref));
crefstr = ComponentReference.printComponentRefStr(cref);
scope = Env.printEnvPathStr(env);
Error.addMessage(Error.LOOKUP_VARIABLE_ERROR, {crefstr,scope});
then fail();
then
(cache, NONE());

case (cache,env,DAE.SIZE(exp = DAE.CREF(componentRef = cref,ty = _),sz = SOME(dim)),DAE.PROP(type_ = ty),_,_)
equation
(cache,attr,varty,bnd,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env, cref);
then
(cache,DAE.EXTARGSIZE(cref,attr,varty,dim));
(cache,SOME(DAE.EXTARGSIZE(cref,attr,varty,dim)));

// adrpo: these can be non-local if they are constants or parameters!
case (cache,env,_,DAE.PROP(type_ = ty,constFlag = DAE.C_CONST()),_,_)
equation
(cache, exp, prop) = Ceval.cevalIfConstant(cache, env, inExp, inProperties, false, info);
// TODO: Check it is a scalar
then (cache,DAE.EXTARGEXP(exp, ty));
true = Expression.isScalarConst(exp);
then
(cache,SOME(DAE.EXTARGEXP(exp, ty)));

case (cache,_,DAE.CALL(path=Absyn.QUALIFIED("OpenModelica",Absyn.IDENT("threadData"))),DAE.PROP(type_ = ty),_,_)
then (cache,DAE.EXTARGEXP(inExp, ty));
then (cache,SOME(DAE.EXTARGEXP(inExp, ty)));

case (cache,_,_,DAE.PROP(type_ = ty),SOME("builtin"),_)
then (cache,DAE.EXTARGEXP(inExp, ty));
then (cache,SOME(DAE.EXTARGEXP(inExp, ty)));

case (_,_,exp,DAE.PROP(type_ = _,constFlag = _),_,_)
case (cache,_,exp,DAE.PROP(type_ = _,constFlag = _),_,_)
equation
str = ExpressionDump.printExpStr(exp);
Error.addSourceMessage(Error.EXTERNAL_ARG_WRONG_EXP,{str},info);
then fail();
then
(cache, NONE());

end matchcontinue;
end instExtGetFargsSingle;
Expand Down Expand Up @@ -5980,7 +6010,7 @@ algorithm
case (cache,env,SCode.EXTERNALDECL(funcName = _,lang = lang,output_ = SOME(cref),args = args),impl,pre,_)
equation
(cache,SOME((exp,prop,_))) = Static.elabCref(cache,env,cref,impl,false /* Do NOT vectorize arrays; we require a CREF */,pre,info);
(cache,extarg) = instExtGetFargsSingle(cache,env,exp,prop,lang,info);
(cache,SOME(extarg)) = instExtGetFargsSingle(cache,env,exp,prop,lang,info);
assertExtArgOutputIsCrefVariable(lang,extarg,Types.getPropType(prop),Types.propAllConst(prop),info);
then
(cache,extarg);
Expand Down
13 changes: 1 addition & 12 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -7584,7 +7584,7 @@ algorithm
"The constness of a function depends on the inputs. If all inputs are constant the call itself is constant." ;

(fn_1,functype) := deoverloadFuncname(fn, functype, inEnv);
tuple_ := isTuple(restype);
tuple_ := Types.isTuple(restype);
(isBuiltin,builtin,fn_1) := isBuiltinFunc(fn_1,functype);
inlineType := inlineBuiltin(isBuiltin,inlineType);

Expand Down Expand Up @@ -8596,17 +8596,6 @@ algorithm
end matchcontinue;
end deoverloadFuncname;

protected function isTuple
"Return true if Type is a Tuple type."
input DAE.Type inType;
output Boolean outBoolean;
algorithm
outBoolean := matchcontinue (inType)
case (DAE.T_TUPLE(tupleType = _)) then true;
case (_) then false;
end matchcontinue;
end isTuple;

protected function elabTypes "
function: elabTypes
Elaborate input parameters to a function and
Expand Down
12 changes: 6 additions & 6 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -476,20 +476,20 @@ public function isTuple "Returns true if type is TUPLE"
input DAE.Type tp;
output Boolean b;
algorithm
b := matchcontinue(tp)
b := match(tp)
case (DAE.T_TUPLE(tupleType = _)) then true;
case (_) then false;
end matchcontinue;
else false;
end match;
end isTuple;

public function isRecord "Returns true if type is COMPLEX and a record (ClassInf)"
input DAE.Type tp;
output Boolean b;
algorithm
b := matchcontinue(tp)
b := match(tp)
case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_))) then true;
case (_) then false;
end matchcontinue;
else false;
end match;
end isRecord;

public function getRecordPath "gets the record path"
Expand Down
29 changes: 21 additions & 8 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -6642,7 +6642,7 @@ case TYPES_VAR(ty = T_ARRAY(__)) then
end recordMemberInit;

template extVarName(ComponentRef cr)
::= '<%contextCref(cr,contextFunction)%>_ext'
::= '_<%crefToMStr(appendStringFirstIdent("_ext", cr))%>'
end extVarName;

template extFunCall(Function fun, Text &preExp /*BUFP*/, Text &varDecls /*BUFP*/)
Expand All @@ -6661,7 +6661,8 @@ template extFunCallC(Function fun, Text &preExp /*BUFP*/, Text &varDecls /*BUFP*
match fun
case EXTERNAL_FUNCTION(__) then
/* adpro: 2011-06-24 do vardecls -> extArgs as there might be some sets in there! */
let varDecs = (List.union(extArgs, extArgs) |> arg => extFunCallVardecl(arg, &varDecls /*BUFD*/) ;separator="\n")
let varDecs = (List.union(extArgs, extArgs) |> arg => extFunCallVardecl(arg, &varDecls) ;separator="\n")
let _ = (biVars |> bivar => extFunCallBiVar(bivar, &preExp, &varDecls) ;separator="\n")
let fname = if dynamicLoad then 'ptr_<%extFunctionName(extName, language)%>' else '<%extName%>'
let dynamicCheck = if dynamicLoad then
<<
Expand All @@ -6672,9 +6673,7 @@ case EXTERNAL_FUNCTION(__) then
} else
>>
else ''
let args = (extArgs |> arg =>
extArg(arg, &preExp /*BUFC*/, &varDecls /*BUFD*/)
;separator=", ")
let args = (extArgs |> arg => extArg(arg, &preExp, &varDecls) ;separator=", ")
let returnAssign = match extReturn case SIMEXTARG(cref=c) then
'<%extVarName(c)%> = '
else
Expand Down Expand Up @@ -6788,6 +6787,20 @@ template typeDefaultValue(DAE.Type ty)
else ""
end typeDefaultValue;

template extFunCallBiVar(Variable var, Text &preExp, Text &varDecls)
::=
match var
case var as VARIABLE(__) then
let var_name = extVarName(name)
let &varDecls += '<%varType(var)%> <%var_name%>;<%\n%>'
let defaultValue = match value
case SOME(v) then
'<%daeExp(v, contextFunction, &preExp, &varDecls)%>'
else ""
let &preExp += if defaultValue then '<%var_name%> = <%defaultValue%>;<%\n%>'
""
end extFunCallBiVar;

template extFunCallBiVarF77(Variable var, Text &preExp, Text &varDecls)
::=
match var
Expand Down Expand Up @@ -6861,11 +6874,11 @@ template extArg(SimExtArg extArg, Text &preExp /*BUFP*/, Text &varDecls /*BUFP*/
let shortTypeStr = expTypeShort(t)
'(<%extType(t,isInput,true)%>) data_of_<%shortTypeStr%>_array(&(<%name%>))'
case SIMEXTARG(cref=c, isInput=ii, outputIndex=0, type_=t) then
let cr = '<%contextCref(c,contextFunction)%>'
let cr = match t case T_STRING(__) then contextCref(c,contextFunction) else extVarName(c)
if acceptMetaModelicaGrammar() then
(match t case T_STRING(__) then 'MMC_STRINGDATA(<%cr%>)' else '<%cr%>_ext')
(match t case T_STRING(__) then 'MMC_STRINGDATA(<%cr%>)' else cr)
else
'<%cr%><%match t case T_STRING(__) then "" else "_ext"%>'
cr
case SIMEXTARG(cref=c, isInput=ii, outputIndex=oi, type_=t) then
'&<%extVarName(c)%>'
case SIMEXTARGEXP(__) then
Expand Down
4 changes: 2 additions & 2 deletions Compiler/Template/CodegenUtil.tpl
Expand Up @@ -82,7 +82,7 @@ template modelNamePrefix(SimCode simCode)
end modelNamePrefix;

template crefStr(ComponentRef cr)
"Generates the name of a variable for variable name array. Uses undersocres for qualified names.
"Generates the name of a variable for variable name array. Uses underscores for qualified names.
a._b not a.b"
::=
match cr
Expand All @@ -94,7 +94,7 @@ template crefStr(ComponentRef cr)
end crefStr;

template crefStrNoUnderscore(ComponentRef cr)
"Generates the name of a variable for variable name array. However does not use undersocres on qualified names.
"Generates the name of a variable for variable name array. However does not use underscores on qualified names.
a.b not a._b. Used for generating variable names that are exported e.g. xml files"
::=
match cr
Expand Down
5 changes: 5 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -2501,6 +2501,11 @@ package ComponentReference
output DAE.ComponentRef ocr;
end appendStringCref;

function appendStringFirstIdent
input String inString;
input DAE.ComponentRef inCref;
output DAE.ComponentRef outCref;
end appendStringFirstIdent;
end ComponentReference;

package Expression
Expand Down

0 comments on commit 0d2aecd

Please sign in to comment.