Skip to content

Commit

Permalink
Fixed bug with multiple declarations, see testsuite/mofiles/MultipleD…
Browse files Browse the repository at this point in the history
…eclarations.mo

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@2438 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed Jul 4, 2006
1 parent 5c92983 commit bf014d5
Show file tree
Hide file tree
Showing 9 changed files with 622 additions and 17 deletions.
121 changes: 121 additions & 0 deletions Compiler/Absyn.mo
Expand Up @@ -1593,5 +1593,126 @@ algorithm
case (_) then false;
end matchcontinue;
end isPackageRestriction;

public function expEqual "Returns true if two expressions are equal"
input Exp exp1;
input Exp exp2;
output Boolean equal;
algorithm
equal := matchcontinue(exp1,exp2)
case(INTEGER(i1),INTEGER(i2))
local Integer i1,i2;
then intEq(i1,i2);
case(REAL(r1),REAL(r2))
local Real r1,r2;
then realEq(r1,r2);
case(CREF(cr1),CREF(cr2))
local ComponentRef cr1,cr2;
then crefEqual(cr1,cr2);
case(STRING(s1),STRING(s2))
local String s1,s2;
then Util.stringEqual(s1,s2);
case (BOOL(b1),BOOL(b2))
local Boolean b1,b2;
then Util.boolEqual(b1,b2);
case (BINARY(e11,_,e12),BINARY(e21,_,e22))
local Exp e11,e12,e21,e22;
then boolAnd(expEqual(e11,e21),expEqual(e12,e22));
case (LBINARY(e11,_,e12),LBINARY(e21,_,e22))
local Exp e11,e12,e21,e22;
then boolAnd(expEqual(e11,e21),expEqual(e12,e22));
case (UNARY(_,e1),UNARY(_,e2))
local Exp e1,e2;
then expEqual(e1,e2);
case (LUNARY(_,e1),LUNARY(_,e2))
local Exp e1,e2;
then expEqual(e1,e2);
case (RELATION(e11,_,e12),RELATION(e21,_,e22))
local Exp e12,e11,e21,e22;
then boolAnd(expEqual(e11,e21),expEqual(e12,e22));
case (IFEXP(e11,e12,e13,_),IFEXP(e21,e22,e23,_))
local Exp e12,e11,e13,e21,e22,e23; Boolean b1,b2,b3; equation
b1 = expEqual(e11,e21);
b2 = expEqual(e12,e22);
b3 = expEqual(e13,e23);
equal = Util.boolAndList({b1,b2,b3});
then equal;
case (CALL(cref1,args1),CALL(cref2,args2))
local ComponentRef cref1,cref2; FunctionArgs args1,args2; Boolean b1,b2; list<Boolean> blst; equation
b1 = crefEqual(cref1,cref2);
b2 = functionArgsEqual(args1,args2);
equal = Util.boolAndList({b1,b2});
then equal;
case (ARRAY(args1),ARRAY(args2))
local ComponentRef cref1,cref2; list<Exp> args1,args2; Boolean b1; list<Boolean> blst; equation
blst = Util.listThreadMap(args1,args2,expEqual);
equal = Util.boolAndList(blst);
then equal;

case (MATRIX(args1),MATRIX(args2))
local ComponentRef cref1,cref2; list<list<Exp>> args1,args2; Boolean b1; list<list<Boolean>> blst; equation
blst = Util.listListThreadMap(args1,args2,expEqual);
equal = Util.boolAndList(Util.listFlatten(blst));
then equal;

case (RANGE(e11,SOME(e12),e13),RANGE(e21,SOME(e22),e23))
local Exp e11,e12,e13,e21,e22,e23;
Boolean b1,b2,b3;
equation
b1 = expEqual(e11,e21);
b2 = expEqual(e12,e22);
b3 = expEqual(e13,e23);
equal = Util.boolAndList({b1,b2,b3});
then equal;

case (RANGE(e11,_,e13),RANGE(e21,_,e23))
local Exp e11,e12,e13,e21,e22,e23;
Boolean b1,b2,b3;
equation
b1 = expEqual(e11,e21);
b3 = expEqual(e13,e23);
equal = Util.boolAndList({b1,b3});
then equal;
case (TUPLE(args1),TUPLE(args2))
local ComponentRef cref1,cref2; list<Exp> args1,args2; Boolean b1; list<Boolean> blst; equation
blst = Util.listThreadMap(args1,args2,expEqual);
equal = Util.boolAndList(blst);
then equal;
case (END(),END()) then true;
case(CODE(_),CODE(_)) equation
print("expEqual CODE not implemented yet.\n");
then false;
case(_,_) then false;
end matchcontinue;
end expEqual;

