Skip to content

Commit

Permalink
- Add error message if inputs or outputs of a match expression are no…
Browse files Browse the repository at this point in the history
…t component references

  - Added testsuite/meta/ErrorMatchInOut{1,2,3}.mo to test this


git-svn-id: https://openmodelica.org/svn/OpenModelica/branches/sjoelund-functiontree@6400 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 17, 2010
1 parent 9c0dfdd commit 165c66d
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 121 deletions.
69 changes: 48 additions & 21 deletions Compiler/DFA.mo
Expand Up @@ -788,43 +788,69 @@ protected function addVarsToDfaEnv "function: addVarsToDfaEnv"
input list<tuple<Absyn.Ident,Absyn.TypeSpec>> dfaEnv;
input Env.Cache cache;
input Env.Env env;
input Absyn.Info info;
output list<tuple<Absyn.Ident,Absyn.TypeSpec>> outDfaEnv;
output Env.Cache outCache;
algorithm
(outDfaEnv,outCache) := matchcontinue (expList,dfaEnv,cache,env)
(SOME(outDfaEnv),outCache) := addVarsToDfaEnv2(expList,dfaEnv,cache,env,info);
end addVarsToDfaEnv;

protected function addVarsToDfaEnv2 "function: addVarsToDfaEnv"
input list<Absyn.Exp> expList;
input list<tuple<Absyn.Ident,Absyn.TypeSpec>> dfaEnv;
input Env.Cache cache;
input Env.Env env;
input Absyn.Info info;
output Option<list<tuple<Absyn.Ident,Absyn.TypeSpec>>> outDfaEnv "";
output Env.Cache outCache;
algorithm
(outDfaEnv,outCache) := matchcontinue (expList,dfaEnv,cache,env,info)
local
list<tuple<Absyn.Ident,Absyn.TypeSpec>> localDfaEnv;
Option<list<tuple<Absyn.Ident,Absyn.TypeSpec>>> res;
Env.Cache localCache;
Env.Env localEnv;
list<Absyn.Exp> restExps;
Absyn.Exp e;
String str;
case ({},localDfaEnv,localCache,_) then (localDfaEnv,localCache);
case (Absyn.CREF(Absyn.WILD) :: restExps,localDfaEnv,localCache,localEnv)
Absyn.Ident firstId;
DAE.Type t;
Absyn.TypeSpec t2;
tuple<Absyn.Ident,Absyn.TypeSpec> dfaEnvElem;
case ({},localDfaEnv,localCache,_,_)
equation
(localDfaEnv,localCache) = addVarsToDfaEnv(restExps,localDfaEnv,localCache,localEnv);
then (localDfaEnv,localCache);
case (Absyn.CREF(Absyn.CREF_IDENT(firstId,{})) :: restExps,localDfaEnv,localCache,localEnv)
local
Absyn.Ident firstId;
DAE.Type t;
Absyn.TypeSpec t2;
list<tuple<Absyn.Ident,Absyn.TypeSpec>> dfaEnvElem;
localDfaEnv = listReverse(localDfaEnv);
then (SOME(localDfaEnv),localCache);
case (Absyn.CREF(Absyn.WILD) :: restExps,localDfaEnv,localCache,localEnv,info)
equation
(res,localCache) = addVarsToDfaEnv2(restExps,localDfaEnv,localCache,localEnv,info);
then (res,localCache);
case (Absyn.CREF(Absyn.CREF_IDENT(firstId,{})) :: restExps,localDfaEnv,localCache,localEnv,info)
equation
(localCache,DAE.TYPES_VAR(_,_,_,t,_,_),_,_) = Lookup.lookupIdent(localCache,localEnv,firstId);
t2 = MetaUtil.typeConvert(t);
dfaEnvElem = {(firstId,t2)};
localDfaEnv = listAppend(localDfaEnv,dfaEnvElem);
(localDfaEnv,localCache) = addVarsToDfaEnv(restExps,localDfaEnv,localCache,localEnv);
then (localDfaEnv,localCache);
case (e::_,_,_,_)
dfaEnvElem = (firstId,t2);
localDfaEnv = dfaEnvElem::localDfaEnv;
(res,localCache) = addVarsToDfaEnv2(restExps,localDfaEnv,localCache,localEnv,info);
then (res,localCache);
case (e::_,_,_,_,info)
equation
true = RTOpts.debugFlag("matchcase");
true = RTOpts.debugFlag("matchcase");
str = Dump.printExpStr(e);
Debug.fprintln("matchcase", "- DFA.addVarsToDfaEnv failed " +& str);
then fail();
case (Absyn.CREF(Absyn.CREF_IDENT(firstId,{}))::_,_,_,env,info)
equation
str = Env.printEnvPathStr(env);
Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR, {firstId,str}, info);
then (NONE(),cache);
case (e::_,_,_,_,info)
equation
str = Dump.printExpStr(e);
Error.addSourceMessage(Error.META_MATCH_INPUT_OUTPUT_NON_CREF, {"output",str}, info);
then (NONE(),cache);
end matchcontinue;
end addVarsToDfaEnv;
end addVarsToDfaEnv2;

