Skip to content

Commit

Permalink
Added support for nested MetaModelica lists + some minor improvements.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@2838 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Kristian Stavåker committed Jun 19, 2007
1 parent 36fb88f commit 157479b
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 135 deletions.
1 change: 1 addition & 0 deletions Compiler/Absyn.mo
Expand Up @@ -744,6 +744,7 @@ uniontype Exp "The Exp uniontype is the container of a Modelica expression.
Exp rest " rest of the list ";
end CONS;

// This one is only used internaly in the compiler
record LIST "Part of MetaModelica extension"
list<Exp> exps;
end LIST;
Expand Down
78 changes: 20 additions & 58 deletions Compiler/Inst.mo
Expand Up @@ -3600,17 +3600,24 @@ algorithm
(cache,dae,env_1,csets_1,ci_state,vars);

//------------------------------------------------------------------------
// The "MetaModelica list" case, part of a MetaModelica extension. KS
// The "MetaModelica list" case, part of MetaModelica extension. KS
//------------------------------------------------------------------------
case (cache,env,mods,pre,csets,ci_state,((comp as SCode.COMPONENT(component = n,innerOuter=io,final_ = final_,replaceable_ = repl,protected_ = prot,
attributes = (attr as SCode.ATTR(arrayDim = ad,flow_ = flow_,RW = acc,parameter_ = param,input_ = dir)),
typeSpec = Absyn.TCOMPLEX(Absyn.IDENT("list"),Absyn.TPATH(t,_) :: _,_), mod = m,baseclass = bc,this = comment)),cmod),inst_dims,impl)
typeSpec = Absyn.TCOMPLEX(Absyn.IDENT("list"),tSpec :: _,_), mod = m,baseclass = bc,this = comment)),cmod),inst_dims,impl)
local String s;
Boolean allreadyDeclared;
list<Types.Var> vars;
Absyn.TypeSpec tSpec;
Absyn.TypeSpec tSpec;
Integer numberOfLists;
equation
//true = RTOpts.acceptMetaModelicaGrammar();
true = RTOpts.acceptMetaModelicaGrammar();

// Derive the basic type of the list and the number of lists (since a list can be nested)
//------------------------------------------------
(t,numberOfLists) = MetaUtil.evalTypeSpec(tSpec,1);
//------------------------------------------------

// Fails if multiple decls not identical
allreadyDeclared = checkMultiplyDeclared(cache,env,mods,pre,csets,ci_state,(comp,cmod),inst_dims,impl);
checkRecursiveDefinition(env,t);
Expand Down Expand Up @@ -3653,9 +3660,8 @@ algorithm
mod1_1 = Mod.merge(cmod, mod1, env2, pre);

/* Apply redeclaration modifier to component */
(cache,SCode.COMPONENT(n,io,final_,repl,prot,(attr as SCode.ATTR(ad,flow_,acc,param,dir)),tSpec,m,bc,comment),mod_1,env2_1,csets)
(cache,SCode.COMPONENT(n,io,final_,repl,prot,(attr as SCode.ATTR(ad,flow_,acc,param,dir)),_,m,bc,comment),mod_1,env2_1,csets)
= redeclareType(cache,mod1_1, comp, env2, pre, ci_state, csets, impl);
t = evalTypeSpec(tSpec);

(cache,env_1) = getDerivedEnv(cache,env, bc);
(cache,cl,cenv) = Lookup.lookupClass(cache,env_1, t, true);
Expand All @@ -3671,9 +3677,9 @@ algorithm
(cache,compenv,dae,csets_1,ty) = instVar(cache,cenv, ci_state, mod_1, pre, csets, n, cl, attr, prot, dims, {}, inst_dims, impl, comment,io);

//---------------------------------
// Add the list type to the var
ty = (Types.T_LIST(ty),NONE());
dae = addListTypeToDAE(dae,ty);
// Add the list type to the dae
ty = MetaUtil.createListType(ty,numberOfLists);
dae = MetaUtil.addListTypeToDAE(dae,ty);
//---------------------------------

//The environment is extended (updated) with the new variable binding.
Expand Down Expand Up @@ -3723,53 +3729,6 @@ algorithm
end instElement;


//------------------------------------------
// Part of MetaModelica list extension. KS
//------------------------------------------

