Skip to content

Commit

Permalink
New instantiation improvements:
Browse files Browse the repository at this point in the history
- Put modifiers in the environment instead of a separate table.
- Moved NFEnv AVL tree implementation to it's own package.
- Propagate basic type properties correctly.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17810 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Oct 22, 2013
1 parent e3ea789 commit c4fc2ac
Show file tree
Hide file tree
Showing 8 changed files with 1,134 additions and 1,073 deletions.
938 changes: 142 additions & 796 deletions Compiler/FrontEnd/NFEnv.mo

Large diffs are not rendered by default.

700 changes: 700 additions & 0 deletions Compiler/FrontEnd/NFEnvAvlTree.mo

Large diffs are not rendered by default.

223 changes: 117 additions & 106 deletions Compiler/FrontEnd/NFInst.mo

Large diffs are not rendered by default.

83 changes: 79 additions & 4 deletions Compiler/FrontEnd/NFInstTypes.mo
Expand Up @@ -43,7 +43,8 @@ public import Absyn;
public import NFConnect2;
public import DAE;
public import SCode;
public import NFEnv;

//public import NFEnv;

public uniontype Prefix
record EMPTY_PREFIX
Expand Down Expand Up @@ -134,7 +135,7 @@ public uniontype Binding

record RAW_BINDING
Absyn.Exp bindingExp;
NFEnv.Env env;
Env env;
Prefix prefix;
Integer propagatedDims "See NFSCodeMod.propagateMod.";
Absyn.Info info;
Expand Down Expand Up @@ -181,7 +182,7 @@ public uniontype Component
SCode.Element element;
Modifier modifier;
Prefixes prefixes;
NFEnv.Env env;
Env env;
Prefix prefix;
Absyn.Info info;
end CONDITIONAL_COMPONENT;
Expand Down Expand Up @@ -235,7 +236,7 @@ public uniontype Modifier
SCode.Final finalPrefix;
SCode.Each eachPrefix;
SCode.Element element;
NFEnv.Env env;
Env env;
Modifier mod;
end REDECLARE;

Expand Down Expand Up @@ -434,4 +435,78 @@ public uniontype FunctionSlot
end SLOT;
end FunctionSlot;

public uniontype EntryOrigin
record LOCAL_ORIGIN "An entry declared in the local scope." end LOCAL_ORIGIN;
record BUILTIN_ORIGIN "An entry declared in the builtin scope." end BUILTIN_ORIGIN;

record INHERITED_ORIGIN
"An entry that has been inherited through an extends clause."
Absyn.Path baseClass "The path of the baseclass the entry was inherited from.";
Absyn.Info info "The info of the extends clause.";
list<EntryOrigin> origin "The origins of the element in the baseclass.";
Env originEnv "The environment the entry was inherited from.";
end INHERITED_ORIGIN;

record REDECLARED_ORIGIN
"An entry that has replaced another entry through redeclare."
Entry replacedEntry "The replaced entry.";
Env originEnv "The environment the replacement came from.";
end REDECLARED_ORIGIN;

record IMPORTED_ORIGIN
"An entry that has been imported with an import statement."
Absyn.Import imp;
Absyn.Info info;
Env originEnv "The environment the entry was imported from.";
end IMPORTED_ORIGIN;
end EntryOrigin;

public uniontype Entry
record ENTRY
String name;
SCode.Element element;
Modifier mod;
list<EntryOrigin> origins;
end ENTRY;
end Entry;

public uniontype ScopeType
record BUILTIN_SCOPE end BUILTIN_SCOPE;
record TOP_SCOPE end TOP_SCOPE;
record NORMAL_SCOPE end NORMAL_SCOPE;
record ENCAPSULATED_SCOPE end ENCAPSULATED_SCOPE;
record IMPLICIT_SCOPE "This scope contains one or more iterators; they are made unique by the following index (plus their name)" Integer iterIndex; end IMPLICIT_SCOPE;
end ScopeType;

public uniontype Frame
record FRAME
Option<String> name;
ScopeType scopeType;
AvlTree entries;
end FRAME;
end Frame;

public type Env = list<Frame>;

public type AvlKey = String;
public type AvlValue = Entry;