protected function createListOfTrue "function: createListOfTrue"
input Integer nStates;
Expand Down Expand Up @@ -1462,7 +1488,7 @@ protected
Absyn.Algorithm alg;
Absyn.AlgorithmItem algItem;
algorithm
(dfaEnv, invalidDecls, cache) := getMatchContinueInvalidDeclsAndInitialEnv(inputVarList, resVarList, cache, localEnv);
(dfaEnv, invalidDecls, cache) := getMatchContinueInvalidDeclsAndInitialEnv(inputVarList, resVarList, cache, localEnv, info);
checkShadowing(declList,invalidDecls);
(outCache, cases) := matchContinueToSwitch2(patMat, caseLocalDecls, inputVarList, resVarList, rhlist, elseRhSide, cache, localEnv, invalidDecls, dfaEnv, info);
alg := Absyn.ALG_MATCHCASES(matchType,cases);
Expand Down Expand Up @@ -1538,16 +1564,17 @@ protected function getMatchContinueInvalidDeclsAndInitialEnv
input list<Absyn.Exp> resVarList;
input Env.Cache inCache;
input Env.Env localEnv;
input Absyn.Info info;
output list<tuple<String,Absyn.TypeSpec>> dfaEnv;
output list<String> invalidDecls;
output Env.Cache cache;
protected
list<tuple<String,Absyn.TypeSpec>> dfaEnvRes;
list<String> envIdents, envIdents1, envIdents2;
algorithm
(dfaEnvRes,cache) := addVarsToDfaEnv(resVarList,{},inCache,localEnv);
(dfaEnvRes,cache) := addVarsToDfaEnv(resVarList,{},inCache,localEnv,info);
envIdents1 := Util.listMap(dfaEnvRes, Util.tuple21);
(dfaEnv,cache) := addVarsToDfaEnv(inputVarList,{},cache,localEnv);
(dfaEnv,cache) := addVarsToDfaEnv(inputVarList,{},cache,localEnv,info);
envIdents2 := Util.listMap(dfaEnv, Util.tuple21);
invalidDecls := listAppend(envIdents1, envIdents2);
end getMatchContinueInvalidDeclsAndInitialEnv;
Expand Down
4 changes: 3 additions & 1 deletion Compiler/Error.mo
Expand Up @@ -272,6 +272,7 @@ public constant ErrorID NON_INSTANTIATED_FUNCTION=5009;
public constant ErrorID META_UNSOLVED_POLYMORPHIC_BINDINGS=5010;
public constant ErrorID META_RECORD_FOUND_FAILURE=5011;
public constant ErrorID META_INVALID_PATTERN=5012;
public constant ErrorID META_MATCH_INPUT_OUTPUT_NON_CREF=5013;

