Skip to content

Commit

Permalink
- Improved cref prefixing in SCodeInst, now uses less magic.
Browse files Browse the repository at this point in the history
- Changed InstTypes.Prefix to be a proper uniontype instead of a list, for no
  apparent reason.
- Some small class extends improvements.



git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@13605 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Oct 24, 2012
1 parent 9bffa19 commit 59276d0
Show file tree
Hide file tree
Showing 11 changed files with 519 additions and 462 deletions.
26 changes: 26 additions & 0 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -1609,6 +1609,32 @@ algorithm
end match;
end crefPrefixStringList;

public function prefixWithPath
input ComponentRef inCref;
input Absyn.Path inPath;
output ComponentRef outCref;
algorithm
outCref := match(inCref, inPath)
local
Absyn.Ident name;
Absyn.Path rest_path;
ComponentRef cref;

case (_, Absyn.IDENT(name = name))
then DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, inCref);

case (_, Absyn.QUALIFIED(name = name, path = rest_path))
equation
cref = prefixWithPath(inCref, rest_path);
then
DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, cref);

case (_, Absyn.FULLYQUALIFIED(path = rest_path))
then prefixWithPath(inCref, rest_path);

end match;
end prefixWithPath;

public function prependStringCref
"function: prependStringCref
Prepend a string to a component reference.
Expand Down
127 changes: 125 additions & 2 deletions Compiler/FrontEnd/InstSymbolTable.mo
Expand Up @@ -173,6 +173,7 @@ algorithm
bucket_size = Util.nextPrime(intDiv((comp_size * 4), 3)) + 1;
symtab = createSized(bucket_size);
(cls, symtab) = addClass(inClass, symtab);
symtab = addAliases(inClass, symtab);
// Add the special variable time to the symboltable.
(symtab, _) = addOptionalComponent(Absyn.IDENT("time"),
BUILTIN_TIME_COMP, NONE(), symtab);
Expand Down Expand Up @@ -404,7 +405,7 @@ algorithm
Boolean added;
HashTable scope;

// PACKAGE isn't really a component, so we don't add it. But it's class
// PACKAGE isn't really a component, so we don't add it. But its class
// should be added, so return true anyway.
case (InstTypes.PACKAGE(name = _), st)
then (st, true);
Expand Down Expand Up @@ -497,6 +498,108 @@ algorithm
end matchcontinue;
end addIterator;

protected function addAliases
"This function adds aliases for all top-level components in a class. For each
component we add an alias from the fully qualified name to the component's
actual name. This is done because components in the top-level class doesn't
get a prefix, so their names are simple identifiers. But if any other class
tries to access something in the top-level class it will do so with the
fully qualified name. E.g. if we instantiate this package:

package P
model M
Real x[n]; // n will be instantiated as P.n.
end M;

constant Integer n = 3; // n will be instantiated as n.
constant M m;
end P;

A solution would be to fully qualify all top-level components, but that makes
a lot of things such as inner/outer handling a lot more complicated. Another
solution would be to simply add the top-level components twice with the two
different names they are referred by, but that will cause unnecessary
instantiation and possible introduce subtle bugs in the typing. Instead
we add aliases to the symboltable, so that whenever a top-level component is
referred to by its fully qualified name we find an alias that points to its
non-qualified name, and look up that component instead.
TODO: Check what kind of restrictions actually apply in this case. We might
only need to introduce aliases if the class is a package, but the
specification is a bit vague on what can be accessed from where."
input Class inClass;
input SymbolTable inSymbolTable;
output SymbolTable outSymbolTable;
algorithm
outSymbolTable := matchcontinue(inClass, inSymbolTable)
local
Absyn.Path class_path;
list<Element> el;
SymbolTable st;

case (InstTypes.COMPLEX_CLASS(name = class_path, components = el), st)
equation
st = List.fold1(el, addAlias, class_path, st);
then
st;

case (InstTypes.BASIC_TYPE(name = _), _) then inSymbolTable;

else
equation
true = Flags.isSet(Flags.FAILTRACE);
Debug.traceln("- InstSymbolTable.addAlises failed.\n");
then
fail();

end matchcontinue;
end addAliases;

protected function addAlias
input Element inElement;
input Absyn.Path inClassPath;
input SymbolTable inSymbolTable;
output SymbolTable outSymbolTable;
algorithm
outSymbolTable := match(inElement, inClassPath, inSymbolTable)
local
Component comp;
Absyn.Path comp_name, qualified_name;
SymbolTable st;
list<Element> el;