public uniontype AvlTree
"The binary tree data structure"
record AVLTREENODE
Option<AvlTreeValue> value "Value";
Integer height "height of tree, used for balancing";
Option<AvlTree> left "left subtree";
Option<AvlTree> right "right subtree";
end AVLTREENODE;
end AvlTree;

public uniontype AvlTreeValue
"Each node in the binary tree can have a value associated with it."
record AVLTREEVALUE
AvlKey key "Key" ;
AvlValue value "Value" ;
end AVLTREEVALUE;
end AvlTreeValue;

end NFInstTypes;
114 changes: 64 additions & 50 deletions Compiler/FrontEnd/NFLookup.mo
Expand Up @@ -54,16 +54,17 @@ public type Env = NFEnv.Env;
public type Entry = NFEnv.Entry;
public type EntryOrigin = NFEnv.EntryOrigin;
public type Modifier = NFInstTypes.Modifier;
public type ModTable = NFMod.ModTable;

protected constant Entry REAL_TYPE_ENTRY = NFEnv.ENTRY(
"Real", NFBuiltin.BUILTIN_REAL, {NFEnv.BUILTIN_ORIGIN()});
protected constant Entry INT_TYPE_ENTRY = NFEnv.ENTRY(
"Integer", NFBuiltin.BUILTIN_INTEGER, {NFEnv.BUILTIN_ORIGIN()});
protected constant Entry BOOL_TYPE_ENTRY = NFEnv.ENTRY(
"Boolean", NFBuiltin.BUILTIN_BOOLEAN, {NFEnv.BUILTIN_ORIGIN()});
protected constant Entry STRING_TYPE_ENTRY = NFEnv.ENTRY(
"String", NFBuiltin.BUILTIN_STRING, {NFEnv.BUILTIN_ORIGIN()});
protected constant Modifier NOMOD = NFInstTypes.NOMOD();

protected constant Entry REAL_TYPE_ENTRY = NFInstTypes.ENTRY(
"Real", NFBuiltin.BUILTIN_REAL, NOMOD, {NFInstTypes.BUILTIN_ORIGIN()});
protected constant Entry INT_TYPE_ENTRY = NFInstTypes.ENTRY(
"Integer", NFBuiltin.BUILTIN_INTEGER, NOMOD, {NFInstTypes.BUILTIN_ORIGIN()});
protected constant Entry BOOL_TYPE_ENTRY = NFInstTypes.ENTRY(
"Boolean", NFBuiltin.BUILTIN_BOOLEAN, NOMOD, {NFInstTypes.BUILTIN_ORIGIN()});
protected constant Entry STRING_TYPE_ENTRY = NFInstTypes.ENTRY(
"String", NFBuiltin.BUILTIN_STRING, NOMOD, {NFInstTypes.BUILTIN_ORIGIN()});

protected uniontype LookupState
"LookupState is used by the name lookup to keep track of what state it's in,
Expand Down Expand Up @@ -799,7 +800,7 @@ algorithm

case (_, _, _, _)
equation
env = enterEntryScope(inEntry, NFMod.emptyModTable, inEnv);
env = enterEntryScope(inEntry, NFInstTypes.NOMOD(), inEnv);
(entry, env, state) = lookupNameInPackage(inName, env, inState);
then
(entry, env, state);
Expand Down Expand Up @@ -828,47 +829,62 @@ end isNameGlobal;

public function enterEntryScope
input Entry inEntry;
input ModTable inMods;
input Modifier inModifier;
input Env inEnv;
output Env outEnv;
protected
SCode.Element el;
Modifier mod;
algorithm
el := NFEnv.entryElement(inEntry);
mod := NFEnv.entryModifier(inEntry);
mod := NFMod.mergeMod(inModifier, mod);
outEnv := enterEntryScope_impl(el, mod, inEnv);
end enterEntryScope;

public function enterEntryScope_impl
input SCode.Element inElement;
input Modifier inModifier;
input Env inEnv;
output Env outEnv;
algorithm
outEnv := match(inEntry, inMods, inEnv)
outEnv := match(inElement, inModifier, inEnv)
local
Env env;
SCode.ClassDef cdef;
Absyn.Info info;
Absyn.TypeSpec ty;
Entry entry;

