Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Add API call strictRMLCheck()
  - Checks that all input/output of a singleton match expression in a function matches the function arguments
  - Run it on the whole compiler in the testsuite
  - Currently 179 functions fail the check


git-svn-id: https://openmodelica.org/svn/OpenModelica/branches/sjoelund-functiontree@6511 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 21, 2010
1 parent f08af0b commit 8c7e8ca
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 83 deletions.
84 changes: 1 addition & 83 deletions Compiler/Inst.mo
Expand Up @@ -9891,7 +9891,7 @@ algorithm
case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(name = n,restriction = r)),inst_dims)
equation
failure(SCode.R_RECORD() = r);
true = strictRMLCheck(RTOpts.debugFlag("rml"),c);
true = MetaUtil.strictRMLCheck(RTOpts.debugFlag("rml"),c);
(cache,env,ih,funs) = implicitFunctionInstantiation2(cache,env,ih,mod,pre,csets,c,inst_dims);
cache = Env.addDaeFunction(cache, funs);
then (cache,env,ih);
Expand Down Expand Up @@ -14973,86 +14973,4 @@ algorithm
end matchcontinue;
end connectImplicitlyConnectedFlow2;

protected function strictRMLCheck
"If we are checking for strict RML, and function containing a single statement
that is a match expression must be on the form (outputs) := matchcontinue (inputs).
RML does not check this even though it's translated to this internally, so we
must check for it to warn the user."
input Boolean b;
input SCode.Class c;
output Boolean isOK;
algorithm
isOK := matchcontinue (b,c)
local
list<SCode.Element> elts,inelts,outelts;
list<String> innames,outnames;
list<Absyn.Exp> outcrefs,increfs;
Absyn.Exp comp,inputs;
Absyn.Info info;
case (false,_) then true;
case (_,SCode.CLASS(info = info, restriction = SCode.R_FUNCTION(), classDef = SCode.PARTS(elementLst = elts, normalAlgorithmLst = {SCode.ALGORITHM({SCode.ALG_ASSIGN(assignComponent = comp, value = Absyn.MATCHEXP(inputExp = inputs))})})))
equation
outcrefs = MetaUtil.extractListFromTuple(comp,0);
increfs = MetaUtil.extractListFromTuple(inputs,0);
inelts = Util.listSelect1(elts, Absyn.INPUT(), SCode.isComponentWithDirection);
outelts = Util.listSelect1(elts, Absyn.OUTPUT(), SCode.isComponentWithDirection);
innames = Util.listMap(inelts, SCode.elementName);
outnames = Util.listMap(outelts, SCode.elementName);
then strictRMLCheck2(increfs,outcrefs,innames,outnames,info);
case (_,_) then true;
end matchcontinue;
end strictRMLCheck;