public function eachEqual "Returns true if two each attributes are equal"
input Each each1;
input Each each2;
output Boolean equal;
algorithm
equal := matchcontinue(each1,each2)
case(NON_EACH(),NON_EACH()) then true;
case(EACH(),EACH()) then true;
case(_,_) then false;
end matchcontinue;
end eachEqual;

protected function functionArgsEqual
input FunctionArgs args1;
input FunctionArgs args2;
output Boolean equal;
algorithm
equal := matchcontinue(args1,args2)
case (FUNCTIONARGS(expl1,_),FUNCTIONARGS(expl2,_))
local ComponentRef cref1,cref2; list<Exp> expl1,expl2; Boolean b1; list<Boolean> blst;
equation
blst = Util.listThreadMap(expl1,expl2,expEqual);
equal = Util.boolAndList(blst);
then equal;

case(_,_) then false;
end matchcontinue;
end functionArgsEqual;
end Absyn;

16 changes: 12 additions & 4 deletions Compiler/Env.mo
Expand Up @@ -146,7 +146,7 @@ uniontype Item
record VAR
Types.Var instantiated "instantiated component" ;
Option<tuple<SCode.Element, Types.Mod>> declaration "declaration if not fully instantiated." ;
Boolean if_ "if it typed/fully instantiated or not" ;
Boolean typed "if it typed/fully instantiated or not" ;
Env env "The environment of the instantiated component
Contains e.g. all sub components
" ;
Expand Down Expand Up @@ -389,9 +389,17 @@ algorithm
Option<tuple<SCode.Element, Types.Mod>> c;
case ((FRAME(class_1 = id,list_2 = ht,list_3 = httypes,list_4 = imps,list_5 = bcframes,current6 = crs,encapsulated_7 = encflag) :: fs),(v as Types.VAR(name = n)),c,i,env) /* environment of component */
equation
failure((_)= treeGet(ht, n, System.hash));
(ht_1) = treeAdd(ht, n, VAR(v,c,i,env), System.hash);
then
(FRAME(id,ht_1,httypes,imps,bcframes,crs,encflag) :: fs);

// Variable already added, perhaps from baseclass
case ((FRAME(class_1 = id,list_2 = ht,list_3 = httypes,list_4 = imps,list_5 = bcframes,current6 = crs,encapsulated_7 = encflag) :: fs),(v as Types.VAR(name = n)),c,i,env) /* environment of component */
equation
(_)= treeGet(ht, n, System.hash);
then
(FRAME(id,ht,httypes,imps,bcframes,crs,encflag) :: fs);
end matchcontinue;
end extendFrameV;

Expand Down Expand Up @@ -840,7 +848,7 @@ algorithm
Integer len;
list<tuple<Types.TType, Option<Absyn.Path>>> lst;
Absyn.Import imp;
case ((n,VAR(instantiated = (tv as Types.VAR(attributes = Types.ATTR(parameter_ = var),type_ = tp,binding = bind)),declaration = SOME((elt,_)),if_ = i,env = (compframe :: _))))
case ((n,VAR(instantiated = (tv as Types.VAR(attributes = Types.ATTR(parameter_ = var),type_ = tp,binding = bind)),declaration = SOME((elt,_)),typed = i,env = (compframe :: _))))
equation
s = SCode.variabilityString(var);
elt_str = SCode.printElementStr(elt);
Expand All @@ -854,7 +862,7 @@ algorithm
frame_str" ;
then
res;
case ((n,VAR(instantiated = (tv as Types.VAR(attributes = Types.ATTR(parameter_ = var),type_ = tp)),declaration = SOME((elt,_)),if_ = i,env = {})))
case ((n,VAR(instantiated = (tv as Types.VAR(attributes = Types.ATTR(parameter_ = var),type_ = tp)),declaration = SOME((elt,_)),typed = i,env = {})))
equation
s = SCode.variabilityString(var);
elt_str = SCode.printElementStr(elt);
Expand All @@ -865,7 +873,7 @@ algorithm
"}, compframe: []"});
then
res;
case ((n,VAR(instantiated = Types.VAR(binding = bnd),declaration = NONE,if_ = i,env = env)))
case ((n,VAR(instantiated = Types.VAR(binding = bnd),declaration = NONE,typed = i,env = env)))
equation
res = Util.stringAppendList({"v:",n,"\n"});
then
Expand Down
4 changes: 4 additions & 0 deletions Compiler/Error.mo
Expand Up @@ -268,6 +268,8 @@ public constant ErrorID MODIFIER_TYPE_MISMATCH_ERROR=87;

