Package org.ek9lang.compiler.symbols
Class SymbolTable
java.lang.Object
org.ek9lang.compiler.symbols.SymbolTable
- All Implemented Interfaces:
Serializable
,IScope
- Direct Known Subclasses:
LocalScope
,ModuleScope
We need to support simple things like classes which are unique per symbol table
Or the fully qualified class names like 'com.some.A and com.other.A' so they won't collide.
But we don't want to define constants/variables like 'int A and float A' this is a duplicate
We do want method overloading like int A() and int A(String some param)
But not int A() and float A() as that is not good.
So for the most part this is straight forward, but this issue is operators and type matching. i.e support for 1. int A() 2. int A(String v1) 3. int A(String v1, int someItem) 4. int A(int item, String other) 5. int A(List of String list1) 6. int A(List of Integer list2) 7. float A(List of Integer list3, String other) 8. int A(List of Double list4, String other) 9. int A(SomeClass sc) 10. int A(ClassThatExtendsSomeClass supersc)When we define these we want them all to be defined and available in the appropriate scope. The issue is doing the resolve! We can't just say hey I'm trying to resolve 'A' that's just not enough We need to know:
1. Are we looking for a class(type), function/method or variable/constant in this context. 2. What is it's name - in this case 'A' 3. What type (or return type) are we expecting - but here we should accept a super class match with some weight match value 4. What is the order and type of parameters - again we need to try and match with some weight using super class matches.So what sort of algorithm can we use for this?
The Symbol has a type already when we define it - we know if it is an AggregateSymbol, MethodSymbol etc. We also know its name! We know the Symbol we will use for it's return type or what it is i.e the Symbol of Integer as the return type or what it is. For methods (which are Scoped Symbols) we also have the parameters (in order). So while parameters can be used when making the call this is just sugar - the order still has to match. Well we could have separate internal tables for methods/functions, classes/types and variables. So we can quickly and simply resolve obvious ones like variables and types. Then use more expensive operations for methods. Now for methods we can store in a hash map of method names - so in a simple case with just one method of name A we're done! But in that hashmap we store and List of all methods of that name - now we have the costly activity of going through each and getting the weight of each to find a match. in local scopes which ever is the best match we return - but clearly it is possible there is no match then we resort to moving back up the scope tree (as we do now).
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.ek9lang.compiler.symbols.IScope
IScope.ScopeType
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected SymbolTable
cloneIntoSymbolTable
(SymbolTable rtn, IScope withParentAsAppropriate) void
Define a Symbol in this scope.boolean
getAllSymbolsMatchingName
(String symbolName) Return a list of all the symbols that match the name.Useful for printing out errors and information.Get all the symbols in this table.Find symbols in a specific category.int
hashCode()
boolean
Typically used with functions.boolean
isScopeAMatchForEnclosingScope
(IScope toCheck) boolean
Typically in a scoped block we can encounter situations (like exceptions) that cause the block to end (terminate) early.resolve
(SymbolSearch search) Search and resolve from a symbol search.resolveInThisScopeOnly
(SymbolSearch search) Resolve a symbol in this symbol table only.resolveMatchingMethods
(MethodSymbolSearch search, MethodSymbolSearchResult result) Add all matching methods for a method search.protected MethodSymbolSearchResult
There are no supers so this will not add any methods.Add all matching methods for a method search but only in this scope.resolveMember
(SymbolSearch search) Just resolve on this or supers/traits - but not anything outside of the class hierarchy.This class is the root and so there is no enclosing scope.protected boolean
searchIsNotInThisScope
(SymbolSearch search) If search is unqualified (i.e.void
setEncounteredExceptionToken
(IToken encounteredExceptionToken) void
setMarkedPure
(boolean markedPure) toString()
-
Constructor Details
-
SymbolTable
-
SymbolTable
public SymbolTable()
-
-
Method Details
-
getEnclosingScope
- Specified by:
getEnclosingScope
in interfaceIScope
-
getFriendlyScopeName
Description copied from interface:IScope
Useful for printing out errors and information. The scope name might be a complex generated name used internally a bit like symbol names are. So some items are both scopes and symbols - so ideally we'd want to use a friendly name where possible.- Specified by:
getFriendlyScopeName
in interfaceIScope
- Returns:
- The friendly name to be used for the developer.
-
getScopeName
- Specified by:
getScopeName
in interfaceIScope
-
getScopeType
- Specified by:
getScopeType
in interfaceIScope
-
isTerminatedNormally
public boolean isTerminatedNormally()Description copied from interface:IScope
Typically in a scoped block we can encounter situations (like exceptions) that cause the block to end (terminate) early.- Specified by:
isTerminatedNormally
in interfaceIScope
-
getEncounteredExceptionToken
- Specified by:
getEncounteredExceptionToken
in interfaceIScope
-
setEncounteredExceptionToken
- Specified by:
setEncounteredExceptionToken
in interfaceIScope
-
clone
-
cloneIntoSymbolTable
-
isMarkedPure
public boolean isMarkedPure()Description copied from interface:IScope
Typically used with functions. Something that is pure cannot have 'side effects'. To enforce this a bit of logic can have no references to other variables, methods and functions else how can no side effects be guaranteed. Hence, a function that just tests a value or calculates a result is deemed pure. Anything else is questionable.- Specified by:
isMarkedPure
in interfaceIScope
- Returns:
- true if marked as pure, false otherwise.
-
setMarkedPure
public void setMarkedPure(boolean markedPure) -
define
Description copied from interface:IScope
Define a Symbol in this scope. -
equals
-
hashCode
public int hashCode() -
getSymbolsForThisScopeOfCategory
Find symbols in a specific category. -
getSymbolsForThisScope
Get all the symbols in this table.- Specified by:
getSymbolsForThisScope
in interfaceIScope
-
getAllSymbolsMatchingName
Description copied from interface:IScope
Return a list of all the symbols that match the name. So for class and traits this must include supers and traits.- Specified by:
getAllSymbolsMatchingName
in interfaceIScope
-
resolve
Search and resolve from a symbol search. -
resolveMatchingMethods
public MethodSymbolSearchResult resolveMatchingMethods(MethodSymbolSearch search, MethodSymbolSearchResult result) Add all matching methods for a method search.- Specified by:
resolveMatchingMethods
in interfaceIScope
-
resolveMatchingMethodsInThisScopeOnly
public MethodSymbolSearchResult resolveMatchingMethodsInThisScopeOnly(MethodSymbolSearch search, MethodSymbolSearchResult result) Add all matching methods for a method search but only in this scope.- Specified by:
resolveMatchingMethodsInThisScopeOnly
in interfaceIScope
-
resolveMatchingMethodsInEnclosingScope
protected MethodSymbolSearchResult resolveMatchingMethodsInEnclosingScope(MethodSymbolSearch search, MethodSymbolSearchResult result) There are no supers so this will not add any methods. -
resolveMember
Description copied from interface:IScope
Just resolve on this or supers/traits - but not anything outside of the class hierarchy.- Specified by:
resolveMember
in interfaceIScope
-
searchIsNotInThisScope
If search is unqualified (i.e. just a name then yes we look in this scope). If the search is a fully qualified name then the scope name in the search has to match this scope. -
resolveInThisScopeOnly
Resolve a symbol in this symbol table only.- Specified by:
resolveInThisScopeOnly
in interfaceIScope
-
resolveWithEnclosingScope
This class is the root and so there is no enclosing scope. subclasses will override to provide the scope that encloses them -
isScopeAMatchForEnclosingScope
- Specified by:
isScopeAMatchForEnclosingScope
in interfaceIScope
-
findNearestNonBlockScopeInEnclosingScopes
- Specified by:
findNearestNonBlockScopeInEnclosingScopes
in interfaceIScope
-
findNearestDynamicBlockScopeInEnclosingScopes
- Specified by:
findNearestDynamicBlockScopeInEnclosingScopes
in interfaceIScope
-
toString
-