Scope.java
package edu.udel.cis.vsl.abc.ast.entity.IF;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Set;
import edu.udel.cis.vsl.abc.ast.IF.AST;
import edu.udel.cis.vsl.abc.token.IF.SyntaxException;
import edu.udel.cis.vsl.abc.token.IF.UnsourcedException;
/**
* <p>
* A lexical (static) scope in a translation unit. The C11 Standard specifies 4
* kinds of scopes: FILE, BLOCK, FUNCTION, and FUNCTION_PROTOTYPE.
* </p>
*
* <p>
* A scope contains declarations of various kinds of entities. An "entity" is
* any conceptual thing which can be named using an identifier. An entity may be
* declared in more than one scope (though the process of "linkage").
* </p>
*
* <p>
* Global declarations are in the FILE scope. A BLOCK scope corresponds to a
* block. The BLOCK scope corresponding to a function body includes the formal
* parameters as well as the outermost local parameters. The only entities with
* FUNCTION scope are (standard) labels---the labels that can be used as a
* target of a "goto" statement. A FUNCTION_PROTOTYPE scope occurs only in a
* function prototype, i.e., a function declaration without body; such a scope
* extends to the end of the declarator for the function prototype.
* </p>
*
* <p>
* The set of all scopes in a translation unit forms a tree. The root of the
* tree is the FILE scope.
* </p>
*
* <p>
* There are four kinds of name spaces in a scope: (1) the label namespace,
* which consists of all the (standard) label names in the scope; (2) the tag
* namespace, which consists of all the tags used in struct, union, and
* enumeration definitions; (3) the "member" namespaces (one namespace for each
* struct or union containing the field names for that struct or union); and (4)
* the namespace for "ordinary identifiers"---those declared in an ordinary (not
* struct or union) declarator, or as an enumeration constant---, this includes
* typedef names, variables, and functions. For example, the same identifier "X"
* could be used to denote a label, the tag of a struct, a member of that
* struct, and a variable, all in the same scope. However, "X" could not denote
* both a variable and a function in the same scope; nor could it denote both a
* struct tag and an enumeration tag in the same scope; but two different
* structs in the same scope can both have a field named "X".
* </p>
*
* <p>
* Ordinary entities include: functions, variables (that are not fields),
* enumeration constants, and typedefs.
* </p>
*
* <p>
* Note that "label" means standard label: the kind that is specified by an
* identifier followed by a colon. Not a "case label" (CASE followed by a
* constant expression then colon, used in switch statements), and not the
* "default" label (also used in switch statements).
* </p>
*
* <p>
* Note: Entities can have no name. It is OK if two distinct entities have no
* name; they are not the same entity. It is as if each is given a new name
* distinct from all other names.
* </p>
*/
public interface Scope {
/**
* The different kinds of scopes: file, block, function, function-prototype,
* and contract.
*/
public enum ScopeKind {
/**
* File scope. This is the root scope.
*/
FILE,
/**
* A block scope.
*/
BLOCK,
/**
* A function scope.
*/
FUNCTION,
/**
* A function prototype scope.
*/
FUNCTION_PROTOTYPE,
/**
* The scope for a CIVL-C contract. The contract scope contains the
* scope of the function signature and body.
*/
CONTRACT
};
// information about this scope in the scope tree...
/**
* Returns the kind of scope this is.
*
* @return the scope kind
*/
ScopeKind getScopeKind();
/**
* Returns the ID number of this scope, unique among the scope of its
* translation unit.
*
* @return the scope ID
*/
int getId();
/**
* Sets the ID number of this scope, which should be unique among the ID
* numbers of the scopes of its translation unit.
*
* @param id
* value to which ID number will be set
*/
void setId(int id);
/**
* Returns the AST to which this scope belongs.
*
* @return the AST to which this scope belongs
*/
AST getAST();
/**
* The parent scope, i.e., the scope directly containing this one. Null if
* this is the root scope.
*
* @return the parent scope
*/
Scope getParentScope();
/**
* The number of children of this scope in the scope tree.
*
* @return the number of children scopes of this scope
*/
int getNumChildrenScopes();
/**
* Returns the child scope of this scope, indexed from 0.
*
* @param index
* integer between 0 and numChildrenScope-1, inclusive
* @return child scope number index
* @exception IllegalArgumentException
* if index is out of bounds
*/
Scope getChildScope(int index);
/**
* Returns an iterator over the children scope of this scope.
*
* @return an iterator over all children scopes
*/
Iterator<Scope> getChildrenScopes();
/**
* Returns the depth of this scope as a node in the scope tree. The FILE
* scope has depth 0. Its immediate children have depth 1. Etc.
*
* @return depth of this scope as node in scope tree
*/
int getScopeDepth();
// Ordinary entities...
/**
* Returns the set of names of functions defined in this scope. This is
* computed BEFORE the complete information on this scope is formed.
*
* @return the set of names of functions defined in this scope.
*/
Set<String> getFunctionNames();
/**
* Adds the name of a function defined in this scope.
*
* @param name
* the name of the function
* @return <code>true</code> iff that name was not already used to define a
* function in this scope
*/
boolean addFunctionName(String name);
/**
* Gets the set of all ordinary entities declared in this scope, represented
* as an iterable object.
*
* @return iterable over all ordinary entities declared in this scope
*/
Iterable<OrdinaryEntity> getOrdinaryEntities();
/**
* Adds an ordinary entity to this scope's collection of entities.
*
* @param entity
* an ordinary entity to be added to this scope
* @return the number of ordinary entities beloning to this scope before the
* new one was added; this number becomes the index of the ordinary
* entity
* @throws UnsourcedException
* if the entity cannot be added to this scope for some reason,
* for example, because there is already an ordinary entity with
* that name in this scope
*/
int add(OrdinaryEntity entity) throws UnsourcedException;
/**
* Gets the ordinary entity (variable/function/enumeration constant/typedef)
* in this scope with the given name, or <code>null</code> if there is not
* one. This does not look in ancestor or descendant scopes.
*
* @param isType
* true iff this is to get an entity of typedef; if false then
* the first entity from the bottom of the scope is returned,
* regardless of whether it is typedef or not
* @param name
* the name of the ordinary entity
* @return the ordinary entity in this scope with that name or
* <code>null</code> if none exists
*/
OrdinaryEntity getOrdinaryEntity(boolean isType, String name);
/**
* Performs search for ordinary entity with given name using lexical
* scoping: if entity is not found in this scope, search the parent scope,
* etc. Returns first occurrence of ordinary entity with this name,
* searching in that order. If not found all the way up the scopes, returns
* <code>null</code>.
*
* @param isType
* true iff this is to get an entity of typedef; if false then
* the first entity from the bottom of the scope is returned,
* regardless of whether it is typedef or not
* @param name
* name of the entity
* @return the first ordinary entity encountered with given name looking up
* the scope tree, or <code>null</code>
*/
OrdinaryEntity getLexicalOrdinaryEntity(boolean isType, String name);
/**
* Returns the number of variables declared in this scope. The set of
* variables is a subset of the set of entities. Variables include global
* variables, local variables declared in any block scope, including formal
* parameters to a function. They do not include members of structures or
* unions (aka "fields"). They do not include enumeration constants.
*
* Note this does not include variables in ancestors or descendants of this
* scope.
*
* @return the number of variables declared in this scope
*/
int getNumVariables();
/**
*
* The variables in this scope are assigned variable ID numbers 0, 1, 2,
* ..., at completion time. This method returns the variable with the given
* ID. Note that the variable ID is not necessarily the same as the entity
* ID.
*
* @return the index-th variable in this scope, indexed from 0
*/
Variable getVariable(int index);
/**
* Returns an iterator over the variables in this scope, in order of
* increasing variable ID.
*
* @return an iterable over the variables in this scope.
*/
Iterable<Variable> getVariables();
/**
* Returns the number of functions in this scope. Note this does not include
* functions in ancestors of this scope. The functions are of course a
* subset of the set of Entities.
*
* @return the number of functions in this scope
*/
int getNumFunctions();
/**
* The functions in this scope are assigned ID numbers 0, 1, 2, ..., at
* completion time. This method returns the function with the given index.
*
* @return the index-th function in this scope, counting from 0
*/
Function getFunction(int index);
/**
* Returns an iterator over the functions defined in this scope, in order of
* increasing function index.
*
* @return iterator over functions in this scope
*/
Iterable<Function> getFunctions();
// Tagged entities (enumerations, structures, and unions)...
/**
* Gets the set of all tagged entities declared in this scope, represented
* as an iterable object.
*
* @return iterable over all tagged entities declared in this scope
*/
Iterable<TaggedEntity> getTaggedEntities();
/**
* Adds a tagged entity (an enumeration, structure, or union) to this scope.
* Tagged entities occupy a separate name space from ordinary entities.
*
* @param entity
* a tagged entity
* @return the number of tagged entities belonging to this scope before the
* new one was added; this number is the index of the newly added
* tagged entity in the tagged entity list
* @throws SyntaxException
* if the entity cannot be added to this scope for some reason,
* for example, because there is already a tagged entity with
* the same name in this scope
*/
int add(TaggedEntity entity) throws SyntaxException;
/**
* <p>
* Gets the tagged entity (struct/union/enumeration) in this scope with the
* given tag, or null if there is not one. This does not look in parent or
* descendant scopes.
* </p>
*
* <p>
* Once you get the tagged entity, you can get its member entities
* (enumeration constants or fields). Those member entities are also part of
* this scope. The enumeration constants share the same name space as
* ordinary identifiers in this scope, but the fields are in their own
* entity-specific namespace.
* </p>
*
* @param tag
* the tag
* @return the tagged entity in this scope with that name or null if none
* exists
*/
TaggedEntity getTaggedEntity(String tag);
/**
* Performs search for struct/union/enumeration entity with given tag using
* lexical scoping: if entity is not found in this scope, search the parent
* scope, etc. Returns first occurrence of entity with this tag, searching
* in that order. If not found in any ancestor, returns <code>null</code>.
*
* @return the first tagged entity encountered with the given tag, lookin up
* the scope tree
*/
TaggedEntity getLexicalTaggedEntity(String tag);
// Labels...
/**
* Adds the given label to the list of labels occurring in this scope.
*
* @param label
* a label
* @return the number of labels belonging to this scope before the new one
* was added; this is the index of the new label in the list of
* labels
* @throws UnsourcedException
* if the label cannot be added for some reasons, for example,
* because there is already a label with the same name
*/
int add(Label label) throws UnsourcedException;
/**
* Does the given label already belong to this scope?
*
* @param label
* a label
* @return <code>true</code> iff the list of labels belonging to this scope
* contains the given label
*/
boolean contains(Label label);
/**
* Gets the label declared in this scope with the given name. Labels only
* exist in a FUNCTION scope. A Label is an entity.
*
* @param name
* the label name
* @return the label in this scope with that name or <code>null</code> if
* none exists
*/
Label getLabel(String name);
/**
* Finds the label with the given name in this or any ancestor scope.
*
* @param name
* label name
* @return label with name or null
*/
Label getLexicalLabel(String name);
/**
* Returns iterator over all (standard) labels declared in this scope.
*
* @return iterator over all standard labels declared in this scope
*/
Iterator<Label> getLabels();
/**
* Returns the number of (standard) labels declared in this scope.
*
* @return number of labels in this scope
*/
int getNumLabels();
/**
* Gets the label with the given label ID.
*
* @param labelId
* the label's id
* @return the label with the given id
* @exception IllegalArgumentException
* if the labelId is less than 0 or greater than or equal to
* the number of labels in this scope
*/
Label getLabel(int labelId);
/**
* Prints complete description of this scope, with each line preceded by the
* string prefix.
*
* @param prefix
* any string
* @param out
* PrintStream to which output is directed
*/
void print(String prefix, PrintStream out);
/**
* Prints complete description of this scope.
*
* @param out
* PrintStream to which output is directed
*/
void print(PrintStream out);
/**
* Determines whether this scope is equal to or a descendant of the given
* scope. This mean either this == that or the parent of this is a
* descendant of that.
*
* @param that
* another scope, not null
* @return true iff this scope is a descendant (or equal to) that scope
*/
boolean isDescendantOf(Scope that);
}