Skip to content

Commit

Permalink
- second attempt to fix bugs: #1405 and #1970
Browse files Browse the repository at this point in the history
  it will generate some missing each warnings for modifiers but it will work otherwise.
  i'll get rid of the warnings later.
- added tests with both models and more:
  testsuite/flattening/modelica/arrays/TypeTest.mos
- let's see how many tests will fail now.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@14273 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adrpo committed Dec 6, 2012
1 parent dc12dd7 commit 0af9f47
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 54 deletions.
113 changes: 59 additions & 54 deletions Compiler/FrontEnd/Inst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -8216,26 +8216,31 @@ algorithm
DAE.ElementSource source;
SCode.Variability vt;

// impl component environment dae elements for component Variables of userdefined type,
// e.g. Point p => Real p[3]; These must be handled separately since even if they do not
// appear to be an array, they can. Therefore we need to collect
// the full dimensionality and call instVar2
// impl component environment dae elements for component Variables of userdefined type,
// e.g. Point p => Real p[3]; These must be handled separately since even if they do not
// appear to be an array, they can. Therefore we need to collect
// the full dimensionality and call instVar2
case (cache,env,ih,store,ci_state,mod,pre,n,(cl as SCode.CLASS(name = id)),attr as SCode.ATTR(variability = vt),pf,dims,idxs,inst_dims,impl,comment,_,graph,csets)
equation
// Collect dimensions
p1 = Absyn.IDENT(n);
p1 = PrefixUtil.prefixPath(p1,pre);
str = Absyn.pathString(p1);
Error.updateCurrentComponent(str,info);
(cache, dims as (_ :: _),cl,type_mods) = getUsertypeDimensions(cache, env, ih, mod, pre, cl, inst_dims, impl);
(cache, dims as (_ :: _),cl,type_mods) = getUsertypeDimensions(cache, env, ih, pre, cl, inst_dims, impl);

//type_mods = Mod.addEachIfNeeded(type_mods, dims);
//mod = Mod.addEachIfNeeded(mod, inDimensionLst);

dims = listAppend(inDimensionLst, dims);
mod = Mod.merge(mod, type_mods, env, pre);