protected function strictRMLCheck2
"If we are checking for strict RML, and function containing a single statement
that is a match expression must be on the form (outputs) := matchcontinue (inputs).
RML does not check this even though it's translated to this internally, so we
must check for it to warn the user."
input list<Absyn.Exp> increfs;
input list<Absyn.Exp> outcrefs;
input list<String> innames;
input list<String> outnames;
input Absyn.Info info;
output Boolean b;
algorithm
b := matchcontinue (increfs,outcrefs,innames,outnames,info)
local
list<String> names;
case (increfs,outcrefs,innames,outnames,info)
equation
true = (listLength(increfs) <> listLength(innames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Number of input arguments don't match"}, info);
then false;
case (increfs,outcrefs,innames,outnames as _::_,info)
equation
true = (listLength(outcrefs) <> listLength(outnames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Number of output arguments don't match"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
failure(_ = Util.listMap(increfs, Absyn.expCref));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Input expression was not a tuple of component references"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
failure(_ = Util.listMap(outcrefs, Absyn.expCref));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Output expression was not a tuple of component references"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
names = Util.listMap(increfs, Absyn.expComponentRefStr);
failure(equality(names = innames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"The input does not match"}, info);
then false;
case (increfs,{Absyn.CREF(Absyn.WILD())},innames,{},info) then true;
case (increfs,outcrefs,innames,outnames,info)
equation
names = Util.listMap(outcrefs, Absyn.expComponentRefStr);
failure(equality(names = outnames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"The output does not match"}, info);
then false;
case (_,_,_,_,_) then true;
end matchcontinue;
end strictRMLCheck2;

end Inst;
57 changes: 57 additions & 0 deletions Compiler/Interactive.mo
Expand Up @@ -1806,6 +1806,7 @@ algorithm
matchcontinue (inInteractiveStmts,inInteractiveSymbolTable)
local
Absyn.Program p_1,p,newp,p1,newp_1;
list<Absyn.Class> aclasses;
String resstr,name,top_names_str,str,resstr_1,res,cmt,s1,res_str;
Absyn.ComponentRef class_,ident,subident,cr,path,tp,model_,cr1,cr2,c1,c2,old_cname,new_cname,cname,from_ident,to_ident;
Absyn.Exp exp;
Expand Down Expand Up @@ -1960,6 +1961,20 @@ algorithm
then
("error",st);

case (istmts, st as SYMBOLTABLE(ast = p))
equation
// Check all functions for some stuff RML doesn't
// In an API call so we easily can test it
matchApiFunction(istmts, "strictRMLCheck");
{} = getApiFunctionArgs(istmts);
aclasses = getFunctionsInProgram(p);
_ = Util.listMap1r(Util.listMap(aclasses, SCodeUtil.translateClass), MetaUtil.strictRMLCheck, true);
resstr = Error.printMessagesStr();
resstr = stringAppend("\"", resstr);
resstr = stringAppend(resstr, "\"");
then
(resstr,st);

/* Checks the installation of OpenModelica and tries to find common errors */
case (istmts, st)
local
Expand Down Expand Up @@ -18777,4 +18792,46 @@ algorithm
end matchcontinue;
end setSymbolTableAST;

protected function getFunctionsInProgram
input Absyn.Program prog;
output list<Absyn.Class> funcs;
list<Absyn.Class> classes;
list<list<Absyn.Class>> classesList;
algorithm
Absyn.PROGRAM(classes = classes) := prog;
classesList := Util.listMap(classes, getAllClassesInClass);
funcs := Util.listFold(classes::classesList, getFunctionsInClasses, {});
end getFunctionsInProgram;

protected function getFunctionsInClasses
input list<Absyn.Class> classes;
input list<Absyn.Class> acc;
output list<Absyn.Class> funcs;
algorithm
funcs := matchcontinue (classes,acc)
local
list<Absyn.ClassPart> classParts;
Absyn.Class cl;
case ({},acc) then acc;
case ((cl as Absyn.CLASS(restriction = Absyn.R_FUNCTION()))::classes,acc)
equation
funcs = getFunctionsInClasses(classes,cl::acc);
then funcs;
case (_::classes,acc) then getFunctionsInClasses(classes,acc);
end matchcontinue;
end getFunctionsInClasses;

protected function getAllClassesInClass
input Absyn.Class class_;
output list<Absyn.Class> outClasses;
algorithm
outClasses := matchcontinue class_
local
list<Absyn.ClassPart> classParts;
case Absyn.CLASS(body = Absyn.PARTS(classParts = classParts))
then getClassesInParts(classParts);
case (_) then {};
end matchcontinue;
end getAllClassesInClass;

end Interactive;
83 changes: 83 additions & 0 deletions Compiler/MetaUtil.mo
Expand Up @@ -46,6 +46,7 @@ public import Env;
public import SCode;
public import SCodeUtil;

protected import Error;
protected import Exp;
protected import Lookup;
protected import RTOpts;
Expand Down Expand Up @@ -1276,4 +1277,86 @@ algorithm
end matchcontinue;
end tryToConvertArrayToList;

public function strictRMLCheck
"If we are checking for strict RML, and function containing a single statement
that is a match expression must be on the form (outputs) := matchcontinue (inputs).
RML does not check this even though it's translated to this internally, so we
must check for it to warn the user."
input Boolean b;
input SCode.Class c;
output Boolean isOK;
algorithm
isOK := matchcontinue (b,c)
local
list<SCode.Element> elts,inelts,outelts;
list<String> innames,outnames;
list<Absyn.Exp> outcrefs,increfs;
Absyn.Exp comp,inputs;
Absyn.Info info;
case (false,_) then true;
case (_,SCode.CLASS(info = info, restriction = SCode.R_FUNCTION(), classDef = SCode.PARTS(elementLst = elts, normalAlgorithmLst = {SCode.ALGORITHM({SCode.ALG_ASSIGN(assignComponent = comp, value = Absyn.MATCHEXP(inputExp = inputs))})})))
equation
outcrefs = extractListFromTuple(comp,0);
increfs = extractListFromTuple(inputs,0);
inelts = Util.listSelect1(elts, Absyn.INPUT(), SCode.isComponentWithDirection);
outelts = Util.listSelect1(elts, Absyn.OUTPUT(), SCode.isComponentWithDirection);
innames = Util.listMap(inelts, SCode.elementName);
outnames = Util.listMap(outelts, SCode.elementName);
then strictRMLCheck2(increfs,outcrefs,innames,outnames,info);
case (_,_) then true;
end matchcontinue;
end strictRMLCheck;

protected function strictRMLCheck2
"If we are checking for strict RML, and function containing a single statement
that is a match expression must be on the form (outputs) := matchcontinue (inputs).
RML does not check this even though it's translated to this internally, so we
must check for it to warn the user."
input list<Absyn.Exp> increfs;
input list<Absyn.Exp> outcrefs;
input list<String> innames;
input list<String> outnames;
input Absyn.Info info;
output Boolean b;
algorithm
b := matchcontinue (increfs,outcrefs,innames,outnames,info)
local
list<String> names;
case (increfs,outcrefs,innames,outnames,info)
equation
true = (listLength(increfs) <> listLength(innames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Number of input arguments don't match"}, info);
then false;
case (increfs,outcrefs,innames,outnames as _::_,info)
equation
true = (listLength(outcrefs) <> listLength(outnames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Number of output arguments don't match"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
failure(_ = Util.listMap(increfs, Absyn.expCref));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Input expression was not a tuple of component references"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
failure(_ = Util.listMap(outcrefs, Absyn.expCref));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"Output expression was not a tuple of component references"}, info);
then false;
case (increfs,outcrefs,innames,outnames,info)
equation
names = Util.listMap(increfs, Absyn.expComponentRefStr);
failure(equality(names = innames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"The input does not match"}, info);
then false;
case (increfs,{Absyn.CREF(Absyn.WILD())},innames,{},info) then true;
case (increfs,outcrefs,innames,outnames,info)
equation
names = Util.listMap(outcrefs, Absyn.expComponentRefStr);
failure(equality(names = outnames));
Error.addSourceMessage(Error.META_STRICT_RML_MATCH_IN_OUT, {"The output does not match"}, info);
then false;
case (_,_,_,_,_) then true;
end matchcontinue;
end strictRMLCheck2;

end MetaUtil;

0 comments on commit 8c7e8ca

Please sign in to comment.