protected constant list<tuple<Integer, MessageType, Severity, String>> errorTable=
{(SYNTAX_ERROR,SYNTAX(),ERROR(),"Syntax error near: %s"),
Expand Down Expand Up @@ -615,7 +616,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
(GENERIC_INST_FUNCTION,TRANSLATION(),ERROR(),"Failed to instantiate function %s in scope %s"),
(META_UNSOLVED_POLYMORPHIC_BINDINGS,TRANSLATION(),ERROR(),"Could not solve the polymorphism in the function call\n Input bindings: %s\n Solved bindings: %s\n Unsolved bindings: %s"),
(META_RECORD_FOUND_FAILURE,TRANSLATION(),ERROR(),"Found %s with type %s, but failed to elaborate the call."),
(META_INVALID_PATTERN,TRANSLATION(),ERROR(),"Invalid pattern: %s")
(META_INVALID_PATTERN,TRANSLATION(),ERROR(),"Invalid pattern: %s"),
(META_MATCH_INPUT_OUTPUT_NON_CREF,TRANSLATION(),ERROR(),"Only component references are valid as %s of a match expression. Got %s.")

};

Expand Down
34 changes: 3 additions & 31 deletions Compiler/InstSection.mo
Expand Up @@ -3042,38 +3042,10 @@ algorithm
Absyn.Info info;
DAE.ElementSource source;

// _ := matchcontinue(...) ...
case (localCache,localEnv,ih,localPre,SCode.ALG_ASSIGN(assignComponent = Absyn.CREF(Absyn.WILD()), value = e as Absyn.MATCHEXP(matchTy=_), info = info),impl)
equation
expl = {};
(localCache,e) = Patternm.matchMain(e,expl,localCache,localEnv,info);
(localCache,e_1,eprop,_) = Static.elabExp(localCache,localEnv, e, impl, NONE,true,pre,info);
(localCache,e_2) = PrefixUtil.prefixExp(localCache, localEnv, ih, e_1, localPre);
source = DAEUtil.createElementSource(info,NONE(),NONE(),NONE(),NONE());
stmt = DAE.STMT_ASSIGN(
DAE.ET_OTHER(),
DAE.CREF(DAE.WILD,DAE.ET_OTHER()),
e_2,source);
then (localCache,stmt);

// v1 := matchcontinue(...). Part of MetaModelica extension. KS
case (localCache,localEnv,ih,localPre,SCode.ALG_ASSIGN(assignComponent = Absyn.CREF(cr), value = e as Absyn.MATCHEXP(matchTy=_), info = info),impl)
equation
expl = {Absyn.CREF(cr)};
(localCache,e) = Patternm.matchMain(e,expl,localCache,localEnv,info);
(localCache,e_1,eprop,_) = Static.elabExp(localCache,localEnv, e, impl, NONE,true,pre,info);
(localCache,e_2) = PrefixUtil.prefixExp(localCache, localEnv, ih, e_1, localPre);
source = DAEUtil.createElementSource(info,NONE(),NONE(),NONE(),NONE());
stmt = DAE.STMT_ASSIGN(
DAE.ET_OTHER(),
DAE.CREF(DAE.WILD,DAE.ET_OTHER()),
e_2,source);
then
(localCache,stmt);

// (v1,v2,..,vn) := matchcontinue(...). Part of MetaModelica extension. KS
case (localCache,localEnv,ih,localPre,SCode.ALG_ASSIGN(assignComponent = Absyn.TUPLE(expl), value = e as Absyn.MATCHEXP(matchTy=_), info = info),impl)
// (v1,v2,..,vn)|v|_ := matchcontinue(...). Part of MetaModelica extension. KS
case (localCache,localEnv,ih,localPre,SCode.ALG_ASSIGN(assignComponent = exp, value = e as Absyn.MATCHEXP(matchTy=_), info = info),impl)
equation
expl = MetaUtil.extractListFromTuple(exp, 0);
(localCache,e) = Patternm.matchMain(e,expl,localCache,localEnv,info);
(localCache,e_1,eprop,_) = Static.elabExp(localCache,localEnv, e, impl, NONE,true,pre,info);
(localCache,e_2) = PrefixUtil.prefixExp(localCache, localEnv, ih, e_1, localPre);
Expand Down

0 comments on commit 165c66d

Please sign in to comment.