package LBJ2.IR;
import LBJ2.Pass;
/**
* The root node of LBJ2's AST. The parser will create only one of these and
* return it as the ultimate result of parsing. It currently contains a
* single (optional) <code>PackageDeclaration</code>, a <code>List</code> of
* <code>ImportDeclaration</code>s (also optional), the global
* <code>SymbolTable</code>, and a <code>List</code> containing
* <code>ClassifierAssignment</code>s, <code>ConstraintDeclaration</code>s,
* and <code>InferenceDeclaration</code>s.
*
* <p>
* The <code>PackageDeclaration</code> specifies what package will contain
* the generated classes. The <code>ImportDeclaration</code>s work similarly
* to <code>import</code> declarations in regular Java code: they allow the
* user to name classes in other packages without using their full package
* names. The list of <code>Declaration</code>s comprises the LBJ2 program.
* The global <code>SymbolTable</code> simply associates variable names with
* their type information in the program.
*
* @author Nick Rizzolo
**/
public class AST extends ASTNode
{
/** The <code>symbolTable</code> variable mirrors this variable. */
public static final SymbolTable globalSymbolTable = new SymbolTable();
/**
* (ø) An optional declaration of the package that generated classes
* should be a part of.
**/
public PackageDeclaration packageDeclaration;
/**
* (¬ø) The list of import statements at the top of the source
* file.
**/
public ImportList imports;
/**
* (¬ø) The list of classifier, constraint, and inference
* declarations representing the LBJ2 program.
**/
public DeclarationList declarations;
/**
* Initializes just the statement list. Line and byte offset information
* are taken from the statement list.
*
* @param d The declarations comprising the program.
**/
public AST(DeclarationList d) {
this(null, new ImportList(), d, d.line, d.byteOffset);
}
/**
* Initializes both lists. Line and byte offset information are taken from
* the <code>import</code> list.
*
* @param i The <code>import</code> declarations.
* @param d The declarations comprising the program.
**/
public AST(ImportList i, DeclarationList d) {
this(null, i, d, i.line, i.byteOffset);
}
/**
* Initializes package declaration and statement list. Line and byte
* offset information are taken from the <code>package</code> declaration.
*
* @param p The <code>package</code> declaration.
* @param d The declarations comprising the program.
**/
public AST(PackageDeclaration p, DeclarationList d) {
this(p, new ImportList(), d, p.line, p.byteOffset);
}
/**
* Initializes all member variables. Line and byte offset information are
* taken from the <code>package</code> declaration.
*
* @param p The <code>package</code> declaration.
* @param i The <code>import</code> declarations.
* @param d The declarations comprising the program.
**/
public AST(PackageDeclaration p, ImportList i, DeclarationList d) {
this(p, i, d, p.line, p.byteOffset);
}
/**
* Full constructor.
*
* @param p The <code>package</code> declaration.
* @param i The <code>import</code> declarations.
* @param d The declarations comprising the program.
* @param line The line on which the source code represented by this
* node is found.
* @param byteOffset The byte offset from the beginning of the source file
* at which the source code represented by this node is
* found.
**/
public AST(PackageDeclaration p, ImportList i, DeclarationList d, int line,
int byteOffset) {
super(line, byteOffset);
packageDeclaration = p;
imports = i;
declarations = d;
symbolTable = globalSymbolTable;
}
/**
* Returns an iterator used to successively access the children of this
* node.
*
* @return An iterator used to successively access the children of this
* node.
**/
public ASTNodeIterator iterator() {
ASTNodeIterator I =
new ASTNodeIterator(packageDeclaration == null ? 2 : 3);
if (packageDeclaration != null) I.children[0] = packageDeclaration;
I.children[I.children.length - 2] = imports;
I.children[I.children.length - 1] = declarations;
return I;
}
/**
* Creates a new object with the same primitive data, and recursively
* creates new member data objects as well.
*
* @return The clone node.
**/
public Object clone() {
PackageDeclaration p = null;
if (packageDeclaration != null)
p = (PackageDeclaration) packageDeclaration.clone();
return new AST(p, (ImportList) imports.clone(),
(DeclarationList) declarations.clone(), -1, -1);
}
/**
* Ensures that the correct <code>run()</code> method is called for this
* type of node.
*
* @param pass The pass whose <code>run()</code> method should be called.
**/
public void runPass(Pass pass) { pass.run(this); }
/**
* Writes a string representation of this <code>ASTNode</code> to the
* specified buffer. The representation written is parsable by the LBJ2
* compiler, but not very readable.
*
* @param buffer The buffer to write to.
**/
public void write(StringBuffer buffer) {
if (packageDeclaration != null) {
packageDeclaration.write(buffer);
buffer.append(" ");
}
imports.write(buffer);
buffer.append(" ");
declarations.write(buffer);
}
}