case (NFEnv.ENTRY(element = SCode.CLASS(classDef = cdef, info = info)), _, _)
case (SCode.CLASS(classDef = cdef, info = info), _, _)
equation
env = openClassEntryScope(inEntry, inEnv);
env = populateEnvWithClassDef(cdef, inMods, SCode.PUBLIC(), {}, env,
env = openClassScope(inElement, inEnv);
env = populateEnvWithClassDef(cdef, inModifier, SCode.PUBLIC(), {}, env,
elementSplitterRegular, info, env);
then
env;

case (NFEnv.ENTRY(element = SCode.COMPONENT(typeSpec = ty, info = info)), _, _)
case (SCode.COMPONENT(typeSpec = ty, info = info), _, _)
equation
(entry, env) = lookupTypeSpec(ty, inEnv, info);
env = enterEntryScope(entry, NFMod.emptyModTable, env);
env = enterEntryScope(entry, inModifier, env);
then
env;

end match;
end enterEntryScope;
end enterEntryScope_impl;

protected function openClassEntryScope
input Entry inClass;
protected function openClassScope
input SCode.Element inClass;
input Env inEnv;
output Env outEnv;
protected
String name;
SCode.Encapsulated ep;
algorithm
SCode.CLASS(name = name, encapsulatedPrefix = ep) := NFEnv.entryElement(inClass);
SCode.CLASS(name = name, encapsulatedPrefix = ep) := inClass;
outEnv := NFEnv.openClassScope(name, ep, inEnv);
end openClassEntryScope;
end openClassScope;

protected function elementSplitterRegular
input SCode.Element inElement;
Expand Down Expand Up @@ -910,7 +926,7 @@ end SplitFunc;

protected function populateEnvWithClassDef
input SCode.ClassDef inClassDef;
input ModTable inMods;
input Modifier inModifier;
input SCode.Visibility inVisibility;
input list<EntryOrigin> inOrigins;
input Env inEnv;
Expand All @@ -919,7 +935,7 @@ protected function populateEnvWithClassDef
input Env inAccumEnv;
output Env outAccumEnv;
algorithm
outAccumEnv := match(inClassDef, inMods, inVisibility, inOrigins, inEnv,
outAccumEnv := match(inClassDef, inModifier, inVisibility, inOrigins, inEnv,
inSplitFunc, inInfo, inAccumEnv)
local
list<SCode.Element> elems, cls_vars, exts, imps;
Expand All @@ -930,6 +946,7 @@ algorithm
Absyn.Path path;
SCode.ClassDef cdef;
Absyn.TypeSpec ty;
SCode.Element el;

case (SCode.PARTS(elementLst = elems), _, _, _, _, _, _, env)
equation
Expand All @@ -941,26 +958,27 @@ algorithm
origin = NFEnv.collapseInheritedOrigins(inOrigins);
// Add classes, component and imports first, so that extends can be found.
env = populateEnvWithElements(cls_vars, origin, env);
env = NFRedeclare.applyRedeclares(inMods, env);
//env = NFRedeclare.applyRedeclares(inMods, env);
env = populateEnvWithImports(imps, env, false);
env = populateEnvWithExtends(exts, inOrigins, inMods, env, env);
env = populateEnvWithExtends(exts, inOrigins, env, env);
env = NFMod.addModToEnv(inModifier, env);
then
env;

case (SCode.CLASS_EXTENDS(composition = cdef), _, _, _, _, _, _, _)
then populateEnvWithClassDef(cdef, inMods, inVisibility, inOrigins, inEnv,
inSplitFunc, inInfo, inAccumEnv);
then populateEnvWithClassDef(cdef, inModifier, inVisibility, inOrigins,
inEnv, inSplitFunc, inInfo, inAccumEnv);

case (SCode.DERIVED(typeSpec = ty), _, _, _, _, _, _, _)
equation
(entry, env) = lookupTypeSpec(ty, inEnv, inInfo);
SCode.CLASS(classDef = cdef) = NFEnv.entryElement(entry);
(el as SCode.CLASS(classDef = cdef)) = NFEnv.entryElement(entry);
// TODO: Only create this environment if needed, i.e. if the cdef
// contains extends.
env = openClassEntryScope(entry, env);
env = populateEnvWithClassDef(cdef, NFMod.emptyModTable, inVisibility, inOrigins, env,
env = openClassScope(el, env);
env = populateEnvWithClassDef(cdef, inModifier, inVisibility, inOrigins, env,
elementSplitterExtends, inInfo, inAccumEnv);
env = populateEnvWithClassDef(cdef, NFMod.emptyModTable, inVisibility, inOrigins, env,
env = populateEnvWithClassDef(cdef, inModifier, inVisibility, inOrigins, env,
inSplitFunc, inInfo, inAccumEnv);
then
env;
Expand Down Expand Up @@ -1157,16 +1175,17 @@ algorithm
env;

// An unqualified import, 'import A.B.*'.
case (Absyn.UNQUAL_IMPORT(path = _),
NFEnv.ENTRY(element = SCode.CLASS(classDef = cdef), origins = origins), _, _, _)
case (Absyn.UNQUAL_IMPORT(path = _), _, _, _, _)
equation
env = populateEnvWithClassDef(cdef, NFMod.emptyModTable, SCode.PUBLIC(),
SCode.CLASS(classDef = cdef) = NFEnv.entryElement(inEntry);
origins = NFEnv.entryOrigins(inEntry);
env = populateEnvWithClassDef(cdef, NFInstTypes.NOMOD(), SCode.PUBLIC(),
origins, inEnv, elementSplitterRegular, inInfo, inAccumEnv);
then
env;

// This should not happen, group imports are split into separate imports by
// SCodeUtil.translateImports.
// Group imports are split into separate imports by
// SCodeUtil.translateImports and should not occur here.
case (Absyn.GROUP_IMPORT(prefix = _), _, _, _, _)
equation
Error.addSourceMessage(Error.INTERNAL_ERROR,
Expand All @@ -1180,24 +1199,21 @@ end populateEnvWithImport2;
protected function populateEnvWithExtends
input list<SCode.Element> inExtends;
input list<EntryOrigin> inOrigins;
input ModTable inMods;
input Env inEnv;
input Env inAccumEnv;
output Env outAccumEnv;
algorithm
outAccumEnv := List.fold3(inExtends, populateEnvWithExtend, inOrigins, inMods,
inEnv, inAccumEnv);
outAccumEnv := List.fold2(inExtends, populateEnvWithExtend, inOrigins, inEnv, inAccumEnv);
end populateEnvWithExtends;

protected function populateEnvWithExtend
input SCode.Element inExtends;
input list<EntryOrigin> inOrigins;
input ModTable inMods;
input Env inEnv;
input Env inAccumEnv;
output Env outAccumEnv;
algorithm
outAccumEnv := match(inExtends, inOrigins, inMods, inEnv, inAccumEnv)
outAccumEnv := match(inExtends, inOrigins, inEnv, inAccumEnv)
local
Entry entry;
Env env, accum_env;
Expand All @@ -1209,28 +1225,26 @@ algorithm
SCode.Visibility vis;
SCode.Mod smod;
Modifier mod;
ModTable mods;
SCode.Element el;

case (SCode.EXTENDS(baseClassPath = bc, visibility = vis,
modifications = smod, info = info), _, _, _, _)
modifications = smod, info = info), _, _, _)
equation
// Look up the base class and check that it's a valid base class.
(entry, env) = lookupBaseClassName(bc, inEnv, info);
checkRecursiveExtends(bc, env, inEnv, info);

// Check entry: not var, not replaceable
// Create an environment for the base class if needed.
SCode.CLASS(classDef = cdef) = NFEnv.entryElement(entry);
(el as SCode.CLASS(classDef = cdef)) = NFEnv.entryElement(entry);
mod = NFMod.translateMod(smod, "", 0, NFInstTypes.emptyPrefix, inEnv);
mods = NFMod.addClassModToTable(mod, inMods);

env = openClassEntryScope(entry, env);
env = populateEnvWithClassDef(cdef, mods, SCode.PUBLIC(), {}, env,
env = openClassScope(el, env);
env = populateEnvWithClassDef(cdef, mod, SCode.PUBLIC(), {}, env,
elementSplitterExtends, info, env);
// Populate the accumulated environment with the inherited elements.
origin = NFEnv.makeInheritedOrigin(inExtends, env);
origins = origin :: inOrigins;
accum_env = populateEnvWithClassDef(cdef, mods, vis, origins, env,
accum_env = populateEnvWithClassDef(cdef, mod, vis, origins, env,
elementSplitterInherited, info, inAccumEnv);
then
accum_env;
Expand Down

0 comments on commit c4fc2ac

Please sign in to comment.