public constant ErrorID ERROR_FLATTENING=88;

public constant ErrorID DUPLICATE_ELEMENTS_NOT_IDENTICAL=89;

public constant ErrorID UNBOUND_PARAMETER_WARNING=500;

public constant ErrorID BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER=501;
Expand Down Expand Up @@ -446,6 +448,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
"Type mismatch in modifier, expected type %s, got modifier %s of type %s"),
(ERROR_FLATTENING,TRANSLATION(),ERROR(),
"Error occured while flattening model %s"),
(DUPLICATE_ELEMENTS_NOT_IDENTICAL,TRANSLATION(),ERROR(),
"Error duplicate elements (due to inherited elements) not identical, first element is: %s, second element is: %s."),
(UNBOUND_PARAMETER_WARNING,TRANSLATION(),WARNING(),
"Warning, parameter %s has no value."),
(BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER(),TRANSLATION(),WARNING(),
Expand Down
87 changes: 77 additions & 10 deletions Compiler/Inst.mo
Expand Up @@ -1136,8 +1136,9 @@ algorithm
cache = addCachedEnv(cache,n,env_1);
then
(cache,l,env_1,csets_1,ci_state_1,tys,bc);
case (_,_,_,_,csets,_,_,_,_,_)
case (cache,env,mods,pre,csets,ci_state,(c as SCode.CLASS(name = n,restricion = r,parts = d)),prot,inst_dims,impl)
equation
//print("instClassIn(");print(n);print("failed\n");
//Debug.fprint("failtrace", "- inst_class_in failed\n");
then
fail();
Expand Down Expand Up @@ -2982,7 +2983,7 @@ algorithm
cmod_1 = Mod.merge(compmod, cmod, env, pre);
env_1 = Env.extendFrameV(env,
Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,
(Types.T_NOTYPE(),NONE),Types.UNBOUND()), SOME((comp,cmod_1)), false, {}) "comp env" ;
(Types.T_NOTYPE(),NONE),Types.UNBOUND()), SOME((comp,cmod_1)), false, {});
env_2 = addComponentsToEnv2(env_1, mods, pre, csets, ci_state, xs, inst_dims, impl);
then
env_2;
Expand Down Expand Up @@ -3124,12 +3125,6 @@ algorithm
case (cache,env,mod,pre,csets,ci_state,(SCode.IMPORT(import_ = imp),_),instdims,_)
then (cache,{},env,csets,ci_state,{});

/* If a variable is declared multiple times, the first is used */
case (cache,env,mods,pre,csets,ci_state,(SCode.COMPONENT(component = n,final_ = final_,replaceable_ = repl,protected_ = prot),_),_,_)
equation
(_,_,NONE,true,_) = Lookup.lookupIdentLocal(cache,env, n);
then
(cache,{},env,csets,ci_state,{});

/* Illegal redeclarations */
case (cache,env,mods,pre,csets,ci_state,(SCode.CLASSDEF(name = n),_),_,_)
Expand Down Expand Up @@ -3181,6 +3176,7 @@ algorithm
type_ = t,mod = m,baseclass = bc,this = comment)),cmod),inst_dims,impl)
local String s;
equation
checkMultiplyDeclared(cache,env,mods,pre,csets,ci_state,(comp,cmod),inst_dims,impl); // Fails if multiple decls not identical
vn = Prefix.prefixCref(pre, Exp.CREF_IDENT(n,{})) "//Debug.fprint(\"insttr\", \"Instantiating component \") &
//Debug.fprint(\"insttr\", n) & //Debug.fprint(\"insttr\", \"\\n\") &" ;
classmod = Mod.lookupModificationP(mods, t) "The class definition is fetched from the environment. Then the set of modifications is calculated. The modificions is the result of merging the modifications from several sources. The modification stored with the class definition is put in the variable `classmod\', the modification passed to the function_ is extracted and put in the variable `mm\', and the modification that is included in the variable declaration is in the variable `m\'. All of these are merged so that the correct precedence rules are followed." ;
Expand Down Expand Up @@ -3244,6 +3240,77 @@ algorithm
end matchcontinue;
end instElement;

protected function checkMultiplyDeclared "Check if variable is multiply declared and that
all declarations are identical if so."
input Env.Cache cache;
input Env env;
input Mod mod;
input Prefix prefix;
input Connect.Sets csets;
input ClassInf.State ciState;
input tuple<SCode.Element, Mod> compTuple;
input InstDims instDims;
input Boolean impl;