public function addListTypeToDAE "function: addListTypeToDAE"
input list<DAE.Element> daeElem;
input Types.Type inType;
output list<DAE.Element> outElem;
algorithm
outElem :=
matchcontinue (daeElem,inType)
case (DAE.VAR(vn,kind,dir,prot,_,e,inst_dims,fl,lPath,dae_var_attr,comment,io,_) :: restList,t)
local
list<DAE.Element> daeE,restList;
Exp.ComponentRef vn;
DAE.VarKind kind;
DAE.VarDirection dir;
DAE.VarProtection prot;
Option<Exp.Exp> e;
DAE.InstDims inst_dims;
DAE.Flow fl;
list<Absyn.Path> lPath;
Option<DAE.VariableAttributes> dae_var_attr;
Option<Absyn.Comment> comment;
Absyn.InnerOuter io;
Types.Type t;
equation
daeE = (DAE.VAR(vn,kind,dir,prot,DAE.LIST(),e,inst_dims,fl,lPath,dae_var_attr,comment,io,t) :: restList);
then daeE;
end matchcontinue;
end addListTypeToDAE;


public function evalTypeSpec "function: evalTypeSpec"
input Absyn.TypeSpec typeSpec;
output Absyn.Path outPath;
algorithm
(outPath,listBool) :=
matchcontinue (typeSpec)
local
Absyn.Path tpath;
case (Absyn.TPATH(tpath, _)) then tpath;
case (Absyn.TCOMPLEX(_,Absyn.TPATH(tpath,_) :: _,_)) then tpath;
end matchcontinue;
end evalTypeSpec;
//------------------------------------------

protected function removeSelfModReference "Help function to elabMod, removes self-references in modifiers.
For instance, A a(x = a.y)
the modifier references the component itself. This is removed to avoid a circular dependency, resulting in
Expand Down Expand Up @@ -7247,7 +7206,7 @@ algorithm
then
(cache,dae,env,csets_1,ci_state_1);


//------------------------------------------------------
// Part of the MetaModelica extension
/* equality equations cref = Array(...) */
Expand Down Expand Up @@ -8189,7 +8148,7 @@ algorithm
list<Absyn.Exp> expList;
Types.Type t2;
equation
//true = RTOpts.acceptMetaModelicaGrammar();
true = RTOpts.acceptMetaModelicaGrammar();

// If this is a list assignment, then the Array(...) expression should
// be evaluated to Exp.LIST
Expand All @@ -8200,6 +8159,9 @@ algorithm
(cache,Exp.CREF(ce,t)) = Prefix.prefixExp(cache,env, cre, pre);
(cache,ce_1) = Static.canonCref(cache,env, ce, impl);

// In case we have a nested list expression
expList = MetaUtil.transformArrayNodesToListNodes(expList,{});

(cache,e_1,eprop,_) = Static.elabListExp(cache,env, expList, cprop, impl, NONE,true);

(cache,e_2) = Prefix.prefixExp(cache,env, e_1, pre);
Expand Down
124 changes: 119 additions & 5 deletions Compiler/MetaUtil.mo
Expand Up @@ -51,7 +51,8 @@ public import Lookup;
public import Debug;
public import Env;
public import Absyn;
public import SCode;
public import SCode;
public import DAE;

public function isList "function: isList
author: KS
Expand Down Expand Up @@ -108,6 +109,7 @@ algorithm
local
Types.Type tLocal,t;
Boolean b2;
case (Types.PROP(tLocal,_),Types.PROP((Types.T_LIST((Types.T_NOTYPE(),_)),_),_)) then true;
case (Types.PROP(tLocal,_),Types.PROP((Types.T_LIST(t),_),_))
equation
b2 = Types.subtype(tLocal,t);
Expand Down Expand Up @@ -197,12 +199,12 @@ algorithm
equation
fn2 = Absyn.crefToPath(fn);
(cache,SCode.CLASS(_,_,_,_,SCode.PARTS(elemList,_,_,_,_,_)),env)
= Lookup.lookupClass(cache,env, fn2,true);
= Lookup.lookupClass(cache,env, fn2,true);

typeList = Util.listMap(elemList,extractNameAndType);
args = fixListConstructorsInArgs2(typeList,args,{});
nargs = fixListConstructorsInArgs3(typeList,nargs,{});
then (cache,env,args,nargs);
then (cache,env,args,nargs);
end matchcontinue;
end fixListConstructorsInArgs;