attr = propagateClassPrefix(attr,pre);
(cache,compenv,ih,store,dae,csets,ty,graph) =
instVar2(cache,env,ih,store, ci_state, mod, pre, n, cl, attr,
instVar2(cache, env, ih, store, ci_state, mod, pre, n, cl, attr,
pf, dims, idxs, inst_dims, impl, comment, info, graph, csets);
source = DAEUtil.createElementSource(info, Env.getEnvPath(env), PrefixUtil.prefixToCrefOpt(pre), NONE(), NONE());
(cache,dae) = addArrayVarEquation(cache,env,ih,ci_state, dae, ty, mod, NFInstUtil.toConst(vt), pre, n, source);
(cache,dae) = addArrayVarEquation(cache, env, ih, ci_state, dae, ty, mod, NFInstUtil.toConst(vt), pre, n, source);
cache = addRecordConstructorFunction(cache,Types.arrayElementType(ty));
Error.updateCurrentComponent("",Absyn.dummyInfo);
then
Expand Down Expand Up @@ -9155,7 +9160,6 @@ public function getUsertypeDimensions
input Env.Cache inCache;
input Env.Env inEnv;
input InstanceHierarchy inIH;
input DAE.Mod inMod;
input Prefix.Prefix inPrefix;
input SCode.Element inClass;
input InstDims inInstDims;
Expand All @@ -9165,7 +9169,7 @@ public function getUsertypeDimensions
output SCode.Element classToInstantiate;
output DAE.Mod outMods "modifications from base classes";
algorithm
(outCache,outDimensionLst,classToInstantiate,outMods) := matchcontinue (inCache,inEnv,inIH,inMod,inPrefix,inClass,inInstDims,inBoolean)
(outCache,outDimensionLst,classToInstantiate,outMods) := matchcontinue (inCache,inEnv,inIH,inPrefix,inClass,inInstDims,inBoolean)
local
SCode.Element cl;
list<Env.Frame> cenv,env;
Expand All @@ -9187,19 +9191,19 @@ algorithm
list<SCode.Element> els;
SCode.Path path;

case (cache,_,_,_,_,cl as SCode.CLASS(name = "Real"),_,_) then (cache,{},cl,DAE.NOMOD()); /* impl */
case (cache,_,_,_,_,cl as SCode.CLASS(name = "Integer"),_,_) then (cache,{},cl,DAE.NOMOD());
case (cache,_,_,_,_,cl as SCode.CLASS(name = "String"),_,_) then (cache,{},cl,DAE.NOMOD());
case (cache,_,_,_,_,cl as SCode.CLASS(name = "Boolean"),_,_) then (cache,{},cl,DAE.NOMOD());
case (cache, _, _, _, cl as SCode.CLASS(name = "Real"), _, _) then (cache,{},cl,DAE.NOMOD());
case (cache, _, _, _, cl as SCode.CLASS(name = "Integer"), _, _) then (cache,{},cl,DAE.NOMOD());
case (cache, _, _, _, cl as SCode.CLASS(name = "String"), _, _) then (cache,{},cl,DAE.NOMOD());
case (cache, _, _, _, cl as SCode.CLASS(name = "Boolean"), _, _) then (cache,{},cl,DAE.NOMOD());

case (cache,_,_,_,_,cl as SCode.CLASS(restriction = SCode.R_RECORD(),
classDef = SCode.PARTS(elementLst = _)),_,_) then (cache,{},cl,DAE.NOMOD());
case (cache, _, _, _, cl as SCode.CLASS(restriction = SCode.R_RECORD(),
classDef = SCode.PARTS(elementLst = _)), _, _) then (cache,{},cl,DAE.NOMOD());

/*------------------------*/
/* MetaModelica extension */
case (cache,env,ih,_,pre,cl as SCode.CLASS(name = id, info=info,
classDef = SCode.DERIVED(Absyn.TCOMPLEX(Absyn.IDENT(_),_,arrayDim = ad),
modifications = mod)),
//------------------------
// MetaModelica extension
case (cache, env, ih, pre, cl as SCode.CLASS(name = id, info=info,
classDef = SCode.DERIVED(Absyn.TCOMPLEX(Absyn.IDENT(_),_,arrayDim = ad),
modifications = mod)),
dims,impl)
equation
true=Config.acceptMetaModelicaGrammar();
Expand All @@ -9211,78 +9215,79 @@ algorithm
(cache,dim1,cl,DAE.NOMOD());

// Partial function definitions with no output - stefan
case (cache,env,ih,_,_,
case (cache, env, ih, _,
cl as SCode.CLASS(name = id,restriction = SCode.R_FUNCTION(SCode.FR_NORMAL_FUNCTION()),
partialPrefix = SCode.PARTIAL()),_,_)
partialPrefix = SCode.PARTIAL()), _, _)
then
(cache,{},cl,DAE.NOMOD());

case (cache,env,ih,_,_,
case (cache, env, ih, _,
SCode.CLASS(name = id,info=info,restriction = SCode.R_FUNCTION(SCode.FR_NORMAL_FUNCTION()),
partialPrefix = SCode.NOT_PARTIAL()),_,_)
equation
Error.addSourceMessage(Error.META_FUNCTION_TYPE_NO_PARTIAL_PREFIX, {id}, info);
then fail();

// MetaModelica Uniontype. Added 2009-05-11 sjoelund
case (cache,env,ih,_,_,
cl as SCode.CLASS(name = id,restriction = SCode.R_UNIONTYPE()),_,_)
// MetaModelica Uniontype. Added 2009-05-11 sjoelund
case (cache, env, ih, _,
cl as SCode.CLASS(name = id,restriction = SCode.R_UNIONTYPE()), _, _)
then (cache,{},cl,DAE.NOMOD());
/*----------------------*/

/* Derived classes with restriction type, e.g. type Point = Real[3]; */
case (cache,env,ih,mods,pre,
// Derived classes with restriction type, e.g. type Point = Real[3];
case (cache, env, ih, pre,
SCode.CLASS(name = id,restriction = SCode.R_TYPE(),info=info,
classDef = SCode.DERIVED(Absyn.TPATH(path = cn, arrayDim = ad),modifications = mod)),
dims,impl)
classDef = SCode.DERIVED(Absyn.TPATH(path = cn, arrayDim = ad),modifications = mod)),
dims, impl)
equation
(cache,cl,cenv) = Lookup.lookupClass(cache,env, cn, true);
(cache,cl,cenv) = Lookup.lookupClass(cache, env, cn, true);
owncref = Absyn.CREF_IDENT(id,{});
ad_1 = getOptionArraydim(ad);
env = addEnumerationLiteralsToEnv(env, cl);

mod = chainRedeclares(mods, mod);

(cache,mod_1) = Mod.elabMod(cache, env, ih, pre, mod, impl, info);
mods_2 = Mod.merge(mods, mod_1, env, pre);
eq = Mod.modEquation(mods_2);
mods_3 = Mod.lookupCompModification(mods_2, id);
(cache,dim1,cl,type_mods) = getUsertypeDimensions(cache,cenv,ih, mods_3, pre, cl, dims, impl);
eq = Mod.modEquation(mod_1);
(cache,dim1,cl,type_mods) = getUsertypeDimensions(cache, cenv, ih, pre, cl, dims, impl);
(cache,dim2) = elabArraydim(cache, env, owncref, cn, ad_1, eq, impl, NONE(), true, false, pre, info, dims);
type_mods = Mod.addEachIfNeeded(type_mods, dim1);
// do not add each to mod_1, it should have it already!
// mod_1 = Mod.addEachIfNeeded(mod_1, dim2);
type_mods = Mod.merge(mod_1, type_mods, env, pre);
(cache,dim2) = elabArraydim(cache,env, owncref, cn, ad_1, eq, impl,NONE(),true, false,pre,info,dims);
res = listAppend(dim2, dim1);
then
(cache,res,cl,type_mods);

/* extended classes type Y = Real[3]; class X extends Y; */
case (cache,env,ih,mods,pre,
SCode.CLASS(name = id,restriction = _,
// extended classes type Y = Real[3]; class X extends Y;
case (cache, env, ih, pre,
SCode.CLASS(name = id, restriction = _,
classDef = SCode.PARTS(elementLst=els,
normalEquationLst={},
initialEquationLst={},
normalAlgorithmLst={},
initialAlgorithmLst={},
externalDecl=_)),
dims,impl)
normalEquationLst = {},
initialEquationLst = {},
normalAlgorithmLst = {},
initialAlgorithmLst = {},
externalDecl = _)),
dims, impl)
equation
(_,_,{SCode.EXTENDS(path, _, mod,_, info)},{}) = splitElts(els); // ONLY ONE extends!
(cache,mod_1) = Mod.elabModForBasicType(cache, env, ih, pre, mod, impl, info);
mods_2 = Mod.merge(mods, mod_1, env, pre);
(cache,cl,cenv) = Lookup.lookupClass(cache,env, path, false);
(cache,res,cl,type_mods) = getUsertypeDimensions(cache,env,ih,mods_2,pre,cl,{},impl);
type_mods = Mod.merge(mods_2, type_mods, env, pre);
(cache,cl,cenv) = Lookup.lookupClass(cache, env, path, false);
(cache,res,cl,type_mods) = getUsertypeDimensions(cache,env,ih,pre,cl,{},impl);
type_mods = Mod.addEachIfNeeded(type_mods, res);
type_mods = Mod.merge(mod_1, type_mods, env, pre);
then
(cache,res,cl,type_mods);