algorithm
_ := matchcontinue(cache,env,mod,prefix,csets,ciState,compTuple,instDims,impl)
local
list<Env.Frame> env,env_1,env2,env2_1,cenv,compenv;
Types.Mod mod;
String n;
Boolean final_,repl,prot;
/* If a variable is declared multiple times, the first is used. If the two variables are not
identical, an error is given.
*/
case (cache,env,mod,prefix,csets,ciState,(newComp as (SCode.COMPONENT(component = n,final_ = final_,replaceable_ = repl,protected_ = prot),_)),_,_)
local
SCode.Element oldElt; Types.Mod oldMod;
tuple<SCode.Element,Types.Mod> newComp;
equation
//print(n);
//print("looking for multiple declared components, env:");
//print(Env.printEnvStr(env));
(_,_,SOME((oldElt,oldMod)),true,_) = Lookup.lookupIdentLocal(cache,env, n);
checkMultipleElementsIdentical((oldElt,oldMod),newComp);
then
();

// If not multiply declared, return.
case (cache,env,mod,prefix,csets,ciState,(newComp as (SCode.COMPONENT(component = n,final_ = final_,replaceable_ = repl,protected_ = prot),_)),_,_)
local
SCode.Element oldElt; Types.Mod oldMod;
tuple<SCode.Element,Types.Mod> newComp;
equation
failure((_,_,SOME((oldElt,oldMod)),true,_) = Lookup.lookupIdentLocal(cache,env, n));
then
();
end matchcontinue;
end checkMultiplyDeclared;

protected function checkMultipleElementsIdentical "checks that the old declaration is identical to
the new one. If not, give error message"
input tuple<SCode.Element,Types.Mod> oldComponent;
input tuple<SCode.Element,Types.Mod> newComponent;

algorithm
_ := matchcontinue(oldComponent,newComponent)
local
SCode.Element oldElt,newElt;
Types.Mod oldMod,newMod;
case((oldElt,oldMod),(newElt,newMod)) equation
true = SCode.elementEqual(oldElt,newElt); // NOTE: Should be type identical instead? see spec.
// p.23, check of flattening. "Check that duplicate elements are identical".
then ();
case ((oldElt,oldMod),(newElt,newMod))
local String s1,s2;
equation
s1 = SCode.unparseElementStr(oldElt);
s2 = SCode.unparseElementStr(newElt);
Error.addMessage(Error.DUPLICATE_ELEMENTS_NOT_IDENTICAL(),{s1,s2});
then fail();
end matchcontinue;
end checkMultipleElementsIdentical;

protected function getDerivedEnv "function: getDerivedEnv
This function returns the environment of a baseclass.
Expand Down Expand Up @@ -4033,7 +4100,7 @@ algorithm
one.
" ;
env_1 = Env.updateFrameV(env2_1,
Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,ty,binding_1), false, compenv) "type info present" ;
Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,ty,binding_1), true, compenv) "type info present" ;
then
(cache,env_1,csets_1);

Expand Down Expand Up @@ -4083,7 +4150,7 @@ algorithm
dims, {}, {}, false, NONE) "Instantiate the component" ;
(cache,binding) = makeBinding(cache,env2, attr, mod_3, ty) "The environment is extended with the new variable binding." ;
env_1 = Env.updateFrameV(env2,
Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,ty,binding), false, compenv) "type info present" ;
Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,ty,binding), true, compenv) "type info present" ;
then
(cache,env_1,csets_1);
case (cache,mod,cref,env,ci_state,csets,impl)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Interactive.mo
Expand Up @@ -938,7 +938,7 @@ algorithm
(_,_,_,_) = Lookup.lookupVar(Env.emptyCache,env, Exp.CREF_IDENT(id,{}));
env_1 = Env.updateFrameV(env,
Types.VAR(id,Types.ATTR(false,SCode.RW(),SCode.VAR(),Absyn.BIDIR()),
false,tp,Types.VALBOUND(v)), false, {});
false,tp,Types.VALBOUND(v)), true, {});
env_2 = addVarsToEnv(rest, env_1);
then
env_2;
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Lookup.mo
Expand Up @@ -304,7 +304,7 @@ algorithm
fail();
case (cache,env,path,false)
equation
// print("lookupClass(");print(Absyn.pathString(path));print(",msg=false failed, env:");
//print("lookupClass(");print(Absyn.pathString(path));print(",msg=false failed, env:");
//print(Env.printEnvStr(env));print("\n");
then
fail();
Expand Down

0 comments on commit bf014d5

Please sign in to comment.