case (InstTypes.ELEMENT(component = comp), _, st)
then addAlias2(comp, inClassPath, st);

case (InstTypes.CONDITIONAL_ELEMENT(component = comp), _, st)
then addAlias2(comp, inClassPath, st);

case (InstTypes.EXTENDED_ELEMENTS(cls = InstTypes.COMPLEX_CLASS(components = el)), _, st)
equation
st = List.fold1(el, addAlias, inClassPath, st);
then
st;

else inSymbolTable;

end match;
end addAlias;

protected function addAlias2
input Component inComponent;
input Absyn.Path inClassPath;
input SymbolTable inSymbolTable;
output SymbolTable outSymbolTable;
protected
Absyn.Path comp_name, qualified_name;
Component comp;
algorithm
comp_name := InstUtil.getComponentName(inComponent);
qualified_name := Absyn.joinPaths(inClassPath, comp_name);
comp := InstTypes.COMPONENT_ALIAS(comp_name);
outSymbolTable := addNoUpdCheck(qualified_name, comp, inSymbolTable);
end addAlias2;

public function addFunctionScope
input SymbolTable inSymbolTable;
output SymbolTable outSymbolTable;
Expand Down Expand Up @@ -625,11 +728,31 @@ public function lookupCref
output Component outComponent;
protected
Absyn.Path path;
Component comp;
algorithm
path := ComponentReference.crefToPathIgnoreSubs(inCref);
outComponent := get(path, inSymbolTable);
comp := get(path, inSymbolTable);
outComponent := resolveAlias(comp, inSymbolTable);
end lookupCref;

protected function resolveAlias
"Resolves a component alias in the symboltable. Returns the aliased component
if the given component is an alias, otherwise just the given component."
input Component inComponent;
input SymbolTable inSymbolTable;
output Component outComponent;
algorithm
outComponent := match(inComponent, inSymbolTable)
local
Absyn.Path name;

case (InstTypes.COMPONENT_ALIAS(componentName = name), _)
then get(name, inSymbolTable);

else inComponent;
end match;
end resolveAlias;

public function lookupCrefResolveOuter
"Looks up a component reference in the symboltable and returns the referenced
component. It also resolves outer references, so that in the case of an outer
Expand Down
20 changes: 18 additions & 2 deletions Compiler/FrontEnd/InstTypes.mo
Expand Up @@ -45,8 +45,20 @@ public import DAE;
public import SCode;
public import SCodeEnv;

public type Prefix = list<tuple<String, DAE.Dimensions>>;
public constant Prefix emptyPrefix = {};
public uniontype Prefix
record EMPTY_PREFIX
Option<Absyn.Path> classPath "The path of the class the prefix originates from.";
end EMPTY_PREFIX;

record PREFIX
String name;
DAE.Dimensions dims;
Prefix restPrefix;
end PREFIX;
end Prefix;

public constant Prefix emptyPrefix = EMPTY_PREFIX(NONE());
public constant Prefix functionPrefix = EMPTY_PREFIX(NONE());

public uniontype Element
record ELEMENT
Expand Down Expand Up @@ -179,6 +191,10 @@ public uniontype Component
Absyn.Path name;
Option<Component> parent; //NO_COMPONENT?
end PACKAGE;

record COMPONENT_ALIAS
Absyn.Path componentName;
end COMPONENT_ALIAS;
end Component;

public uniontype Condition
Expand Down
45 changes: 31 additions & 14 deletions Compiler/FrontEnd/InstUtil.mo
Expand Up @@ -341,6 +341,8 @@ algorithm
list<list<Statement>> al, ial;
Absyn.Path name;

case ({}, _) then inClass;

case (_, InstTypes.COMPLEX_CLASS(name, el, eq, ieq, al, ial))
equation
el = listAppend(inElements, el);
Expand Down Expand Up @@ -1167,7 +1169,7 @@ public function addPrefix
input Prefix inPrefix;
output Prefix outPrefix;
algorithm
outPrefix := (inName, inDimensions) :: inPrefix;
outPrefix := InstTypes.PREFIX(inName, inDimensions, inPrefix);
end addPrefix;

public function prefixCref
Expand All @@ -1181,9 +1183,13 @@ algorithm
Prefix rest_prefix;
DAE.ComponentRef cref;

case (_, {}) then inCref;
case (_, {(name, _)}) then DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
case (_, (name, _) :: rest_prefix)
case (_, InstTypes.EMPTY_PREFIX(classPath = _)) then inCref;