Expand Down Expand Up @@ -244,7 +246,8 @@ algorithm
local
list<Absyn.Exp> expList,restArgs;
list<Option<tuple<Absyn.Ident,Absyn.TypeSpec>>> restTypes;
equation
equation
expList = transformArrayNodesToListNodes(expList,{});
localAccList = listAppend(localAccList,{Absyn.LIST(expList)});
localAccList = fixListConstructorsInArgs2(restTypes,restArgs,localAccList);
then localAccList;
Expand Down Expand Up @@ -291,6 +294,7 @@ algorithm
list<Absyn.NamedArg> restArgs;
equation
Absyn.TCOMPLEX(Absyn.IDENT("list"),_,_) = findArgType(id,argTypes);
expList = transformArrayNodesToListNodes(expList,{});
localAccList = listAppend(localAccList,{Absyn.NAMEDARG(id,Absyn.LIST(expList))});
localAccList = fixListConstructorsInArgs3(argTypes,restArgs,localAccList);
then localAccList;
Expand Down Expand Up @@ -337,6 +341,115 @@ algorithm
end matchcontinue;
end findArgType;

public function transformArrayNodesToListNodes
input list<Absyn.Exp> inList;
input list<Absyn.Exp> accList;
output list<Absyn.Exp> outList;
algorithm
outList :=
matchcontinue (inList,accList)
local
list<Absyn.Exp> localAccList;
case ({},localAccList) then localAccList;
case (Absyn.ARRAY({}) :: restList,localAccList)
local
list<Absyn.Exp> restList;
equation
localAccList = listAppend(localAccList,{Absyn.LIST({})});
localAccList = transformArrayNodesToListNodes(restList,localAccList);
then localAccList;
case (Absyn.ARRAY(es) :: restList,localAccList)
local
list<Absyn.Exp> es,restList;
equation
es = transformArrayNodesToListNodes(es,{});
localAccList = listAppend(localAccList,{Absyn.LIST(es)});
localAccList = transformArrayNodesToListNodes(restList,localAccList);
then localAccList;
case (firstExp :: restList,localAccList)
local
list<Absyn.Exp> restList;
Absyn.Exp firstExp;
equation
localAccList = listAppend(localAccList,{firstExp});
localAccList = transformArrayNodesToListNodes(restList,localAccList);
then localAccList;
end matchcontinue;
end transformArrayNodesToListNodes;


public function evalTypeSpec "function: evalTypeSpec"
input Absyn.TypeSpec typeSpec;
input Integer numLists;
output Absyn.Path outPath;
output Integer outNumLists;
algorithm
(outPath,outNumLists) :=
matchcontinue (typeSpec,numLists)
local
Absyn.Path tpath;
Integer n;
case (Absyn.TPATH(tpath, _),n) then (tpath,n);
case (Absyn.TCOMPLEX(Absyn.IDENT("list"),tSpec :: _,_),n)
local
Absyn.TypeSpec tSpec;
equation
(tpath,n) = evalTypeSpec(tSpec,n+1);
then (tpath,n);
end matchcontinue;
end evalTypeSpec;

public function createListType "function: createListType"
input Types.Type inType;
input Integer numLists;
output Types.Type outType;
algorithm
outType :=
matchcontinue (inType,numLists)
local
Types.Type localT;
case (localT,0) then localT;
case (localT,n)
local
Integer n;
Types.Type t;
equation
t = (Types.T_LIST(localT),NONE());
t = createListType(t,n-1);
then t;
end matchcontinue;
end createListType;


public function addListTypeToDAE "function: addListTypeToDAE"
input list<DAE.Element> daeElem;
input Types.Type inType;
output list<DAE.Element> outElem;
algorithm
outElem :=
matchcontinue (daeElem,inType)
case (DAE.VAR(vn,kind,dir,prot,_,e,inst_dims,fl,lPath,dae_var_attr,comment,io,_) :: restList,t)
local
list<DAE.Element> daeE,restList;
Exp.ComponentRef vn;
DAE.VarKind kind;
DAE.VarDirection dir;
DAE.VarProtection prot;
Option<Exp.Exp> e;
DAE.InstDims inst_dims;
DAE.Flow fl;
list<Absyn.Path> lPath;
Option<DAE.VariableAttributes> dae_var_attr;
Option<Absyn.Comment> comment;
Absyn.InnerOuter io;
Types.Type t;
equation
daeE = (DAE.VAR(vn,kind,dir,prot,DAE.LIST(),e,inst_dims,fl,lPath,dae_var_attr,comment,io,t) :: restList);
then daeE;
end matchcontinue;
end addListTypeToDAE;


/*
public function typeMatching
input Types.Type t;
Expand Down Expand Up @@ -390,4 +503,5 @@ algorithm
end matchcontinue;
end typeMatching; */


end MetaUtil;

0 comments on commit 157479b

Please sign in to comment.