Skip to content

Commit

Permalink
NFInst improvements.
Browse files Browse the repository at this point in the history
- Implemented new type ClassTree which contains a class' elements,
  and moved some of the instantiation logic to it.
- Implemented new type Sections which contains a class' equations and
  algorithms.
- Added new class type DERIVED_CLASS to better handle short class
  definitions.
- Implemented some basic support for class prefixes.
- Improved the handling of imports.
- Improved the handling of modifiers, though element redeclares are
  currently broken (but didn't really work well before anyway).
- Improved the handling of package constants.
- Fixed lots of lookup and scoping issues.
- Rewrote SCode.translateArgs to filter out empty modifiers better.
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jun 16, 2017
1 parent 4e4ac93 commit c7d04e1
Show file tree
Hide file tree
Showing 25 changed files with 2,760 additions and 1,877 deletions.
13 changes: 13 additions & 0 deletions Compiler/FrontEnd/Absyn.mo
Expand Up @@ -6841,5 +6841,18 @@ algorithm
end match;
end isInvariantExpNoTraverse;

function pathPartCount
"Returns the number of parts a path consists of, e.g. A.B.C gives 3."
input Path path;
input Integer partsAccum = 0;
output Integer parts;
algorithm
parts := match path
case Path.IDENT() then partsAccum + 1;
case Path.QUALIFIED() then pathPartCount(path.path, partsAccum + 1);
case Path.FULLYQUALIFIED() then pathPartCount(path.path, partsAccum);
end match;
end pathPartCount;

annotation(__OpenModelica_Interface="frontend");
end Absyn;
10 changes: 10 additions & 0 deletions Compiler/FrontEnd/SCode.mo
Expand Up @@ -5759,5 +5759,15 @@ algorithm
end match;
end isArrayComponent;

public function isEmptyMod
input Mod mod;
output Boolean isEmpty;
algorithm
isEmpty := match mod
case Mod.NOMOD() then true;
else false;
end match;
end isEmptyMod;

annotation(__OpenModelica_Interface="frontend");
end SCode;
127 changes: 37 additions & 90 deletions Compiler/FrontEnd/SCodeUtil.mo
Expand Up @@ -1007,8 +1007,9 @@ algorithm
case Absyn.ANNOTATION(elementArgs = args)
equation
m = translateMod(SOME(Absyn.CLASSMOD(args,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), Absyn.dummyInfo);

then
SOME(SCode.ANNOTATION(m));
if SCode.isEmptyMod(m) then NONE() else SOME(SCode.ANNOTATION(m));

end match;
end translateAnnotation;
Expand Down Expand Up @@ -1777,100 +1778,46 @@ algorithm
end match;
end translateMod;

//public function translateMod
//"Builds an SCode.Mod from an Absyn.Modification."
// input Option<Absyn.Modification> inAbsynModificationOption;
// input SCode.Final inFinalPrefix;
// input SCode.Each inEachPrefix;
// input SourceInfo inInfo;
// output SCode.Mod outMod;
//algorithm
// outMod := match (inAbsynModificationOption,inFinalPrefix,inEachPrefix,inInfo)
// local
// Absyn.Exp e;
// SCode.Final finalPrefix;
// SCode.Each eachPrefix;
// list<SCode.SubMod> subs;
// list<Absyn.ElementArg> l;
//
// case (NONE(), SCode.FINAL(), _, _)
// then SCode.MOD(inFinalPrefix, inEachPrefix, {}, NONE(), inInfo);
// case (NONE(),_,_,_) then SCode.NOMOD();
// case (SOME(Absyn.CLASSMOD({},(Absyn.EQMOD(exp=e)))),finalPrefix,eachPrefix,_)
// then SCode.MOD(finalPrefix,eachPrefix,{},SOME(e), inInfo);
// case (SOME(Absyn.CLASSMOD({},(Absyn.NOMOD()))),finalPrefix,eachPrefix,_)
// then SCode.MOD(finalPrefix,eachPrefix,{},NONE(), inInfo);
// case (SOME(Absyn.CLASSMOD(l,Absyn.EQMOD(exp=e))),finalPrefix,eachPrefix,_)
// equation
// subs = translateArgs(l);
// then
// SCode.MOD(finalPrefix, eachPrefix, subs, SOME(e), inInfo);
//
// case (SOME(Absyn.CLASSMOD(l,Absyn.NOMOD())),finalPrefix,eachPrefix,_)
// equation
// subs = translateArgs(l);
// then
// SCode.MOD(finalPrefix, eachPrefix, subs, NONE(), inInfo);
// end match;
//end translateMod;
protected function translateArgs
input list<Absyn.ElementArg> inArgs;
output list<SCode.SubMod> outSubMods;
algorithm
outSubMods := translateArgs_tail(inArgs, {});
end translateArgs;

protected function translateArgs_tail
input list<Absyn.ElementArg> inArgs;
input list<SCode.SubMod> inAccumSubs;
output list<SCode.SubMod> outSubMods;
input list<Absyn.ElementArg> args;
output list<SCode.SubMod> subMods = {};
protected
SCode.Mod smod;
SCode.Element elem;
SCode.SubMod sub;
algorithm
outSubMods := match(inArgs, inAccumSubs)
local
Boolean fp;
Absyn.Each ep;
Option<Absyn.Modification> mod;
SourceInfo info;
list<Absyn.ElementArg> rest_args;
SCode.Mod smod;
Absyn.ElementSpec spec;
String n;
SCode.Element elem;
Absyn.RedeclareKeywords rk;
Option<Absyn.ConstrainClass> cc;
SCode.Final sfp;
SCode.Each sep;
SCode.SubMod sub;
Option<SCode.SubMod> opt_mod;
list<SCode.SubMod> accum;
Absyn.Path p;

case (Absyn.MODIFICATION(finalPrefix = fp, eachPrefix = ep,
path = p, modification = mod, info = info) :: rest_args, _)
equation
smod = translateMod(mod, SCode.boolFinal(fp), translateEach(ep), info);
sub = translateSub(p, smod, info);
then
translateArgs_tail(rest_args, sub :: inAccumSubs);
for arg in args loop
subMods := match arg
case Absyn.MODIFICATION()
algorithm
smod := translateMod(arg.modification, SCode.boolFinal(arg.finalPrefix),
translateEach(arg.eachPrefix), arg.info);

case (Absyn.REDECLARATION(finalPrefix = fp, redeclareKeywords = rk, eachPrefix = ep,
elementSpec = spec, constrainClass = cc, info = info) :: rest_args, accum)
equation
n = Absyn.elementSpecName(spec);
{elem} = translateElementspec(cc, fp, Absyn.NOT_INNER_OUTER(),
SOME(rk), SCode.PUBLIC(), spec, info);
sfp = SCode.boolFinal(fp);
sep = translateEach(ep);
sub = SCode.NAMEMOD(n, SCode.REDECL(sfp, sep, elem));
// first put the redeclare
accum = sub :: accum;
then
translateArgs_tail(rest_args, accum);
if not SCode.isEmptyMod(smod) then
sub := translateSub(arg.path, smod, arg.info);
subMods := sub :: subMods;
end if;
then
subMods;

case ({}, _) then listReverse(inAccumSubs);
case Absyn.REDECLARATION()
algorithm
{elem} := translateElementspec(arg.constrainClass, arg.finalPrefix,
Absyn.NOT_INNER_OUTER(), SOME(arg.redeclareKeywords), SCode.PUBLIC(),
arg.elementSpec, arg.info);

sub := SCode.NAMEMOD(Absyn.elementSpecName(arg.elementSpec),
SCode.REDECL(
SCode.boolFinal(arg.finalPrefix),
translateEach(arg.eachPrefix),
elem));
then
sub :: subMods;
end match;
end for;

end match;
end translateArgs_tail;
subMods := listReverse(subMods);
end translateArgs;

protected function translateSub
"This function converts a Absyn.ComponentRef plus a list
Expand Down
92 changes: 34 additions & 58 deletions Compiler/NFFrontEnd/NFBuiltin.mo
Expand Up @@ -46,14 +46,15 @@ import DAE;
import SCode;
import Binding = NFBinding;
import NFClass.Class;
import NFClass.ClassTree;
import NFClassTree;
import NFComponent.Component;
import Expression = NFExpression;
import NFInstNode.InstNode;
import NFInstNode.InstNodeType;
import NFMod.Modifier;
import Type = NFType;
import BuiltinFuncs = NFBuiltinFuncs;
import Pointer;

encapsulated package Elements
import SCode;
Expand All @@ -64,26 +65,6 @@ encapsulated package Elements
Absyn.TPATH(Absyn.IDENT("$EnumType"), NONE());

// StateSelect-specific elements:
constant SCode.Element STATESELECT_NEVER = SCode.COMPONENT(
"never", SCode.defaultPrefixes, SCode.defaultConstAttr, ENUMTYPE_SPEC,
SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

constant SCode.Element STATESELECT_AVOID = SCode.COMPONENT(
"avoid", SCode.defaultPrefixes, SCode.defaultConstAttr, ENUMTYPE_SPEC,
SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

constant SCode.Element STATESELECT_DEFAULT = SCode.COMPONENT(
"default", SCode.defaultPrefixes, SCode.defaultConstAttr, ENUMTYPE_SPEC,
SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

constant SCode.Element STATESELECT_PREFER = SCode.COMPONENT(
"prefer", SCode.defaultPrefixes, SCode.defaultConstAttr, ENUMTYPE_SPEC,
SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

constant SCode.Element STATESELECT_ALWAYS = SCode.COMPONENT(
"always", SCode.defaultPrefixes, SCode.defaultConstAttr, ENUMTYPE_SPEC,
SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

constant SCode.Element REAL = SCode.CLASS("Real",
SCode.defaultPrefixes, SCode.NOT_ENCAPSULATED(), SCode.NOT_PARTIAL(), SCode.R_TYPE(),
SCode.PARTS({}, {}, {}, {}, {}, {}, {}, NONE()),
Expand Down Expand Up @@ -120,56 +101,51 @@ encapsulated package Elements
}),
SCode.noComment, Absyn.dummyInfo);

// Builtin variable time:
constant SCode.Element TIME = SCode.COMPONENT("time", SCode.defaultPrefixes,
SCode.ATTR({}, SCode.POTENTIAL(), SCode.NON_PARALLEL(), SCode.VAR(), Absyn.INPUT(), Absyn.NONFIELD()),
Absyn.TPATH(Absyn.IDENT("Real"), NONE()), SCode.NOMOD(), SCode.noComment, NONE(), Absyn.dummyInfo);

end Elements;

// InstNodes for the builtin types. These have empty class trees to prevent
// access to the attributes via dot notation (which is not needed for
// modifiers and illegal in other cases).
constant InstNode REAL_TYPE = InstNode.CLASS_NODE("Real",
Elements.REAL,
listArray({Class.PARTIAL_BUILTIN(Type.REAL(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.NO_CACHE()}),
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.REAL(), NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.NO_CACHE()),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant InstNode INT_TYPE = InstNode.CLASS_NODE("Integer",
Elements.INTEGER,
listArray({Class.PARTIAL_BUILTIN(Type.INTEGER(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.FUNCTION({NFBuiltinFuncs.INTEGER}, true)}),
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.INTEGER(), NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.FUNCTION({NFBuiltinFuncs.INTEGER}, true)),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant InstNode BOOLEAN_TYPE = InstNode.CLASS_NODE("Boolean",
Elements.BOOLEAN,
listArray({Class.PARTIAL_BUILTIN(Type.BOOLEAN(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.NO_CACHE()}),
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.BOOLEAN(), NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.NO_CACHE()),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant InstNode STRING_TYPE = InstNode.CLASS_NODE("String",
Elements.STRING,
listArray({Class.PARTIAL_BUILTIN(Type.STRING(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.FUNCTION({
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.STRING(), NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.FUNCTION({
NFBuiltinFuncs.STRING_ENUM, NFBuiltinFuncs.STRING_INT,
NFBuiltinFuncs.STRING_BOOL, NFBuiltinFuncs.STRING_REAL,
NFBuiltinFuncs.STRING_REAL_FORMAT}, true)}),
NFBuiltinFuncs.STRING_REAL_FORMAT}, true)),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant InstNode ENUM_TYPE = InstNode.CLASS_NODE("enumeration",
Elements.ENUMERATION,
listArray({Class.PARTIAL_BUILTIN(Type.ENUMERATION_ANY(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.NO_CACHE()}),
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.ENUMERATION_ANY(), NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.NO_CACHE()),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant Type STATESELECT_TYPE_TYPE = Type.ENUMERATION(
Absyn.IDENT("StateSelect"), {"never", "avoid", "default", "prefer", "always"});

constant InstNode STATESELECT_TYPE = InstNode.CLASS_NODE("StateSelect",
Elements.STATESELECT,
listArray({Class.PARTIAL_BUILTIN(STATESELECT_TYPE_TYPE, ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
listArray({NFInstNode.CachedData.NO_CACHE()}),
Pointer.createImmutable(Class.PARTIAL_BUILTIN(STATESELECT_TYPE_TYPE, NFClassTree.EMPTY, Modifier.NOMOD())),
Pointer.createImmutable(NFInstNode.CachedData.NO_CACHE()),
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());

constant Binding STATESELECT_NEVER_BINDING =
Expand Down Expand Up @@ -214,62 +190,62 @@ constant Binding STATESELECT_ALWAYS_BINDING =

constant InstNode STATESELECT_NEVER =
InstNode.COMPONENT_NODE("never",
Elements.STATESELECT_NEVER,
listArray({Component.TYPED_COMPONENT(
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE_TYPE,
STATESELECT_NEVER_BINDING,
NFComponent.CONST_ATTR)}),
NFComponent.CONST_ATTR,
Absyn.dummyInfo)),
STATESELECT_TYPE);

constant InstNode STATESELECT_AVOID =
InstNode.COMPONENT_NODE("avoid",
Elements.STATESELECT_AVOID,
listArray({Component.TYPED_COMPONENT(
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE_TYPE,
STATESELECT_AVOID_BINDING,
NFComponent.CONST_ATTR)}),
NFComponent.CONST_ATTR,
Absyn.dummyInfo)),
STATESELECT_TYPE);

constant InstNode STATESELECT_DEFAULT =
InstNode.COMPONENT_NODE("default",
Elements.STATESELECT_DEFAULT,
listArray({Component.TYPED_COMPONENT(
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE_TYPE,
STATESELECT_DEFAULT_BINDING,
NFComponent.CONST_ATTR)}),
NFComponent.CONST_ATTR,
Absyn.dummyInfo)),
STATESELECT_TYPE);

constant InstNode STATESELECT_PREFER =
InstNode.COMPONENT_NODE("prefer",
Elements.STATESELECT_PREFER,
listArray({Component.TYPED_COMPONENT(
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE_TYPE,
STATESELECT_PREFER_BINDING,
NFComponent.CONST_ATTR)}),
NFComponent.CONST_ATTR,
Absyn.dummyInfo)),
STATESELECT_TYPE);

constant InstNode STATESELECT_ALWAYS =
InstNode.COMPONENT_NODE("always",
Elements.STATESELECT_ALWAYS,
listArray({Component.TYPED_COMPONENT(
InstNode.COMPONENT_NODE("always",
Pointer.createImmutable(Component.TYPED_COMPONENT(
InstNode.EMPTY_NODE(),
STATESELECT_TYPE_TYPE,
STATESELECT_ALWAYS_BINDING,
NFComponent.CONST_ATTR)}),
NFComponent.CONST_ATTR,
Absyn.dummyInfo)),
STATESELECT_TYPE);

constant InstNode TIME =
InstNode.COMPONENT_NODE("time",
Elements.TIME,
listArray({Component.TYPED_COMPONENT(
Pointer.createImmutable(Component.TYPED_COMPONENT(
REAL_TYPE,
Type.REAL(),
Binding.UNBOUND(),
NFComponent.INPUT_ATTR)}),
NFComponent.INPUT_ATTR,
Absyn.dummyInfo)),
InstNode.EMPTY_NODE());

annotation(__OpenModelica_Interface="frontend");
Expand Down

0 comments on commit c7d04e1

Please sign in to comment.