case (_, InstTypes.PREFIX(name = name,
restPrefix = InstTypes.EMPTY_PREFIX(classPath = _)))
then DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, inCref);

case (_, InstTypes.PREFIX(name = name, restPrefix = rest_prefix))
equation
cref = DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
then
Expand All @@ -1202,8 +1208,12 @@ algorithm
Prefix rest_prefix;
DAE.ComponentRef cref;

case ({(name, _)}) then DAE.CREF_IDENT(name, DAE.T_UNKNOWN_DEFAULT, {});
case ((name, _) :: rest_prefix)
case (InstTypes.PREFIX(name = name,
restPrefix = InstTypes.EMPTY_PREFIX(classPath = _)))
then
DAE.CREF_IDENT(name, DAE.T_UNKNOWN_DEFAULT, {});

case (InstTypes.PREFIX(name = name, restPrefix = rest_prefix))
equation
cref = DAE.CREF_IDENT(name, DAE.T_UNKNOWN_DEFAULT, {});
then
Expand All @@ -1223,9 +1233,13 @@ algorithm
Prefix rest_prefix;
Absyn.Path path;

case (_, {}) then inPath;
case (_, {(name, _)}) then Absyn.QUALIFIED(name, inPath);
case (_, (name, _) :: rest_prefix)
case (_, InstTypes.EMPTY_PREFIX(classPath = _)) then inPath;
case (_, InstTypes.PREFIX(name = name,
restPrefix = InstTypes.EMPTY_PREFIX(classPath = _)))
then
Absyn.QUALIFIED(name, inPath);

case (_, InstTypes.PREFIX(name = name, restPrefix = rest_prefix))
equation
path = Absyn.QUALIFIED(name, inPath);
then
Expand All @@ -1244,8 +1258,11 @@ algorithm
Prefix rest_prefix;
Absyn.Path path;

case ({(name, _)}) then Absyn.IDENT(name);
case ((name, _) :: rest_prefix)
case InstTypes.PREFIX(name = name,
restPrefix = InstTypes.EMPTY_PREFIX(classPath = _))
then Absyn.IDENT(name);

case InstTypes.PREFIX(name = name, restPrefix = rest_prefix)
equation
path = Absyn.IDENT(name);
then
Expand All @@ -1258,7 +1275,7 @@ public function pathPrefix
input Absyn.Path inPath;
output Prefix outPrefix;
algorithm
outPrefix := pathPrefix2(inPath, {});
outPrefix := pathPrefix2(inPath, InstTypes.emptyPrefix);
end pathPrefix;

protected function pathPrefix2
Expand All @@ -1272,10 +1289,10 @@ algorithm
String name;

case (Absyn.QUALIFIED(name, path), _)
then pathPrefix2(path, (name, {}) :: inPrefix);
then pathPrefix2(path, InstTypes.PREFIX(name, {}, inPrefix));

case (Absyn.IDENT(name), _)
then (name, {}) :: inPrefix;
then InstTypes.PREFIX(name, {}, inPrefix);

case (Absyn.FULLYQUALIFIED(path), _)
then pathPrefix2(path, inPrefix);
Expand Down
6 changes: 4 additions & 2 deletions Compiler/FrontEnd/SCodeDependency.mo
Expand Up @@ -1956,7 +1956,8 @@ algorithm
// Create a new class environment that preserves the imports and extends.
(empty_class_env, cls_and_vars) :=
SCodeEnv.removeClsAndVarsFromFrame(inClassEnv);
// Collect all constants in the top class, makes it easier to write test cases.
// Collect all constants in the top class, even if they're not used.
// This makes it easier to write test cases.
collect_constants := Absyn.pathEqual(inClassName, inAccumPath);
//collect_constants := false;
(outUsedElements, outNewEnv, outGlobalConstants) :=
Expand Down Expand Up @@ -2059,8 +2060,9 @@ algorithm
true = inCollectConstants or SCodeEnv.isItemUsed(item);
env = SCodeEnv.extendEnvWithItem(item, inAccumEnv, name);
const_path = Absyn.suffixPath(inAccumPath, name);
consts = List.consOnTrue(not inCollectConstants, const_path, inAccumConsts);
then
(inElement, env, const_path :: inAccumConsts);
(inElement, env, consts);

// Class components are always collected, regardless of whether they are
// used or not.
Expand Down

0 comments on commit 59276d0

Please sign in to comment.