case (cache,_,_,_,_,cl as SCode.CLASS(name = _),_,_)
case (cache, _, _, _, cl as SCode.CLASS(name = _), _, _)
then (cache,{},cl,DAE.NOMOD());

case (_,_,_,_,_,SCode.CLASS(name = id),_,_)
case (_, _, _, _, SCode.CLASS(name = id), _, _)
equation
true = Flags.isSet(Flags.FAILTRACE);
id = SCodeDump.printClassStr(inClass);
Debug.traceln("Inst.getUsertypeDimensions failed: " +& id);
then fail();
then
fail();

end matchcontinue;
end getUsertypeDimensions;

Expand Down
82 changes: 82 additions & 0 deletions Compiler/FrontEnd/Mod.mo
Original file line number Diff line number Diff line change
Expand Up @@ -3538,5 +3538,87 @@ algorithm outsubs := match(inSubs,componentName)
end match;
end removeModInSubs;

public function addEachIfNeeded
"This function adds each to the mods
if the dimensions are not empty."
input DAE.Mod inMod;
input DAE.Dimensions inDimensions;
output DAE.Mod outMod;
algorithm
outMod := matchcontinue (inMod, inDimensions)
local
SCode.Final finalPrefix;
list<tuple<SCode.Element, DAE.Mod>> elist;
SCode.Each eachPrefix;
list<DAE.SubMod> subs;
Option<DAE.EqMod> eq;

case (_, {}) then inMod;
case (DAE.NOMOD(), _) then DAE.NOMOD();

// do not apply if dimensions are more than 1 (only leafs)
case (_, _)
equation
true = listLength(inDimensions) > 1;
then
inMod;

case (DAE.REDECL(finalPrefix,eachPrefix,elist), _)
then
DAE.REDECL(finalPrefix,SCode.EACH(),elist);

// do not each the subs of already each'ed mod
case (DAE.MOD(finalPrefix,SCode.EACH(),subs,eq), _)
then
DAE.MOD(finalPrefix,SCode.EACH(),subs,eq);

case (DAE.MOD(finalPrefix,eachPrefix,subs,eq), _)
equation
subs = addEachToSubsIfNeeded(subs, inDimensions);
then
DAE.MOD(finalPrefix,SCode.EACH(),subs,eq);

case(_, _)
equation
print("Mod.addEachIfNeeded failed on: " +& printModStr(inMod) +& "\n");
then
fail();

end matchcontinue;
end addEachIfNeeded;

public function addEachToSubsIfNeeded
input list<DAE.SubMod> inSubMods;
input DAE.Dimensions inDimensions;
output list<DAE.SubMod> outSubMods;
algorithm
outSubMods := matchcontinue(inSubMods, inDimensions)
local
list<DAE.SubMod> rest;
DAE.Mod m;
String id;
list<Integer> idxs;

case (_, {}) then inSubMods;

case ({}, _) then {};

case (DAE.NAMEMOD(id, m)::rest, _)
equation
m = addEachIfNeeded(m, inDimensions);
rest = addEachToSubsIfNeeded(rest, inDimensions);
then
DAE.NAMEMOD(id, m)::rest;

case (DAE.IDXMOD(idxs, m)::rest, _)
equation
m = addEachIfNeeded(m, inDimensions);
rest = addEachToSubsIfNeeded(rest, inDimensions);
then
DAE.IDXMOD(idxs, m)::rest;

end matchcontinue;
end addEachToSubsIfNeeded;

end Mod;

0 comments on commit 0af9f47

Please sign in to comment.