/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
\* */
// $Id$
package meta.scalac.ast;
import java.util.List;
import java.util.ArrayList;
import meta.java.Type;
import meta.scalac.Phase;
/** This class describes all tree nodes. */
public class Tree {
//########################################################################
// Private Fields
private final TreeKind
Any = TreeKind.Any,
Type = TreeKind.Type,
Term = TreeKind.Term,
Dual = TreeKind.Dual,
Test = TreeKind.Test,
None = TreeKind.None;
private final Type
t_int = TreeType.INT,
t_ints = TreeType.Array(t_int),
t_Object = TreeType.Reference(null, "Object"),
t_String = TreeType.Reference(null, "String"),
t_Global = TreeType.Reference("scalac", "Global"),
t_Unit = TreeType.Reference("scalac", "Unit"),
t_TreeGen = TreeType.Reference("scalac.ast", "TreeGen"),
t_AConstant = TreeType.Reference("scalac.atree", "AConstant"),
t_Symbol = TreeType.Reference("scalac.symtab", "Symbol"),
t_Type = TreeType.Reference("scalac.symtab", "Type"),
t_Name = TreeType.Name(Any),
t_TypeName = TreeType.Name(Type),
t_TermName = TreeType.Name(Term),
t_TestName = TreeType.Name(Test),
t_Names = TreeType.Array(t_Name),
t_Tree = getType(0),
t_TypeTree = getType(0, Type),
t_TermTree = getType(0, Term),
t_Trees = getType(1),
t_TypeTrees = getType(1, Type),
t_TermTrees = getType(1, Term);
private final TreeFieldLink
SymFlags = TreeFieldLink.SymFlags,
SymName = TreeFieldLink.SymName;
private final TreeField
tree_symbol = new TreeField(t_Symbol, "symbol");
private final TreeSymbol
NoSym = TreeSymbol.NoSym,
HasSym = TreeSymbol.HasSym(tree_symbol, false),
DefSym = TreeSymbol.HasSym(tree_symbol, true);
private final List list
= new ArrayList();
//########################################################################
// Public Fields
public final TreeNode
n_Empty = node("Empty" , Any , NoSym),
n_DocDef = node("DocDef" , None, NoSym),
n_ClassDef = node("ClassDef" , None, DefSym),
n_PackageDef = node("PackageDef" , None, NoSym),
n_ModuleDef = node("ModuleDef" , None, DefSym),
n_ValDef = node("ValDef" , None, DefSym),
n_PatDef = node("PatDef" , None, NoSym),
n_DefDef = node("DefDef" , None, DefSym),
n_AbsTypeDef = node("AbsTypeDef" , None, DefSym),
n_AliasTypeDef = node("AliasTypeDef" , None, DefSym),
n_Import = node("Import" , None, HasSym),
n_CaseDef = node("CaseDef" , None, NoSym),
n_Template = node("Template" , None, HasSym),
n_LabelDef = node("LabelDef" , Term, DefSym),
n_Block = node("Block" , Term, NoSym),
n_Sequence = node("Sequence" , Term, NoSym),
n_Alternative = node("Alternative" , Term, NoSym),
n_Bind = node("Bind" , Term, DefSym),
n_Visitor = node("Visitor" , Term, NoSym),
n_Function = node("Function" , Term, NoSym),
n_Assign = node("Assign" , Term, NoSym),
n_If = node("If" , Term, NoSym),
n_Switch = node("Switch" , Term, NoSym),
n_Return = node("Return" , Term, HasSym),
n_Throw = node("Throw" , Term, NoSym),
n_New = node("New" , Term, NoSym),
n_Create = node("Create" , Term, HasSym),
n_Typed = node("Typed" , Term, NoSym),
n_TypeApply = node("TypeApply" , Term, NoSym),
n_Apply = node("Apply" , Term, NoSym),
n_Super = node("Super" , Term, HasSym),
n_This = node("This" , Term, HasSym),
n_Select = node("Select" , Test, HasSym),
n_Ident = node("Ident" , Test, HasSym),
n_Literal = node("Literal" , Term, NoSym),
n_TypeTerm = node("TypeTerm" , Type, NoSym),
n_SingletonType = node("SingletonType" , Type, NoSym),
n_SelectFromType = node("SelectFromType", Type, HasSym),
n_FunType = node("FunType" , Type, NoSym),
n_CompoundType = node("CompoundType" , Type, NoSym),
n_AppliedType = node("AppliedType" , Type, NoSym),
n_Try = node("Try" , Term, NoSym);
public final TreeNode[] nodes;
public int arrays;
//########################################################################
// Public Constructors
public Tree() {
nodes = (TreeNode[])list.toArray(new TreeNode[list.size()]);
n_Empty.
setDescription("A tree node for the absence of a tree").
setRange(Phase.PARSER, Phase.UNKNOWN).
noFields();
n_DocDef.
setDescription("Documented definition").
setRange(Phase.PARSER, Phase.ANALYZER).
addField(t_String, "comment").
addField(t_Tree, "definition");
n_ClassDef.
setDescription("Class and data declaration").
setRange(Phase.PARSER, Phase.END).
addField(t_int, "mods", SymFlags).
addField(t_TypeName, "name", SymName).
addField(n_AbsTypeDef.getType(1), "tparams").
addField(n_ValDef.getType(2), "vparams").
addField(t_TypeTree, "tpe").
addField(n_Template.getType(0), "impl");
n_PackageDef.
setDescription("Package declaration").
setRange(Phase.PARSER, Phase.UNKNOWN).
addField(t_TermTree, "packaged").
addField(n_Template.getType(0), "impl");
n_ModuleDef.
setDescription("Module declaration").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_int, "mods", SymFlags).
addField(t_TermName, "name", SymName).
addField(t_TypeTree, "tpe").
addField(n_Template.getType(0), "impl");
n_ValDef.
setDescription("Value declaration (var or let)").
setRange(Phase.PARSER, Phase.END).
addField(t_int, "mods", SymFlags).
addField(t_TermName, "name", SymName).
addField(t_TypeTree, "tpe").
addField(t_TermTree, "rhs");
n_PatDef.
setDescription("Value declaration with patterns (val)").
setRange(Phase.PARSER, Phase.DESUGARIZER).
addField(t_int, "mods").
addField(t_TermTree, "pat").
addField(t_TermTree, "rhs");
n_DefDef.
setDescription("Function declaration (def)").
setRange(Phase.PARSER, Phase.END).
addField(t_int, "mods", SymFlags).
addField(t_TermName, "name", SymName).
addField(n_AbsTypeDef.getType(1), "tparams").
addField(n_ValDef.getType(2), "vparams").
addField(t_TypeTree, "tpe").
addField(t_TermTree, "rhs");
n_AbsTypeDef.
setDescription("Type declaration").
setRange(Phase.PARSER, Phase.END). // !!! needed for type params
addField(t_int, "mods", SymFlags).
addField(t_TypeName, "name", SymName).
addField(t_TypeTree, "rhs").
addField(t_TypeTree, "lobound");
n_AliasTypeDef.
setDescription("Type alias").
setRange(Phase.PARSER, Phase.EXPLICITOUTER).
addField(t_int, "mods", SymFlags).
addField(t_TypeName, "name", SymName).
addField(n_AbsTypeDef.getType(1), "tparams").
addField(t_TypeTree, "rhs");
n_Import.
setDescription("Import declaration").
setRange(Phase.PARSER, Phase.ANALYZER).
addField(t_TermTree, "expr").
addField(t_Names, "selectors");
n_CaseDef.
setDescription("Case declaration").
setRange(Phase.PARSER, Phase.TRANSMATCH).
addField(t_TermTree, "pat").
addField(t_TermTree, "guard").
addField(t_TermTree, "body");
n_Template.
setDescription("Instantiation templates").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTrees, "parents").
addField(t_Trees, "body");
n_LabelDef.
setDescription("Labelled expression - the symbols in the array (must be Idents!) are those the label takes as argument").
setRange(Phase.PARSER, Phase.END).
addField(t_TermName, "name", SymName).
addField(n_Ident.getType(1), "params").
addField(t_TermTree, "rhs");
n_Block.
setDescription("Block of expressions " +
"(semicolon separated expressions)").
setRange(Phase.PARSER, Phase.END).
addField(t_Trees, "stats").
addField(t_TermTree, "expr");
n_Sequence.
setDescription("Sequence of expressions (comma separated expressions)").
setRange(Phase.PARSER, Phase.TRANSMATCH).
addField(t_TermTrees, "trees");
n_Alternative.
setDescription("Alternatives of expressions/patterns").
setRange(Phase.PARSER, Phase.TRANSMATCH).
addField(t_TermTrees, "trees");
n_Bind.
setDescription("Bind of a variable to a rhs pattern, possibly recursive").
setRange(Phase.PARSER, Phase.TRANSMATCH).
addField(t_TermName, "name", SymName).
addField(t_TermTree, "rhs");
n_Visitor.
setDescription("Visitor (a sequence of cases)").
setRange(Phase.PARSER, Phase.TRANSMATCH).
addField(n_CaseDef.getType(1), "cases");
n_Function.
setDescription("Anonymous function").
setRange(Phase.PARSER, Phase.ANALYZER).
addField(n_ValDef.getType(1), "vparams").
addField(t_TermTree, "body");
n_Assign.
setDescription("Assignment").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "lhs").
addField(t_TermTree, "rhs");
n_If.
setDescription("Conditional expression").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "cond").
addField(t_TermTree, "thenp").
addField(t_TermTree, "elsep");
n_Switch.
setDescription("Switch").
setRange(Phase.REFCHECK, Phase.END).
addField(t_TermTree, "test").
addField(t_ints, "tags").
addField(t_TermTrees, "bodies").
addField(t_TermTree, "otherwise");
n_Return.
setDescription("Return").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "expr");
n_Throw.
setDescription("Throw").
setRange(Phase.PARSER, Phase.ANALYZER).
addField(t_TermTree, "expr");
n_New.
setDescription("Instantiation").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "init");
n_Create.
setDescription("Instance creation").
setRange(Phase.ANALYZER, Phase.END).
addField(t_TermTree, "qualifier").
addField(t_TypeTrees, "targs");
n_Typed.
setDescription("Type annotation").
setRange(Phase.PARSER, Phase.EXPLICITOUTER).
addField(t_TermTree, "expr").
addField(t_TypeTree, "tpe");
n_TypeApply.
setDescription("Type application").
setRange(Phase.PARSER, Phase.END).
addField(t_Tree, "fun").
addField(t_TypeTrees, "args");
n_Apply.
setDescription("Value application").
setRange(Phase.PARSER, Phase.END).
addField(t_Tree, "fun"). // !!! should be t_TermTree
addField(t_TermTrees, "args");
n_Super.
setDescription("Super reference").
setRange(Phase.PARSER, Phase.END).
addField(t_TypeName, "qualifier", SymName).
addField(t_TypeName, "mixin");
n_This.
setDescription("Self reference").
setRange(Phase.PARSER, Phase.END).
addField(t_TypeName, "qualifier", SymName);
n_Select.
setDescription("Designator").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "qualifier").
addField(t_TestName, "selector", SymName);
n_Ident.
setDescription("Identifier").
setRange(Phase.PARSER, Phase.END).
addField(t_TestName, "name", SymName);
n_Literal.
setDescription("Literal").
setRange(Phase.PARSER, Phase.END).
addField(t_AConstant, "value");
n_TypeTerm.
setDescription("TypeTerm").
setRange(Phase.PARSER, Phase.END);
n_SingletonType.
setDescription("Singleton type").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_TermTree, "ref");
n_SelectFromType.
setDescription("Type selection").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_TypeTree, "qualifier").
addField(t_TypeName, "selector", SymName);
n_FunType.
setDescription("Function type").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_TypeTrees, "argtpes").
addField(t_TypeTree, "restpe");
n_CompoundType.
setDescription("Object type (~ Template)").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_TypeTrees, "parents").
addField(t_Trees, "refinements");
n_AppliedType.
setDescription("Applied type").
setRange(Phase.PARSER, Phase.REFCHECK).
addField(t_TypeTree, "tpe").
addField(t_TypeTrees, "args");
n_Try.
setDescription("Try Expression").
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "block").
addField(t_TermTree, "catcher").
addField(t_TermTree, "finalizer");
}
//########################################################################
// Public Functions
public static boolean isTree(Type type) {
switch (type) {
case Array(Type item):
return isTree(item);
case TreeType.Tree(_):
case TreeType.Node(_):
return true;
default:
return false;
}
}
//########################################################################
// Public Methods
public Type getType(int rank) {
return getType(rank, Any);
}
public Type getType(int rank, TreeKind kind) {
arrays = Math.max(arrays , rank);
return rank==0 ? TreeType.Tree(kind) : TreeType.Array(getType(rank-1));
}
public String getFormal(String name) {
return getType(0) + " " + name;
}
//########################################################################
// Private Methods
private TreeNode node(String name, TreeKind kind, TreeSymbol symbol) {
TreeNode node = new TreeNode(name, kind, symbol);
list.add(node);
return node;
}
//########################################################################
}