diff options
author | paltherr <paltherr@epfl.ch> | 2004-02-19 13:08:48 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-02-19 13:08:48 +0000 |
commit | d19cd4e6791347cfbcd161c02a49eebef4aab686 (patch) | |
tree | c8cc3229b42c7656e9148765b0fac3f22e21252b /sources/scalac/ast | |
parent | 3b4e70e1bdf4dcf237d398157b13cbd941e1001e (diff) | |
download | scala-d19cd4e6791347cfbcd161c02a49eebef4aab686.tar.gz scala-d19cd4e6791347cfbcd161c02a49eebef4aab686.tar.bz2 scala-d19cd4e6791347cfbcd161c02a49eebef4aab686.zip |
- Removed java version of files translated to s...
- Removed java version of files translated to scala
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r-- | sources/scalac/ast/Tree.java.tmpl | 18 | ||||
-rw-r--r-- | sources/scalac/ast/TreeGen.java | 59 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 2124 | ||||
-rw-r--r-- | sources/scalac/ast/parser/ParserPhase.java | 39 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Scanner.java | 867 | ||||
-rw-r--r-- | sources/scalac/ast/parser/TokenData.java | 44 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Tokens.java | 92 | ||||
-rw-r--r-- | sources/scalac/ast/printer/HTMLTreePrinter.java | 176 | ||||
-rw-r--r-- | sources/scalac/ast/printer/TextTreePrinter.java | 813 |
9 files changed, 29 insertions, 4203 deletions
diff --git a/sources/scalac/ast/Tree.java.tmpl b/sources/scalac/ast/Tree.java.tmpl index 5f5277b8af..e1dbed177f 100644 --- a/sources/scalac/ast/Tree.java.tmpl +++ b/sources/scalac/ast/Tree.java.tmpl @@ -8,6 +8,9 @@ package scalac.ast; +import java.io.StringWriter; +import java.io.PrintWriter; + import ch.epfl.lamp.util.Position; import scalac.Global; @@ -15,8 +18,6 @@ import scalac.checkers.CheckTreeNodes; import scalac.symtab.Symbol; import scalac.symtab.Type; import scalac.util.Debug; -import java.io.StringWriter; -import scalac.ast.printer.TextTreePrinter; {#Imports#} public class Tree { @@ -117,15 +118,12 @@ public class Tree { //######################################################################## // Public Methods - tree to string - /** - * Get string corresponding to this tree only implemented for - * prefix trees, maybe we should generalize this; the PatternMatch - * phase needs support for Apply, so this case got added - */ + /** Returns the string representation of this tree. */ public String toString() { - StringWriter out = new StringWriter(); - new TextTreePrinter(out).print(this).flush(); - return out.toString(); + StringWriter buffer = new StringWriter(); + Global global = Global.instance; + global.newTextTreePrinter(new PrintWriter(buffer)).print(this).flush(); + return buffer.toString(); } //######################################################################## diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 27b168abd8..524e0ed253 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -12,9 +12,7 @@ import scalac.Global; import scalac.ast.Tree.*; import scalac.atree.AConstant; import scalac.symtab.*; -import scalac.typechecker.Infer; import scalac.util.*; -import scalac.ApplicationError; /** * This class provides method to build attributed trees. @@ -36,9 +34,6 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { /** The tree factory */ private final TreeFactory make; - /** The type inferencer */ - private final Infer infer; - /** Initializes this instance. */ public TreeGen(Global global) { this(global, global.make); @@ -49,7 +44,6 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { this.global = global; this.definitions = global.definitions; this.make = make; - this.infer = new Infer(global, this, make); } //######################################################################## @@ -412,23 +406,18 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { return TypeApply(fn.pos, fn, targs); } public TypeApply TypeApply(int pos, Tree fn, Tree[] targs) { - try { - switch (fn.type) { - case Type.OverloadedType(Symbol[] alts, Type[] alttypes): - global.nextPhase(); - infer.polyAlternative(fn, alts, alttypes, targs.length); - global.prevPhase(); - } - switch (fn.type) { - case Type.PolyType(Symbol[] tparams, Type restpe): - global.nextPhase(); - restpe = restpe.subst(tparams, Tree.typeOf(targs)); - global.prevPhase(); - return (TypeApply)make.TypeApply(pos, fn, targs).setType(restpe); - } - } catch (Type.Error ex) { - } - throw new ApplicationError("poly type required", fn.type); + switch (fn.type()) { + case Type.OverloadedType(_, _): + // TreeGen only builds trees, names must already be resolved + throw Debug.abort("unresolved name", fn + " - " + fn.type); + case Type.PolyType(Symbol[] tparams, Type restpe): + global.nextPhase(); + restpe = restpe.subst(tparams, Tree.typeOf(targs)); + global.prevPhase(); + return (TypeApply)make.TypeApply(pos, fn, targs).setType(restpe); + default: + throw Debug.abort("illegal case", fn + " - " + fn.type()); + } } public TypeApply TypeApply(Tree fn, Tree[] targs) { return TypeApply(fn.pos, fn, targs); @@ -436,21 +425,15 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { /** Builds an Apply node with given function and arguments. */ public Apply Apply(int pos, Tree fn, Tree[] vargs) { - try { - switch (fn.type) { - case Type.OverloadedType(Symbol[] alts, Type[] alttypes): - global.nextPhase(); - infer.methodAlternative(fn, alts, alttypes, - Tree.typeOf(vargs), Type.AnyType); - global.prevPhase(); - } - switch (fn.type) { - case Type.MethodType(Symbol[] vparams, Type restpe): - return (Apply)make.Apply(pos, fn, vargs).setType(restpe); - } - } catch (Type.Error ex) { - } - throw new ApplicationError("method type required", fn.type); + switch (fn.type()) { + case Type.OverloadedType(_, _): + // TreeGen only builds trees, names must already be resolved + throw Debug.abort("unresolved name", fn + " - " + fn.type()); + case Type.MethodType(Symbol[] vparams, Type restpe): + return (Apply)make.Apply(pos, fn, vargs).setType(restpe); + default: + throw Debug.abort("illegal case", fn + " - " + fn.type()); + } } public Apply Apply(Tree fn, Tree[] vargs) { return Apply(fn.pos, fn, vargs); diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java deleted file mode 100644 index 6cbf3e342a..0000000000 --- a/sources/scalac/ast/parser/Parser.java +++ /dev/null @@ -1,2124 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast.parser; - -import ch.epfl.lamp.util.Position; - -import java.util.*; -import scalac.*; -import scalac.util.*; -import scalac.symtab.Modifiers; -import scalac.ast.*; -import scalac.atree.AConstant; -import Tree.*; - -/** A recursive descent parser for the programming language Scala. - * - * @author Martin Odersky, Matthias Zenger, Burak Emir - * @version 1.2 - */ -public class Parser implements Tokens { - - /** the lexical analyzer - */ - Scanner s; - - /** the tree factory - */ - TreeFactory make; - - /** the tree generator - */ - TreeGen gen; - - /** pattern checker and normalizer - */ - PatternNormalizer pN; - - /** The current nesting depths of while and do loops. - */ - int loopNestingDepth; - - public Parser(Unit unit) { - s = new Scanner(unit); - make = unit.global.make; - gen = unit.global.treeGen; - pN = new PatternNormalizer( unit ); - mapTreeComment = unit.global.mapTreeComment; - loopNestingDepth = 0; - } - - /** this is the general parse method - */ - public Tree[] parse() { - Tree[] ts = s.unit.console ? templateStatSeq() : compilationUnit(); - accept(EOF); - return ts; - } - -/////// ERROR HANDLING ////////////////////////////////////////////////////// - - private void skip() { - //System.out.println("<skipping> " + s.token2string(s.token));//DEBUG - int nparens = 0; - int nbraces = 0; - while (true) { - switch (s.token) { - case EOF: - return; - case SEMI: - if (nparens == 0 && nbraces == 0) - return; - break; - case RPAREN: - nparens--; - break; - case RBRACE: - if (nbraces == 0) - return; - nbraces--; - break; - case LPAREN: - nparens++; - break; - case LBRACE: - nbraces++; - break; - } - //System.out.println("skipped: " + s.token2string(s.token));//DEBUG - s.nextToken(); - } - } - - Tree syntaxError(String msg, boolean skip) { - return syntaxError(s.pos, msg, skip); - } - - Tree syntaxError(int pos, String msg, boolean skip) { - if (pos != s.errpos) { - s.unit.error(pos, msg); - s.errpos = pos; - } - if (skip) skip(); - return make.Bad(pos); - } - - int accept(int token) { - int pos = s.pos; - if (s.token != token) { - int errpos = ((s.pos >>> Position.COLUMN_BITS) > - (s.lastpos >>> Position.COLUMN_BITS)) ? - s.lastpos : s.pos; - syntaxError(errpos, s.token2string(token) + " expected but " + - s.token2string(s.token) + " found.", true); - } - if (s.token == token) s.nextToken(); - return pos; - } - -/////// TOKEN CLASSES ////////////////////////////////////////////////////// - - boolean isModifier() { - return (s.token == ABSTRACT) - || (s.token == FINAL) - || (s.token == SEALED) - || (s.token == PRIVATE) - || (s.token == PROTECTED) - || (s.token == OVERRIDE); - } - - boolean isLocalModifier() { - return (s.token == ABSTRACT) - || (s.token == FINAL) - || (s.token == SEALED); - } - - boolean isDefIntro() { - switch (s.token) { - case VAL: case VAR: case DEF: case TYPE: - case OBJECT: case CASEOBJECT: case CLASS: case CASECLASS: case TRAIT: - return true; - default: - return false; - } - } - - boolean isDclIntro() { - switch (s.token) { - case VAL: case VAR: case DEF: case TYPE: - return true; - default: - return false; - } - } - - boolean isExprIntro() { - switch (s.token) { - case CHARLIT: case INTLIT: case LONGLIT: - case FLOATLIT: case DOUBLELIT: case STRINGLIT: - case SYMBOLLIT: case TRUE: case FALSE: case NULL: case IDENTIFIER: - case THIS: case SUPER: case IF: - case FOR: case NEW: case USCORE: - case TRY: case WHILE: case DO: case RETURN: case THROW: - case LPAREN: case LBRACE: - return true; - default: - return false; - } - } - -/////// COMMENT COLLECTION /////////////////////////////////////////////////// - - /** keep the comments associated with a given tree - */ - protected Map mapTreeComment; - - /** stack of comments - */ - protected final Stack commentStack = new Stack(); - - /** positive if we are inside a block - */ - protected int local = 0; - - /** push last encountered comment and reset the buffer - */ - protected void pushComment() { - if (local == 0) { - commentStack.push(s.docBuffer == null ? null : s.docBuffer.toString()); - s.docBuffer = null; - } - } - - /** pop a comment from the stack and associate it with the given tree - */ - protected Tree popComment(Tree tree) { - if (local == 0) - if (!commentStack.empty()) - mapTreeComment.put(tree, (String) commentStack.pop()); - return tree; - } - -/////// TREE CONSTRUCTION //////////////////////////////////////////////////// - - /** Name supply - */ - int fresh = 0; - - Name fresh() { - return Name.fromString("x$" + (fresh++)); - } - - /** Create a tree representing a packaging - */ - Tree makePackaging(int pos, Tree pkg, Tree[] stats) { - while (true) { - Template templ = make.Template(pos, Tree.EMPTY_ARRAY, stats); - switch (pkg) { - case Select(Tree qual, Name name): - stats = new Tree[]{ - make.PackageDef(pos, make.Ident(pkg.pos, name), templ)}; - pkg = qual; - break; - default: - return make.PackageDef(pos, pkg, templ); - } - } - } - - /** Create tree representing binary operation expression or pattern. - */ - Tree makeBinop(boolean isExpr, int pos, Tree left, Name op, Tree right) { - if (isExpr) { - if (op.isLeftAssoc()) { - return make.Apply(pos, - make.Select(pos, left, NameTransformer.encode(op)), - new Tree[]{right}); - } else { - Name x = fresh(); - return make.Block(pos, - new Tree[]{ - make.ValDef(pos, 0, x, Tree.Empty, left)}, - make.Apply(pos, - make.Select(pos, right, NameTransformer.encode(op)), - new Tree[]{make.Ident(left.pos, x)})); - } - } else { - return make.Apply(pos, - make.Ident(pos, NameTransformer.encode(op).toTypeName()), - new Tree[]{left, right}); - } - } - - - Tree scalaDot(int pos, Name name) { - return make.Select(pos, make.Ident(pos, Names.scala), name); - } - - Tree scalaRuntimeDot(int pos, Name name) { - return make.Select(pos, scalaDot(pos, Names.runtime), name); - } - - Tree ScalaRunTimeDot(int pos, Name name) { - return make.Select(pos, scalaRuntimeDot(pos, Names.ScalaRunTime), name); - } - - Tree scalaBooleanDot(int pos, Name name) { - return make.Select(pos, scalaDot(pos, Names.Boolean), name); - } - - Tree scalaXmlDot(int pos, Name name) { - return make.Select(pos, scalaDot(pos, Names.xml), name); - } - - Tree scalaXmlNoBindingDot(int pos, Name name) { - return make.Select(pos, scalaXmlDot(pos, Names.nobinding), name); - } - - Tree scalaAnyRefConstr(int pos) { - return make.Apply( - pos, scalaDot(pos, Names.AnyRef.toTypeName()), Tree.EMPTY_ARRAY); - } - - Tree scalaObjectConstr(int pos) { - return make.Apply( - pos, scalaDot(pos, Names.ScalaObject.toTypeName()), Tree.EMPTY_ARRAY); - } - - /** Create tree for for-comprehension <for (enums) do body> or - * <for (enums) yield body> where mapName and flatmapName are chosen - * corresponding to whether this is a for-do or a for-yield. - */ - Tree makeFor(int pos, Tree[] enums, Name mapName, Name flatmapName, Tree body) { - switch (enums[0]) { - case PatDef(int mods, Tree pat, Tree rhs): - if (enums.length == 1) - return makeFor1(pos, mapName, pat, rhs, body); - Tree[] newenums = new Tree[enums.length - 1]; - switch (enums[1]) { - case PatDef(int mods2, Tree pat2, Tree rhs2): - System.arraycopy(enums, 1, newenums, 0, newenums.length); - return makeFor1(pos, flatmapName, pat, rhs, - makeFor(enums[1].pos, newenums, mapName, flatmapName, body)); - default: - System.arraycopy(enums, 2, newenums, 1, newenums.length - 1); - newenums[0] = make.PatDef( - enums[0].pos, mods, pat, - makeFor1(enums[1].pos, Names.filter, pat.duplicate(), rhs, enums[1])); - return makeFor(pos, newenums, mapName, flatmapName, body); - } - default: - throw new ApplicationError(); - } - } - - //where - Tree makeFor1(int pos, Name name, Tree pat, Tree rhs, Tree body) { - return make.Apply( - pos, make.Select(pos, rhs, name), - new Tree[]{makeForCont(pos, pat, body)}); - } - Tree makeForCont(int pos, Tree pat, Tree body) { - switch (pat) { - case Ident(Name name1): - if (name1.isVariable()) - return make.Function( - pos, - new Tree.ValDef[]{ - (ValDef) make.ValDef( - pat.pos, Modifiers.PARAM, - name1, Tree.Empty, Tree.Empty)}, - body); - } - return make.Visitor(pos, new Tree.CaseDef[]{ - (CaseDef)make.CaseDef(pos, pat, Tree.Empty, body)}); - } - - Tree makeTry(int pos, Tree body, Tree catcher, Tree finalizer) { - Tree t = body; - if (catcher != Tree.Empty) - t = - make.Apply( - pos, - make.Select( - pos, - make.Apply( - pos, ScalaRunTimeDot(pos, Names.Try), new Tree[]{t}), - Names.Catch), - new Tree[]{catcher}); - if (finalizer != Tree.Empty) - t = - make.Apply( - pos, - make.Select( - pos, - make.Apply( - pos, ScalaRunTimeDot(pos, Names.Try), new Tree[]{t}), - Names.Finally), - new Tree[]{finalizer}); - return t; - } - - Tree makeWhile(int pos, Name lname, Tree cond, Tree body) { - Tree continu = make.Apply( - pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY); - Tree rhs = make.If( - pos, - cond, - make.Block(body.pos, new Tree[]{body}, continu), - gen.mkUnitLit(pos)); - return make.LabelDef(pos, lname, new Ident[0], rhs); - } - - Tree makeDoWhile(int pos, Name lname, Tree body, Tree cond) { - Tree continu = make.Apply( - pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY); - Tree rhs = make.Block( - body.pos, - new Tree[]{ - body}, - make.If( - cond.pos, - cond, - continu, - gen.mkUnitLit(pos))); - return make.LabelDef(pos, lname, new Ident[0], rhs); - } - - /** Convert tree to formal parameter list - */ - ValDef[] convertToParams(Tree t) { - switch (t) { - case Function(ValDef[] params, Tree.Empty): - return params; - case Ident(_): - case Typed(Ident(_), _): - return new ValDef[]{convertToParam(t)}; - case Literal(AConstant.UNIT): - return Tree.ValDef_EMPTY_ARRAY; // !!! - } - syntaxError(t.pos, "malformed formal parameter list", false); - return Tree.ValDef_EMPTY_ARRAY; - } - - /** Convert list of trees to formal parameter list - */ - ValDef[] convertToParams(Tree[] ts) { - ValDef[] res = new ValDef[ts.length]; - for (int i = 0; i < res.length; i++) - res[i] = convertToParam(ts[i]); - return res; - } - - /** Convert tree to formal parameter - */ - ValDef convertToParam(Tree tree) { - switch (tree) { - case Ident(Name name): - return (ValDef)make.ValDef( - tree.pos, Modifiers.PARAM, name, Tree.Empty, Tree.Empty); - case Typed(Ident(Name name), Tree tpe): - return (ValDef)make.ValDef( - tree.pos, Modifiers.PARAM, name, tpe, Tree.Empty); - default: - Tree tpe = syntaxError(tree.pos, "not a legal formal parameter", false); - return (ValDef)make.ValDef( - tree.pos, Modifiers.PARAM, Names.ERROR, tpe, Tree.Empty); - } - } - - /** Convert (qual)ident to type identifier - */ - Tree convertToTypeId(Tree t) { - switch (t) { - case Ident(Name name): - return make.Ident(t.pos, name.toTypeName()); - case Select(Tree qual, Name name): - return make.Select(t.pos, qual, name.toTypeName()); - default: - return t; - } - } - - /** Convert (qual)ident to constructor identifier - */ - Tree convertToConstr(Tree t) { - switch (t) { - case Ident(Name name): - return make.Ident(t.pos, name.toTypeName()); - case Select(Tree qual, Name name): - return make.Select(t.pos, qual, name.toTypeName()); - default: - return syntaxError(t.pos, "class constructor expected", false); - } - } - - /** Complete unapplied constructor with `()' arguments - */ - Tree applyConstr(Tree t) { - switch (t) { - case Apply(_, _): - return t; - default: - return make.Apply(t.pos, t, Tree.EMPTY_ARRAY); - } - } - -/////// OPERAND/OPERATOR STACK ///////////////////////////////////////////////// - - Tree[] operands = new Tree[8]; - int[] positions = new int[8]; - Name[] operators = new Name[8]; - int sp = 0; - - void push(Tree od, int pos, Name op) { - if (sp == operands.length) { - Tree[] operands1 = new Tree[sp * 2]; - System.arraycopy(operands, 0, operands1, 0, sp); - operands = operands1; - int[] positions1 = new int[sp * 2]; - System.arraycopy(positions, 0, positions1, 0, sp); - positions = positions1; - Name[] operators1 = new Name[sp * 2]; - System.arraycopy(operators, 0, operators1, 0, sp); - operators = operators1; - } - operands[sp] = od; - positions[sp] = pos; - operators[sp] = op; - sp++; - } - - Tree reduceStack(boolean isExpr, int base, Tree top, - int prec, boolean leftAssoc) { - if (sp != base && - operators[sp-1].precedence() == prec && - operators[sp-1].isLeftAssoc() != leftAssoc) { - syntaxError( - positions[sp-1], - "left- and right-associative operators with same precedence may not be mixed", - false); - } - while (sp != base && - (prec < operators[sp-1].precedence() || - (leftAssoc && prec == operators[sp-1].precedence()))) { - sp--; - top = makeBinop(isExpr, positions[sp], operands[sp], operators[sp], top); - } - return top; - } - -/////// IDENTIFIERS AND LITERALS //////////////////////////////////////////////////////////// - - static final Name MINUS = Name.fromString("-"); - static final Name PLUS = Name.fromString("+"); - static final Name BANG = Name.fromString("!"); - static final Name TILDE = Name.fromString("~"); - static final Name STAR = Name.fromString("*"); - static final Name BAR = Name.fromString("|"); - static final Name OPT = Name.fromString("?"); - - Name ident() { - if (s.token == IDENTIFIER) { - Name name = NameTransformer.encode(s.name); - s.nextToken(); - return name; - } else { - accept(IDENTIFIER); - return Names.ERROR; - } - } - - /** StableRef ::= StableId - * | [Ident `.'] this - * SimpleType ::= StableRef [`.' type] - */ - Tree stableRef(boolean thisOK, boolean typeOK) { - Tree t; - if (s.token == THIS) { - t = make.This(s.skipToken(), TypeNames.EMPTY); - if (!thisOK || s.token == DOT) - t = selectors(accept(DOT), t, typeOK); - } else if (s.token == SUPER) { - t = make.Super( - s.skipToken(), TypeNames.EMPTY, mixinQualifierOpt()); - t = make.Select(accept(DOT), t, ident()); - if (s.token == DOT) - t = selectors(s.skipToken(), t, typeOK); - } else { - Ident i = make.Ident(s.pos, ident()); - t = i; - if (s.token == DOT) { - int pos = s.skipToken(); - if (s.token == THIS) { - s.nextToken(); - t = make.This(i.pos, i.name.toTypeName()); - if (!thisOK || s.token == DOT) - t = selectors(accept(DOT), t, typeOK); - } else if (s.token == SUPER) { - s.nextToken(); - t = make.Super( - i.pos, i.name.toTypeName(), mixinQualifierOpt()); - t = make.Select(accept(DOT), t, ident()); - if (s.token == DOT) - t = selectors(s.skipToken(), t, typeOK); - } else { - t = selectors(pos, t, typeOK); - } - } - } - return t; - } - - Tree selectors(int pos, Tree t, boolean typeOK) { - if (typeOK && s.token == TYPE) { - s.nextToken(); - return make.SingletonType(pos, t); - } else { - t = make.Select(pos, t, ident()); - if (s.token == DOT) { - t = selectors(s.skipToken(), t, typeOK); - } - return t; - } - } - - /** MixinQualifier ::= `[' Id `]' - */ - Name mixinQualifierOpt() { - if (s.token == LBRACKET) { - s.nextToken(); - Name name = ident().toTypeName(); - accept(RBRACKET); - return name; - } else { - return TypeNames.EMPTY; - } - } - - /** StableId ::= Id - * | StableRef `.' Id - * | [Id '.'] super [MixinQualifier] ` `.' Id - */ - Tree stableId() { - return stableRef(false, false); - } - - /** QualId ::= Id {`.' Id} - */ - Tree qualId() { - Tree id = make.Ident(s.pos, ident()); - if (s.token == DOT) return selectors(s.skipToken(), id, false); - else return id; - } - - /** SimpleExpr ::= literal - * | symbol [ArgumentExprs] - * | null - */ - Tree literal(boolean isPattern) { - Tree t; - switch (s.token) { - case CHARLIT: - t = gen.mkCharLit(s.pos, (char)s.intVal); - break; - case INTLIT: - t = gen.mkIntLit(s.pos, (int)s.intVal); - break; - case LONGLIT: - t = gen.mkLongLit(s.pos, s.intVal); - break; - case FLOATLIT: - t = gen.mkFloatLit(s.pos, (float)s.floatVal); - break; - case DOUBLELIT: - t = gen.mkDoubleLit(s.pos, s.floatVal); - break; - case STRINGLIT: - t = gen.mkStringLit(s.pos, s.name.toString()); - break; - case TRUE: - t = gen.mkBooleanLit(s.pos, true); - break; - case FALSE: - t = gen.mkBooleanLit(s.pos, false); - break; - case NULL: - t = gen.mkNullLit(s.pos); - break; - case SYMBOLLIT: - int pos = s.pos; - Tree symt = scalaDot(s.pos, Names.Symbol); - if (isPattern) symt = convertToTypeId(symt); - TreeList ts = new TreeList(); - ts.append(gen.mkStringLit(s.pos, s.name.toString())); - s.nextToken(); - if (s.token == LPAREN || s.token == LBRACE) - ts.append(argumentExprs()); - return make.Apply(pos, symt, ts.toArray()); - default: - return syntaxError("illegal literal", true); - } - s.nextToken(); - return t; - } - -//////// TYPES /////////////////////////////////////////////////////////////// - - /** TypedOpt ::= [`:' Type] - */ - Tree typedOpt() { - if (s.token == COLON) { - s.nextToken(); - return type(); - } else { - return Tree.Empty; - } - } - - /** SimpleTypedOpt ::= [`:' SimpleType] - */ - Tree simpleTypedOpt() { - if (s.token == COLON) { - s.nextToken(); - return simpleType(); - } else { - return Tree.Empty; - } - } - - /** Types ::= Type {`,' Type} - */ - Tree[] types() { - TreeList ts = new TreeList(); - ts.append(type()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(type()); - } - return ts.toArray(); - } - - /** Type ::= Type1 `=>' Type - * | `(' [Types] `)' `=>' Type - * | Type1 - */ - Tree type() { - Tree t; - if (s.token == LPAREN) { - s.nextToken(); - if (s.token == RPAREN) { - s.nextToken(); - int pos = accept(ARROW); - return make.FunType(pos, Tree.EMPTY_ARRAY, type()); - } else { - t = type(); - if (s.token == COMMA) { - s.nextToken(); - TreeList ts = new TreeList(); - ts.append(t); - ts.append(types()); - accept(RPAREN); - int pos = accept(ARROW); - return make.FunType(pos, ts.toArray(), type()); - } else { - accept(RPAREN); - } - } - } else { - t = type1(); - } - if (s.token == ARROW) - return make.FunType(s.skipToken(), new Tree[]{t}, type()); - else - return t; - } - - /** Type1 ::= SimpleType {with SimpleType} [Refinement] - */ - Tree type1() { - int pos = s.pos; - Tree t = simpleType(); - if (s.token == WITH || s.token == LBRACE) { - TreeList ts = new TreeList(); - ts.append(t); - while (s.token == WITH) { - s.nextToken(); - ts.append(simpleType()); - } - Tree[] rs = (s.token == LBRACE) ? refinement() : Tree.EMPTY_ARRAY; - return make.CompoundType(pos, ts.toArray(), rs); - } else { - return t; - } - } - - /** SimpleType ::= SimpleType TypeArgs - * | SimpleType `#' Id - * | StableId - * | StableRef `.' type - * | `(' Type `)' - */ - Tree simpleType() { - int pos = s.pos; - Tree t; - if (s.token == LPAREN) { - s.nextToken(); - t = type(); - accept(RPAREN); - } else { - t = convertToTypeId(stableRef(false, true)); - } - while (true) { - if (s.token == HASH) - t = make.SelectFromType(s.skipToken(), t, ident().toTypeName()); - else if (s.token == LBRACKET) - t = make.AppliedType(pos, t, typeArgs()); - else break; - } - return t; - } - - /** TypeArgs ::= `[' Types `]' - */ - Tree[] typeArgs() { - accept(LBRACKET); - Tree[] ts = types(); - accept(RBRACKET); - return ts; - } - -//////// EXPRESSIONS //////////////////////////////////////////////////////// - - /** EqualsExpr ::= `=' Expr - */ - Tree equalsExpr() { - accept(EQUALS); - return expr(); - } - - /** Exprs ::= Expr {`,' Expr} - * | Expr `:' `_' `*' - Tree[] exprs() { - TreeList ts = new TreeList(); - ts.append(expr(true)); - while (s.token == COMMA) { - s.nextToken(); - ts.append(expr()); - } - return ts.toArray(); - } - */ - - /** Exprs ::= Expr {`,' Expr} - */ - Tree[] exprs() { - TreeList ts = new TreeList(); - ts.append(expr(true)); - while (s.token == COMMA) { - s.nextToken(); - ts.append(expr(true)); - } - return ts.toArray(); - } - - /** Expr ::= Bindings `=>' Expr - * | if `(' Expr `)' Expr [[`;'] else Expr] - * | try `{' block `}' [catch Expr] [finally Expr] - * | while `(' Expr `)' Expr - * | do Expr [`;'] while `(' Expr `)' - * | for `(' Enumerators `)' (do | yield) Expr - * | throw Expr - * | return [Expr] - * | [SimpleExpr `.'] Id `=' Expr - * | SimpleExpr ArgumentExprs `=' Expr - * | PostfixExpr [`:' Type1] - * Bindings ::= Id [`:' Type1] - * | `(' [Binding {`,' Binding}] `)' - * Binding ::= Id [`:' Type] - */ - Tree expr() { - return expr(false); - } - - Tree expr(boolean isArgument) { - if (s.token == IF) { - int pos = s.skipToken(); - accept(LPAREN); - Tree cond = expr(); - accept(RPAREN); - Tree thenp = expr(); - Tree elsep = Tree.Empty; - if (s.token == ELSE) { - s.nextToken(); - elsep = expr(); - } else { - elsep = Tree.Empty; - } - return make.If(pos, cond, thenp, elsep); - } else if (s.token == TRY) { - int pos = s.skipToken(); - accept(LBRACE); - Tree body = block(pos); - accept(RBRACE); - Tree catcher = Tree.Empty; - if (s.token == CATCH) { - s.nextToken(); - catcher = expr(); - } - Tree finalizer = Tree.Empty; - if (s.token == FINALLY) { - s.nextToken(); - finalizer = expr(); - } - return makeTry(pos, body, catcher, finalizer); - } else if (s.token == WHILE) { - Name lname = Name.fromString("label$" + loopNestingDepth); - loopNestingDepth++; - int pos = s.skipToken(); - accept(LPAREN); - Tree cond = expr(); - accept(RPAREN); - Tree body = expr(); - loopNestingDepth--; - return makeWhile(pos, lname, cond, body); - } else if (s.token == DO) { - Name lname = Name.fromString("label$" + loopNestingDepth); - loopNestingDepth++; - int pos = s.skipToken(); - Tree body = expr(); - if (s.token == SEMI) s.nextToken(); - accept(WHILE); - accept(LPAREN); - Tree cond = expr(); - accept(RPAREN); - loopNestingDepth--; - return makeDoWhile(pos, lname, body, cond); - } else if (s.token == FOR) { - s.nextToken(); - Tree[] enums; - accept(LPAREN); - enums = enumerators(); - accept(RPAREN); - if (s.token == YIELD) - return makeFor(s.skipToken(), enums, Names.map, Names.flatmap, expr()); - else - return makeFor(s.pos, enums, Names.foreach, Names.foreach, expr()); - } else if (s.token == RETURN) { - int pos = s.skipToken(); - Tree e = (isExprIntro()) ? expr() - : gen.mkUnitLit(pos); - return make.Return(pos, e); - } else if (s.token == THROW) { - int pos = s.skipToken(); - return make.Throw(pos, expr()); -// } else if (s.token == ARROW) { -// return make.Function(s.skipToken(), new ValDef[]{}, expr()); - } else { - Tree t = postfixExpr(); - if (s.token == EQUALS) { - switch (t) { - case Ident(_): - case Select(_, _): - case Apply(_, _): - t = make.Assign(s.skipToken(), t, expr()); - } - } else if (s.token == COLON) { - int pos = s.skipToken(); - if (isArgument && s.token == USCORE) { - int pos1 = s.skipToken(); - if (s.token == IDENTIFIER && s.name == Names.STAR) { - s.nextToken(); - /* this hack new */ - if( s.token != RPAREN ) { - syntaxError(s.pos, " escaping sequences only allowed for last argument", true); - } - /* end hack */ - t = make.Typed( - pos, t, make.Ident(pos1, TypeNames.WILDCARD_STAR)); - } else { - syntaxError(s.pos, "`*' expected", true); - } - } else { - Tree tp = type1(); - t = make.Typed(pos, t, tp); - } - } - if (s.token == ARROW) { - t = make.Function(s.skipToken(), convertToParams(t), expr()); - } - return t; - } - } - - /** PostfixExpr ::= InfixExpr [Id] - * InfixExpr ::= PrefixExpr - * | InfixExpr Id InfixExpr - */ - Tree postfixExpr() { - int base = sp; - Tree top = prefixExpr(); - while (s.token == IDENTIFIER) { - top = reduceStack( - true, base, top, s.name.precedence(), s.name.isLeftAssoc()); - push(top, s.pos, s.name); - ident(); - if (isExprIntro()) { - top = prefixExpr(); - } else { - sp--; - int pos = positions[sp]; - Name postOp = operators[sp]; - top = reduceStack(true, base, operands[sp], 0, true); - return make.Select(pos, top, NameTransformer.encode(postOp)); - } - } - return reduceStack(true, base, top, 0, true); - } - - /** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr - */ - Tree prefixExpr() { - Tree t; - if (s.token == IDENTIFIER && - (s.name == MINUS || - s.name == PLUS || - s.name == TILDE || - s.name == BANG)) { - Name name = ident(); - t = make.Select(s.pos, simpleExpr(), name); - } else { - t = simpleExpr(); - } - return t; - } - - /* SimpleExpr ::= literal - * | StableRef - * | `(' [Expr] `)' - * | BlockExpr - * | new Template - * | SimpleExpr `.' Id - * | SimpleExpr TypeArgs - * | SimpleExpr ArgumentExprs - */ - Tree simpleExpr() { - Tree t; - switch (s.token) { - case CHARLIT: - case INTLIT: - case LONGLIT: - case FLOATLIT: - case DOUBLELIT: - case STRINGLIT: - case SYMBOLLIT: - case TRUE: - case FALSE: - case NULL: - t = literal(false); - break; - case IDENTIFIER: - case THIS: - case SUPER: - t = stableRef(true, false); - break; - case LPAREN: - int pos = s.skipToken(); - if (s.token == RPAREN) { - s.nextToken(); - t = gen.mkUnitLit(pos); - } else { - t = expr(); - if (s.token == COMMA) { - int commapos = s.skipToken(); - TreeList ts = new TreeList(); - ts.append(t); - ts.append(exprs()); - accept(RPAREN); - if (s.token == ARROW) { - t = make.Function( - pos, convertToParams(ts.toArray()), Tree.Empty); - } else { - t = syntaxError(commapos, "`)' expected", false); - } - } else { - accept(RPAREN); - } - } - break; - case LBRACE: - t = blockExpr(); - break; - case NEW: - t = make.New(s.skipToken(), template()); - break; - default: - return syntaxError("illegal start of expression", true); - } - while (true) { - switch (s.token) { - case DOT: - t = make.Select(s.skipToken(), t, ident()); - break; - case LBRACKET: - switch (t) { - case Ident(_): - case Select(_, _): - t = make.TypeApply(s.pos, t, typeArgs()); - break; - default: - return t; - } - break; - case LPAREN: - case LBRACE: - t = make.Apply(s.pos, t, argumentExprs()); - break; - default: - return t; - } - } - } - - /** ArgumentExprs ::= `(' [Exprs] `)' - * | BlockExpr - */ - Tree[] argumentExprs() { - Tree[] ts = Tree.EMPTY_ARRAY; - if (s.token == LBRACE) { - ts = new Tree[]{blockExpr()}; - } else { - accept(LPAREN); - if (s.token != RPAREN) - ts = exprs(); - accept(RPAREN); - } - return ts; - } - - /** BlockExpr ::= `{' CaseClause {CaseClause} `}' - * | `{' Block `}' - */ - Tree blockExpr() { - local++; - Tree res; - int pos = accept(LBRACE); - if (s.token == CASE) { - TreeList stats = new TreeList(); - do { - stats.append(caseClause()); - } while (s.token == CASE); - res = make.Visitor( - pos, (CaseDef[]) stats.copyTo(new CaseDef[stats.length()])); - } else { - res = block(pos); - } - accept(RBRACE); - local--; - return res; - } - - /** Block ::= BlockStatSeq - */ - Tree block(int pos) { - return block(pos, blockStatSeq(new TreeList())); - } - private Tree block(int pos, Tree[] stats) { - if (stats.length == 0) - return gen.mkUnitLit(pos); - else if (!stats[stats.length - 1].isTerm()) - return make.Block(pos, stats, gen.mkUnitLit(pos)); - else if (stats.length == 1) - return stats[0]; - else { - Tree[] trees = new Tree[stats.length - 1]; - System.arraycopy(stats, 0, trees, 0, trees.length); - return make.Block(pos, trees, stats[stats.length - 1]); - } - } - - /** CaseClause ::= case Pattern [if PostfixExpr] `=>' Block - */ - Tree caseClause() { - int pos = accept(CASE); - Tree pat = validPattern(); - Tree guard = Tree.Empty; - if (s.token == IF) { - s.nextToken(); - guard = postfixExpr(); - } - return make.CaseDef(pos, pat, guard, block(accept(ARROW))); - } - - /** Enumerators ::= Generator {`;' Enumerator} - * Enumerator ::= Generator - * | Expr - */ - Tree[] enumerators() { - TreeList enums = new TreeList(); - enums.append(generator()); - while (s.token == SEMI) { - s.nextToken(); - if (s.token == VAL) enums.append(generator()); - else enums.append(expr()); - } - return enums.toArray(); - } - - /** Generator ::= val Pattern1 `<-' Expr - */ - Tree generator() { - int pos = accept(VAL); - Tree pat = validPattern1(); - accept(LARROW); - Tree rhs = expr(); - if (!TreeInfo.isVarPattern(pat)) - rhs = make.Apply( - rhs.pos, - make.Select(rhs.pos, rhs, Names.filter), - new Tree[]{ - make.Visitor( - rhs.pos, - new Tree.CaseDef[]{ - (CaseDef)make.CaseDef( - rhs.pos, pat.duplicate(), Tree.Empty, - gen.mkBooleanLit(s.pos, true)), - (CaseDef)make.CaseDef( - rhs.pos, make.Ident(rhs.pos, Names.PATTERN_WILDCARD), Tree.Empty, - gen.mkBooleanLit(s.pos, false))})}); - return make.PatDef(pos, 0, pat, rhs); - } - -//////// PATTERNS //////////////////////////////////////////////////////////// - - /** Pattern ( see pattern() ) which is checked for validity - */ - Tree validPattern() { - int pos = s.pos; - - Tree pat = pattern(); - if( this.pN.check( pat ) ) { // reports syntax errors as side effect - // normalize - Tree res = pN.wrapAlternative( pN.elimSequence( pN.flattenSequence ( pat ))); - return res; - } - //syntaxError( pos, "invalid pattern", false ); done in pN.check... - return make.Bad(pos); - } - - /** Pattern1 ( see pattern1() ) which is checked for validity - */ - Tree validPattern1() { - int pos = s.pos; - - Tree pat = pattern1(); - - if( this.pN.check( pat ) ) { // reports syntax errors as side effect - // normalize - Tree res = pN.wrapAlternative( pN.elimSequence( pN.flattenSequence ( pat ))); - return res; - } - //syntaxError( pos, "invalid pattern", false ); - return make.Bad(pos); - } - - /** Patterns ::= Pattern {`,' Pattern} - */ - Tree[] patterns() { - TreeList ts = new TreeList(); - ts.append(pattern()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(pattern()); - } - return ts.toArray(); - } - - /** Pattern ::= Pattern1 { `|' Pattern1 } - */ - Tree pattern() { - int pos = s.pos; - Tree first = pattern1(); - if(( s.token == IDENTIFIER )&&( s.name == BAR )) { - TreeList choices = new TreeList(); - choices.append( first ); - while(( s.token == IDENTIFIER )&&( s.name == BAR )) { - s.nextToken(); - choices.append( pattern1() ); - } - Tree[] tarr = choices.toArray(); - TreeList ts = pN.flattenAlternativeChildren( tarr ); - return pN.flattenAlternative( make.Alternative( pos, ts.toArray() ) ); - } - return first; - } - - /** Pattern1 ::= varid `:' Type1 - * | `_' `:' Type1 - * | Pattern2 - */ - Tree pattern1() { - Tree p = pattern2(); - if (s.token == COLON && TreeInfo.isVarPattern(p)) { - return make.Typed(s.skipToken(), p, type1()); - } - return p; - } - - /* Pattern2 ::= varid [ @ Pattern3 ] - * | Pattern3 - */ - Tree pattern2() { - Tree p = pattern3(); - if (s.token == AT && TreeInfo.isVarPattern(p)) { - switch (p) { - case Ident(Name name): - if (name == Names.PATTERN_WILDCARD) return pattern3(); - } - return make.Bind(s.skipToken(), ((Ident)p).name, pattern3()); - } - return p; - } - - /* Pattern3 ::= SimplePattern [ '*' | '?' | '+' ] - * | SimplePattern {Id SimplePattern} // op2 must not be empty - */ - Tree pattern3() { - int base = sp; - Tree top = simplePattern(); - if (s.token == IDENTIFIER) { - if (s.name == STAR) { /* p* becomes z@( |(p,z)) */ - s.nextToken(); - Name zname = fresh(); - Tree zvar = make.Ident(s.pos, zname); - - return make.Bind(s.pos, zname, - pN.flattenAlternative( - make.Alternative(s.pos, new Tree[] { - make.Sequence(s.pos, Tree.EMPTY_ARRAY), - pN.flattenSequence(make.Sequence(s.pos, new Tree[] { - top, - zvar - })) - }))); - } - else if (s.name == PLUS) { /* p+ becomes z@(p,(z| )) */ - s.nextToken(); - Name zname = fresh(); - Tree zvar = make.Ident(s.pos, zname); - - return make.Bind(s.pos, zname, - pN.flattenSequence(make.Sequence(s.pos, new Tree[] { - top, - pN.flattenAlternative(make.Alternative(s.pos, new Tree[] { - zvar, - make.Sequence(s.pos, Tree.EMPTY_ARRAY) - })) - }))); - } - else if (s.name == OPT) { /* p? becomes (p| ) */ - s.nextToken(); - return pN.flattenAlternative(make.Alternative(s.pos, new Tree[] { - top, - make.Sequence(s.pos, Tree.EMPTY_ARRAY)})); - } - } - while ((s.token == IDENTIFIER) && (s.name != BAR)) { - Name tokn = s.name; // for error message - top = reduceStack( - false, base, top, s.name.precedence(), s.name.isLeftAssoc()); - push(top, s.pos, s.name); - ident(); - top = simplePattern(); - if( TreeInfo.isEmptySequence( top ) ) { - syntaxError( top.pos, "2nd argument to binary op "+s.name+" may not be empty sequence pattern", false); - } - } - return reduceStack(false, base, top, 0, true); - } - - /** SimplePattern ::= varid - * | `_' - * | literal - * | StableId [ `(' [Patterns] `)' ] - * | `(' [Patterns] `)' - * | (empty word - nothing) - */ - Tree simplePattern() { - switch (s.token) { - case RPAREN: - case COMMA: - return make.Sequence(s.pos, Tree.EMPTY_ARRAY); // ((nothing)) - case IDENTIFIER: - if (s.name == BAR) { - return make.Sequence(s.pos, Tree.EMPTY_ARRAY); // ((nothing)) - } - // else fall through to case THIS - case THIS: - Tree t = stableId(); - while (s.token == LPAREN) { - Tree[] ts = Tree.EMPTY_ARRAY; - accept(LPAREN); - if (s.token != RPAREN) - ts = patterns(); - accept(RPAREN); - t = make.Apply(s.pos, convertToTypeId(t), ts); - } - return t; - case USCORE: - return make.Ident(s.skipToken(), Names.PATTERN_WILDCARD); - case CHARLIT: - case INTLIT: - case LONGLIT: - case FLOATLIT: - case DOUBLELIT: - case STRINGLIT: - case SYMBOLLIT: - case TRUE: - case FALSE: - case NULL: - return literal(true); - case LPAREN: - int p = s.pos; - s.nextToken(); - Tree[] ts = Tree.EMPTY_ARRAY; - if( s.token!= RPAREN ) - ts = patterns(); - Tree t = null; - if ((ts.length == 1)&&!( ts[0] instanceof Tree.Alternative )) { - t = ts[0]; - } else { - t = pN.flattenSequence(make.Sequence(s.pos, ts)); - t = pN.elimSequence(t); - } - accept(RPAREN); - return t; - default: - return syntaxError("illegal start of pattern", true); - } - } - -////////// MODIFIERS //////////////////////////////////////////////////////////// - - /** Modifiers ::= {Modifier} - * Modifier ::= final - * | private - * | protected - * | override - * | abstract - */ - int modifiers() { - pushComment(); - int mods = 0; - while (true) { - int mod; - switch (s.token) { - case ABSTRACT: - mod = Modifiers.ABSTRACT; - break; - case FINAL: - mod = Modifiers.FINAL; - break; - case SEALED: - mod = Modifiers.SEALED; - break; - case PRIVATE: - mod = Modifiers.PRIVATE; - break; - case PROTECTED: - mod = Modifiers.PROTECTED; - break; - case OVERRIDE: - mod = Modifiers.OVERRIDE; - break; - default: - return mods; - } - if ((mods & mod) != 0) - syntaxError(s.pos, "repeated modifier", false); - mods |= mod; - s.nextToken(); - } - } - - /** LocalModifiers ::= {LocalModifier} - * LocalModifier ::= final - * | private - */ - int localClassModifiers() { - int mods = 0; - while (true) { - int mod; - switch (s.token) { - case ABSTRACT: - mod = Modifiers.ABSTRACT; - break; - case FINAL: - mod = Modifiers.FINAL; - break; - case SEALED: - mod = Modifiers.SEALED; - break; - default: - return mods; - } - if ((mods & mod) != 0) - syntaxError(s.pos, "repeated modifier", false); - mods |= mod; - s.nextToken(); - } - } - -//////// PARAMETERS ////////////////////////////////////////////////////////// - - /** ParamClauses ::= {ParamClause} - */ - ValDef[][] paramClauses() { - ArrayList ts = new ArrayList(); - while (s.token == LPAREN) - ts.add(paramClause()); - return (ValDef[][])ts.toArray(new ValDef[ts.size()][]); - } - - /** ParamClauseOpt ::= [ParamClause] - */ - ValDef[][] paramClauseOpt() { - return (s.token == LPAREN) ? new ValDef[][]{paramClause()} - : Tree.ValDef_EMPTY_ARRAY_ARRAY; - } - - /** ParamClause ::= `(' [Param {`,' Param}] `)' - */ - ValDef[] paramClause() { - int pos = accept(LPAREN); - TreeList params = new TreeList(); - if (s.token != RPAREN) { - params.append(param()); - while (s.token == COMMA) { - s.nextToken(); - params.append(param()); - } - } - accept(RPAREN); - return (ValDef[])params.copyTo(new ValDef[params.length()]); - } - - /** Param ::= [def] Id `:' Type [`*'] - */ - ValDef param() { - int pos = s.pos; - int mods = Modifiers.PARAM; - if (s.token == DEF) { - mods |= Modifiers.DEF; - s.nextToken(); - } - Name name = ident(); - accept(COLON); - Tree tp = type(); - if (s.token == IDENTIFIER && s.name == STAR) { - s.nextToken(); - mods |= Modifiers.REPEATED; - tp = make.AppliedType(tp.pos, - scalaDot(tp.pos, Names.Seq.toTypeName()), - new Tree[]{tp}); - } - return (ValDef)make.ValDef(pos, mods, name, tp, Tree.Empty); - } - - /** TypeParamClauseOpt ::= [`[' TypeParam {`,' TypeParam} `]'] - * FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]'] - */ - AbsTypeDef[] typeParamClauseOpt(boolean variant) { - TreeList params = new TreeList(); - if (s.token == LBRACKET) { - s.nextToken(); - params.append(typeParam(variant)); - while (s.token == COMMA) { - s.nextToken(); - params.append(typeParam(variant)); - } - accept(RBRACKET); - } - return (AbsTypeDef[])params.copyTo(new AbsTypeDef[params.length()]); - } - - /** TypeParam ::= [`+' | `-'] FunTypeParam - * FunTypeParam ::= Id TypeBounds - */ - Tree typeParam(boolean variant) { - int mods = Modifiers.PARAM; - if (variant && s.token == IDENTIFIER) { - if (s.name == PLUS) { - s.nextToken(); - mods |= Modifiers.COVARIANT; - } else if (s.name == MINUS) { -// syntaxError( -// "contravariant type parameters not yet supported", false); - s.nextToken(); - mods |= Modifiers.CONTRAVARIANT; - } - } - return typeBounds(s.pos, mods, ident()); - } - - /** TypeBounds ::= [`>:' Type] [`<:' Type] - */ - Tree typeBounds(int pos, int mods, Name name) { - Tree lobound; - Tree hibound; - if (s.token == SUPERTYPE) { - s.nextToken(); - lobound = type(); - } else { - lobound = scalaDot(pos, Names.All.toTypeName()); - } - if (s.token == SUBTYPE) { - s.nextToken(); - hibound = type(); - } else { - hibound = scalaDot(pos, Names.Any.toTypeName()); - } - return make.AbsTypeDef(pos, mods, name.toTypeName(), hibound, lobound); - } - -//////// DEFS //////////////////////////////////////////////////////////////// - - /** Import ::= import ImportExpr {`,' ImportExpr} - */ - Tree[] importClause() { - accept(IMPORT); - TreeList ts = new TreeList(); - ts.append(importExpr()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(importExpr()); - } - return ts.toArray(); - } - - /** ImportRef ::= StableId `.' (Id | `_' | ImportSelectors) - */ - Tree importExpr() { - Tree t; - int startpos = s.pos; - int pos; - if (s.token == THIS) { - t = make.This(s.skipToken(), TypeNames.EMPTY); - t = make.Select(accept(DOT), t, ident()); - pos = accept(DOT); - } else { - Ident i = make.Ident(s.pos, ident()); - pos = accept(DOT); - if (s.token == THIS) { - s.nextToken(); - t = make.This(i.pos, i.name.toTypeName()); - t = make.Select(accept(DOT), t, ident()); - pos = accept(DOT); - } else { - t = i; - } - } - while (true) { - if (s.token == USCORE) { - s.nextToken(); - return make.Import(startpos, t, new Name[]{Names.IMPORT_WILDCARD}); - } else if (s.token == LBRACE) { - return make.Import(startpos, t, importSelectors()); - } else { - Name name = ident(); - if (s.token == DOT) { - t = make.Select(pos, t, name); - pos = accept(DOT); - } else { - /* - if (name == Names.ASTERISK) - s.unit.warning( - pos, "this imports only the identifier `*';\nuse `import xyz._' to import all members of `xyz'."); - */ - return make.Import(startpos, t, new Name[]{name, name}); - } - } - } - } - - /** ImportSelectors ::= `{' {ImportSelector `,'} (ImportSelector | `_') `}' - */ - Name[] importSelectors() { - LinkedList/*<Name>*/ names = new LinkedList(); - accept(LBRACE); - boolean isLast = importSelector(names); - while (!isLast && s.token == COMMA) { - s.nextToken(); - isLast = importSelector(names); - } - accept(RBRACE); - return (Name[])names.toArray(new Name[]{}); - } - - /** ImportSelector ::= Id [`=>' Id | `=>' `_'] - */ - boolean importSelector(LinkedList/*<Name>*/ names) { - if (s.token == USCORE) { - s.nextToken(); - names.add(Names.IMPORT_WILDCARD); - return true; - } else { - Name name = ident(); - names.add(name); - if (s.token == ARROW) { - s.nextToken(); - if (s.token == USCORE) { - s.nextToken(); - names.add(Names.IMPORT_WILDCARD); - } else { - names.add(ident()); - } - } else { - names.add(name); - } - return false; - } - } - - /** Def ::= val PatDef {`,' PatDef} - * | var VarDef {`,' VarDef} - * | def FunDef {`,' FunDef} - * | type TypeDef {`,' TypeDef} - * | ClsDef - * Dcl ::= val ValDcl {`,' ValDcl} - * | var ValDcl {`,' ValDcl} - * | def FunDcl {`,' FunDcl} - * | type TypeDcl {`,' TypeDcl} - */ - Tree[] defOrDcl(int mods) { - TreeList ts = new TreeList(); - switch (s.token) { - case VAL: - do { - s.nextToken(); - ts.append(popComment(patDefOrDcl(mods))); - } while (s.token == COMMA); - return ts.toArray(); - case VAR: - do { - s.nextToken(); - ts.append(popComment(varDefOrDcl(mods))); - } while (s.token == COMMA); - return ts.toArray(); - case DEF: - do { - s.nextToken(); - ts.append(popComment(funDefOrDcl(mods))); - } while (s.token == COMMA); - return ts.toArray(); - case TYPE: - do { - s.nextToken(); - ts.append(popComment(typeDefOrDcl(mods))); - } while (s.token == COMMA); - return ts.toArray(); - default: - return clsDef(mods); - } - } - - /** ClsDef ::= ([case] class | trait) ClassDef {`,' ClassDef} - * | [case] object ObjectDef {`,' ObjectDef} - */ - Tree[] clsDef(int mods) { - TreeList ts = new TreeList(); - switch (s.token) { - case CLASS: - case CASECLASS: - case TRAIT: - if (s.token == CASECLASS) mods |= Modifiers.CASE; - else if (s.token == TRAIT) mods |= Modifiers.TRAIT | Modifiers.ABSTRACT; - do { - s.nextToken(); - ts.append(classDef(mods)); - } while (s.token == COMMA); - return ts.toArray(); - case OBJECT: - case CASEOBJECT: - if (s.token == CASEOBJECT) mods |= Modifiers.CASE; - do { - s.nextToken(); - ts.append(objectDef(mods)); - } while (s.token == COMMA); - return ts.toArray(); - default: - return new Tree[]{syntaxError("illegal start of definition", true)}; - } - } - - /** PatDef ::= Pattern2 [`:' Type] `=' Expr - * ValDcl ::= Id `:' Type - */ - Tree patDefOrDcl(int mods) { - int pos = s.pos; - Tree pat = pattern2(); - Tree tp = (s.token == COLON) ? typedOpt() : Tree.Empty; - switch (pat) { - case Ident(Name name): - if (tp == Tree.Empty || s.token == EQUALS) - return make.ValDef(pos, mods, name, tp, equalsExpr()); - else - return make.ValDef(pos, mods | Modifiers.DEFERRED, name, tp, Tree.Empty); - default: - return make.PatDef(pos, mods, pat, equalsExpr()); - } - } - - /** VarDef ::= Id [`:' Type] `=' Expr - * | Id `:' Type `=' `_' - * VarDcl ::= Id `:' Type - */ - Tree varDefOrDcl(int mods) { - int pos = s.pos; - Name name = ident(); - Tree type = typedOpt(); - if (type == Tree.Empty || s.token == EQUALS) { - accept(EQUALS); - Tree rhs; - if (type != Tree.Empty && s.token == USCORE) { - rhs = Tree.Empty; - s.nextToken(); - } else { - rhs = expr(); - } - return make.ValDef(pos, mods | Modifiers.MUTABLE, name, type, rhs); - } else { - return make.ValDef(pos, mods | Modifiers.MUTABLE | Modifiers.DEFERRED, - name, type, Tree.Empty); - } - } - - /** FunDef ::= Id [FunTypeParamClause] {ParamClauses} [`:' Type] `=' Expr - * | this ParamClause `=' ConstrExpr - * FunDcl ::= Id [FunTypeParamClause] {ParamClauses} `:' Type - */ - Tree funDefOrDcl(int mods) { - int pos = s.pos; - if (s.token == THIS) { - s.nextToken(); - ValDef[][] vparams = new ValDef[][]{paramClause()}; - accept(EQUALS); - return make.DefDef( - pos, mods, Names.CONSTRUCTOR, - Tree.AbsTypeDef_EMPTY_ARRAY, vparams, Tree.Empty, - constrExpr()); - } else { - Name name = ident(); - AbsTypeDef[] tparams = typeParamClauseOpt(false); - ValDef[][] vparams = paramClauses(); - Tree restype = typedOpt(); - if (s.token == EQUALS || restype == Tree.Empty) - return make.DefDef(pos, mods, name, tparams, vparams, - restype, equalsExpr()); - else - return make.DefDef(pos, mods | Modifiers.DEFERRED, name, - tparams, vparams, restype, Tree.Empty); - } - } - - /** ConstrExpr ::= SelfInvocation - * | `{' SelfInvocation {`;' BlockStat} `}' - * SelfInvocation ::= this ArgumentExpr - */ - Tree constrExpr() { - if (s.token == LBRACE) { - int pos = s.skipToken(); - TreeList statlist = new TreeList(); - statlist.append(selfInvocation()); - Tree[] stats; - if (s.token == SEMI) { - s.nextToken(); - stats = blockStatSeq(statlist); - } else { - stats = statlist.toArray(); - } - accept(RBRACE); - return block(pos, stats); - } else { - return selfInvocation(); - } - } - - /** SelfInvocation ::= this ArgumentExprs - */ - Tree selfInvocation() { - int pos = s.pos; - accept(THIS); - return make.Apply( - s.pos, make.Ident(pos, Names.CONSTRUCTOR), argumentExprs()); - } - - /** TypeDef ::= Id `=' Type - * TypeDcl ::= Id TypeBounds - */ - Tree typeDefOrDcl(int mods) { - int pos = s.pos; - Name name = ident().toTypeName(); - switch (s.token) { - case LBRACKET: - AbsTypeDef[] tparams = typeParamClauseOpt(true); - accept(EQUALS); - return make.AliasTypeDef(pos, mods, name, tparams, type()); - case EQUALS: - s.nextToken(); - return make.AliasTypeDef(pos, mods, name, Tree.AbsTypeDef_EMPTY_ARRAY, type()); - case SUPERTYPE: - case SUBTYPE: - case SEMI: - case COMMA: - case RBRACE: - return typeBounds(pos, mods | Modifiers.DEFERRED, name); - default: - return syntaxError("`=', `>:', or `<:' expected", true); - } - } - - /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate - */ - Tree classDef(int mods) { - int pos = s.pos; - Name clazzname = ident().toTypeName(); - AbsTypeDef[] tparams = typeParamClauseOpt(true); - ValDef[][] params = paramClauseOpt(); - TreeList result = new TreeList(); - return popComment(make.ClassDef(pos, mods, clazzname, tparams, params, - simpleTypedOpt(), classTemplate())); - } - - /** ObjectDef ::= Id [`:' SimpleType] ClassTemplate - */ - Tree objectDef(int mods) { - return popComment(make.ModuleDef( - s.pos, mods, ident(), simpleTypedOpt(), classTemplate())); - } - - /** ClassTemplate ::= [`extends' Constr] {`with' Constr} [TemplateBody] - */ - Template classTemplate() { - int pos = s.pos; - TreeList parents = new TreeList(); - if (s.token == EXTENDS) { - s.nextToken(); - parents.append(constr()); - } else { - parents.append(scalaAnyRefConstr(pos)); - } - parents.append(scalaObjectConstr(pos)); - if (s.token == WITH) { - s.nextToken(); - return template(parents); - } else if (s.token == LBRACE) { - return (Template)make.Template( - pos, parents.toArray(), templateBody()); - } else { - if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE)) - syntaxError("`extends' or `{' expected", true); - return (Template)make.Template( - pos, parents.toArray(), Tree.EMPTY_ARRAY); - } - } - -////////// TEMPLATES //////////////////////////////////////////////////////////// - - - /** Template ::= Constr {`with' Constr} [TemplateBody] - */ - Template template() { - return template(new TreeList()); - } - - Template template(TreeList parents) { - int pos = s.pos; - parents.append(constr()); - while (s.token == WITH) { - s.nextToken(); - parents.append(constr()); - } - Tree[] stats = (s.token == LBRACE) ? templateBody() : Tree.EMPTY_ARRAY; - return (Template)make.Template(pos, parents.toArray(), stats); - } - - /** Constr ::= StableId [TypeArgs] [`(' [Exprs] `)'] - */ - Tree constr() { - Tree t = convertToConstr(stableId()); - if (s.token == LBRACKET) - t = make.AppliedType(s.pos, t, typeArgs()); - if (s.token == LPAREN) - t = make.Apply(s.pos, t, argumentExprs()); - return applyConstr(t); - } - - /** TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}' - */ - Tree[] templateBody() { - accept(LBRACE); - Tree[] body = templateStatSeq(); - if (body.length == 0) - body = new Tree[]{Tree.Empty}; - accept(RBRACE); - return body; - } - - /** Refinement ::= `{' [RefineStat {`;' RefineStat}] `}' - */ - Tree[] refinement() { - accept(LBRACE); - Tree[] body = refineStatSeq(); - accept(RBRACE); - return body; - } - -/////// STATSEQS ////////////////////////////////////////////////////////////// - - /** Packaging ::= package QualId `{' TopStatSeq `}' - */ - Tree packaging() { - int pos = accept(PACKAGE); - Tree pkg = qualId(); - accept(LBRACE); - Tree[] stats = topStatSeq(); - accept(RBRACE); - return makePackaging(pos, pkg, stats); - } - - /** TopStatSeq ::= [TopStat {`;' TopStat}] - * TopStat ::= Modifiers ClsDef - * | Packaging - * | Import - * | - */ - Tree[] topStatSeq() { - TreeList stats = new TreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (s.token == PACKAGE) { - stats.append(packaging()); - } else if (s.token == IMPORT) { - stats.append(importClause()); - } else if (s.token == CLASS || - s.token == CASECLASS || - s.token == TRAIT || - s.token == OBJECT || - s.token == CASEOBJECT || - isModifier()) { - stats.append(clsDef(modifiers())); - } else if (s.token != SEMI) { - syntaxError("illegal start of class or object definition", true); - } - if (s.token != RBRACE && s.token != EOF) accept(SEMI); - } - return stats.toArray(); - } - - /** TemplateStatSeq ::= TemplateStat {`;' TemplateStat} - * TemplateStat ::= Import - * | Modifiers Def - * | Modifiers Dcl - * | Expr - * | - */ - Tree[] templateStatSeq() { - TreeList stats = new TreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (s.token == IMPORT) { - stats.append(importClause()); - } else if (isExprIntro()) { - stats.append(expr()); - } else if (isDefIntro() || isModifier()) { - stats.append(defOrDcl(modifiers())); - } else if (s.token != SEMI) { - syntaxError("illegal start of definition", true); - } - if (s.token != RBRACE) accept(SEMI); - } - return stats.toArray(); - } - - /** RefineStatSeq ::= RefineStat {`;' RefineStat} - * RefineStat ::= Dcl - * | type TypeDef {`,' TypeDef} - * | - */ - Tree[] refineStatSeq() { - TreeList stats = new TreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (isDclIntro()) { - stats.append(defOrDcl(0)); - } else if (s.token != SEMI) { - syntaxError("illegal start of declaration", true); - } - if (s.token != RBRACE) accept(SEMI); - } - return stats.toArray(); - } - - /** BlockStatSeq ::= { BlockStat `;' } [Expr] - * BlockStat ::= Import - * | Def - * | LocalModifiers ClsDef - * | Expr - * | - */ - Tree[] blockStatSeq(TreeList stats) { - while ((s.token != RBRACE) && (s.token != EOF) && (s.token != CASE)) { - if (s.token == IMPORT) { - stats.append(importClause()); - accept(SEMI); - } else if (isExprIntro()) { - stats.append(expr()); - if (s.token != RBRACE && s.token != CASE) accept(SEMI); - } else if (isDefIntro()) { - stats.append(defOrDcl(0)); - accept(SEMI); - if (s.token == RBRACE || s.token == CASE) { - stats.append(gen.mkUnitLit(s.pos)); - } - } else if (isLocalModifier()) { - stats.append(clsDef(localClassModifiers())); - accept(SEMI); - if (s.token == RBRACE || s.token == CASE) { - stats.append(gen.mkUnitLit(s.pos)); - } - } else if (s.token == SEMI) { - s.nextToken(); - } else { - syntaxError("illegal start of statement", true); - } - } - return stats.toArray(); - } - - - /** CompilationUnit ::= [ package QualId ( `;' | `{' TopStatSeq `}' ) ] TopStatSeq . - */ - Tree[] compilationUnit() { - if (s.token == PACKAGE) { - int pos = s.skipToken(); - Tree pkg = qualId(); - if (s.token == SEMI) { - s.nextToken(); - return new Tree[]{makePackaging(pos, pkg, topStatSeq())}; - } else { - TreeList stats = new TreeList(); - accept(LBRACE); - stats.append(makePackaging(pos, pkg, topStatSeq())); - accept(RBRACE); - stats.append(topStatSeq()); - return stats.toArray(); - } - } else { - return topStatSeq(); - } - } -} diff --git a/sources/scalac/ast/parser/ParserPhase.java b/sources/scalac/ast/parser/ParserPhase.java deleted file mode 100644 index 1355b3926d..0000000000 --- a/sources/scalac/ast/parser/ParserPhase.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast.parser; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.Unit; - -public class ParserPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ParserPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation units. */ - public void apply(Unit[] units) { - for (int i = 0; i < units.length; i++) { - global.start(); - units[i].body = new Parser(units[i]).parse(); - global.stop("parsed " + units[i].source); - } - } - - //######################################################################## -} diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java deleted file mode 100644 index 81e15058a1..0000000000 --- a/sources/scalac/ast/parser/Scanner.java +++ /dev/null @@ -1,867 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast.parser; - -import ch.epfl.lamp.util.Position; -import ch.epfl.lamp.util.SourceFile; - -import scalac.*; -import scalac.util.Name; - - -/** A scanner for the programming language Scala. - * - * @author Matthias Zenger, Martin Odersky - * @version 1.0 - */ -public class Scanner extends TokenData { - - /** buffer for the documentation comment - */ - public StringBuffer docBuffer = null; - - /** add the given character to the documentation buffer - */ - protected void addCharToDoc(byte ch) { - if (docBuffer != null) docBuffer.append((char) ch); - } - - /** layout & character constants - */ - public int tabinc = 8; - protected final static byte LF = SourceFile.LF; - protected final static byte FF = SourceFile.FF; - protected final static byte CR = SourceFile.CR; - protected final static byte SU = SourceFile.SU; - - /** the names of all tokens - */ - public Name[] tokenName = new Name[128]; - public int numToken = 0; - - /** keyword array; maps from name indices to tokens - */ - protected byte[] key; - protected int maxKey = 0; - - /** we need one token lookahead - */ - protected TokenData next = new TokenData(); - protected TokenData prev = new TokenData(); - - /** the first character position after the previous token - */ - public int lastpos = 0; - - /** the last error position - */ - public int errpos = -1; - - /** the input buffer: - */ - protected byte[] buf; - protected int bp; - - /** the current character - */ - protected byte ch; - - /** the line and column position of the current character - */ - public int cline; - public int ccol; - - /** a buffer for character and string literals - */ - protected byte[] lit = new byte[64]; - protected int litlen; - - /** the compilation unit - */ - public Unit unit; - - - /** Construct a scanner from a file input stream. - */ - public Scanner(Unit unit) { - this.unit = unit; - buf = unit.source.bytes(); - cline = 1; - bp = -1; - ccol = 0; - nextch(); - token = EMPTY; - init(); - nextToken(); - } - - /** only used to determine keywords. used in dtd2scala tool */ - public Scanner() { - initKeywords(); - } - - private void nextch() { - ch = buf[++bp]; ccol++; - } - - /** read next token and return last position - */ - public int skipToken() { - int p = pos; - nextToken(); - return p; - } - - public void nextToken() { - if (token == RBRACE) { - int prevpos = pos; - fetchToken(); - switch (token) { - case ELSE: case EXTENDS: case WITH: - case YIELD: case CATCH: case FINALLY: - case COMMA: case SEMI: case DOT: - case COLON: case EQUALS: case ARROW: - case LARROW: case SUBTYPE: case SUPERTYPE: - case HASH: case AT: - case RPAREN: case RBRACKET: case RBRACE: - break; - default: - if (token == EOF || - ((pos >>> Position.COLUMN_BITS) > - (prevpos >>> Position.COLUMN_BITS))) { - next.copyFrom(this); - this.token = SEMI; - this.pos = prevpos; - } - } - } else { - if (next.token == EMPTY) { - fetchToken(); - } else { - copyFrom(next); - next.token = EMPTY; - } - if (token == CASE) { - prev.copyFrom(this); - fetchToken(); - if (token == CLASS) { - token = CASECLASS; - } else if (token == OBJECT) { - token = CASEOBJECT; - } else { - next.copyFrom(this); - this.copyFrom(prev); - } - } else if (token == SEMI) { - prev.copyFrom(this); - fetchToken(); - if (token != ELSE) { - next.copyFrom(this); - this.copyFrom(prev); - } - } - } - //System.out.println("<" + token2string(token) + ">");//DEBUG - } - - /** read next token - */ - public void fetchToken() { - if (token == EOF) return; - lastpos = Position.encode(cline, ccol); - int index = bp; - while(true) { - switch (ch) { - case ' ': - nextch(); - break; - case '\t': - ccol = ((ccol - 1) / tabinc * tabinc) + tabinc; - nextch(); - break; - case CR: - cline++; - ccol = 0; - nextch(); - if (ch == LF) { - ccol = 0; - nextch(); - } - break; - case LF: - case FF: - cline++; - ccol = 0; - nextch(); - break; - default: - pos = Position.encode(cline, ccol); - index = bp; - switch (ch) { - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': case '$': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - nextch(); - getIdentRest(index); - return; - case '~': case '!': case '@': case '#': case '%': - case '^': case '*': case '+': case '-': case '<': - case '>': case '?': case ':': case '\\': - case '=': case '&': case '|': - nextch(); - getOperatorRest(index); - return; - case '/': - nextch(); - if (!skipComment()) { - getOperatorRest(index); - return; - } - break; - case '_': - nextch(); - getIdentRest(index); - return; - case '0': - nextch(); - if (ch == 'x' || ch == 'X') { - nextch(); - getNumber(index + 2, 16); - } else - getNumber(index, 8); - return; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - getNumber(index, 10); - return; - case '`': - getStringLit('`'); - token = IDENTIFIER; - return; - case '\"': - getStringLit('\"'); - return; - case '\'': - nextch(); - litlen = 0; - switch (ch) { - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': case '$': case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - index = bp; - putch(ch); - nextch(); - if (ch != '\'') { - getIdentRest(index); - token = SYMBOLLIT; - return; - } - break; - default: - getlitch(); - } - if (ch == '\'') { - nextch(); - token = CHARLIT; - byte[] ascii = new byte[litlen * 2]; - int alen = SourceRepresentation.source2ascii(lit, 0, litlen, ascii); - if (alen > 0) - intVal = SourceRepresentation.ascii2string(ascii, 0, alen).charAt(0); - else - intVal = 0; - } else - syntaxError("unclosed character literal"); - return; - case '.': - nextch(); - if (('0' <= ch) && (ch <= '9')) getFraction(index); - else token = DOT; - return; - case ';': - nextch(); token = SEMI; - return; - case ',': - nextch(); token = COMMA; - return; - case '(': - nextch(); token = LPAREN; - return; - case '{': - nextch(); token = LBRACE; - return; - case ')': - nextch(); token = RPAREN; - return; - case '}': - nextch(); token = RBRACE; - return; - case '[': - nextch(); token = LBRACKET; - return; - case ']': - nextch(); token = RBRACKET; - return; - case SU: - token = EOF; - return; - default: - nextch(); - syntaxError("illegal character"); - return; - } - } - } - } - - private boolean skipComment() { - if (ch == '/') { - do { - nextch(); - } while ((ch != CR) && (ch != LF) && (ch != SU)); - return true; - } else if (ch == '*') { - docBuffer = null; - int openComments = 1; - nextch(); - if (ch == '*') { - docBuffer = new StringBuffer("/**"); - } - while (openComments > 0) { - do { - do { - if (ch == CR) { - cline++; - ccol = 0; - nextch(); addCharToDoc(ch); - if (ch == LF) { - ccol = 0; - nextch(); addCharToDoc(ch); - } - } else if (ch == LF) { - cline++; - ccol = 0; - nextch(); addCharToDoc(ch); - } - else if (ch == '\t') { - ccol = ((ccol - 1) / tabinc * tabinc) + tabinc; - nextch(); addCharToDoc(ch); - } else if (ch == '/') { - nextch(); addCharToDoc(ch); - if (ch == '*') { - nextch(); addCharToDoc(ch); - openComments++; - } - } else { - nextch(); addCharToDoc(ch); - } - } while ((ch != '*') && (ch != SU)); - while (ch == '*') { - nextch(); addCharToDoc(ch); - } - } while (ch != '/' && ch != SU); - if (ch == '/') { - nextch(); - openComments--; - } else { - syntaxError("unclosed comment"); - return true; - } - } - return true; - } else { - return false; - } - } - - private void getIdentRest(int index) { - while (true) { - switch (ch) { - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': case '$': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - nextch(); - break; - case '_': - nextch(); - getIdentOrOperatorRest(index); - return; - default: - treatIdent(index, bp); - return; - } - } - } - - private void getOperatorRest(int index) { - while (true) { - switch (ch) { - case '~': case '!': case '@': case '#': case '%': - case '^': case '*': case '+': case '-': case '<': - case '>': case '?': case ':': case '\\': - case '=': case '&': case '|': - nextch(); - break; - case '/': - int lastbp = bp; - nextch(); - if (skipComment()) { - treatIdent(index, lastbp); - return; - } else { - break; - } - /* case '_': - nextch(); - getIdentOrOperatorRest(index); - return; */ - default: - treatIdent(index, bp); - return; - } - } - } - - private void getIdentOrOperatorRest(int index) { - switch (ch) { - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': case '$': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - getIdentRest(index); - return; - case '~': case '!': case '@': case '#': case '%': - case '^': case '*': case '+': case '-': case '<': - case '>': case '?': case ':': case '\\': - case '=': case '&': case '|': - case '/': - getOperatorRest(index); - return; - case '_': - nextch(); - getIdentOrOperatorRest(index); - return; - default: - treatIdent(index, bp); - return; - } - } - - private void getStringLit(char delimiter) { - nextch(); - litlen = 0; - while (ch != delimiter && ch != CR && ch != LF && ch != SU) - getlitch(); - if (ch == delimiter) { - token = STRINGLIT; - name = Name.fromSource(lit, 0, litlen); - nextch(); - } - else - syntaxError("unclosed character literal"); - } - - /** returns true if argument corresponds to a keyword. - * Used in dtd2scala tool. - */ - public boolean isKeyword(String str) { - Name name = Name.fromString(str); - return (name.index <= maxKey); - } - - void treatIdent(int start, int end) { - name = Name.fromAscii(buf, start, end - start); - if (name.index <= maxKey) { - token = key[name.index]; - } - else - token = IDENTIFIER; - } - - /** generate an error at the given position - */ - void syntaxError(int pos, String msg) { - unit.error(pos, msg); - token = ERROR; - errpos = pos; - } - - /** generate an error at the current token position - */ - void syntaxError(String msg) { - syntaxError(pos, msg); - } - - /** append characteter to "lit" buffer - */ - protected void putch(byte c) { - if (litlen == lit.length) { - byte[] newlit = new byte[lit.length * 2]; - System.arraycopy(lit, 0, newlit, 0, lit.length); - lit = newlit; - } - lit[litlen++] = c; - } - - /** return true iff next 6 characters are a valid unicode sequence: - */ - protected boolean isUnicode() { - return - (bp + 6) < buf.length && - (buf[bp] == '\\') && - (buf[bp+1] == 'u') && - (SourceRepresentation.digit2int(buf[bp+2], 16) >= 0) && - (SourceRepresentation.digit2int(buf[bp+3], 16) >= 0) && - (SourceRepresentation.digit2int(buf[bp+4], 16) >= 0) && - (SourceRepresentation.digit2int(buf[bp+5], 16) >= 0); - } - - /** read next character in character or string literal: - */ - protected void getlitch() { - if (ch == '\\') { - if (isUnicode()) { - putch(ch); nextch(); - putch(ch); nextch(); - putch(ch); nextch(); - putch(ch); nextch(); - putch(ch); nextch(); - putch(ch); nextch(); - } else { - nextch(); - if ('0' <= ch && ch <= '7') { - byte leadch = ch; - int oct = SourceRepresentation.digit2int(ch, 8); - nextch(); - if ('0' <= ch && ch <= '7') { - oct = oct * 8 + SourceRepresentation.digit2int(ch, 8); - nextch(); - if (leadch <= '3' && '0' <= ch && ch <= '7') { - oct = oct * 8 + SourceRepresentation.digit2int(ch, 8); - nextch(); - } - } - putch((byte)oct); - } else if (ch != SU) { - switch (ch) { - case 'b': case 't': case 'n': - case 'f': case 'r': case '\"': - case '\'': case '\\': - putch((byte)'\\'); - putch(ch); - break; - default: - syntaxError(Position.encode(cline, ccol) - 1, "invalid escape character"); - putch(ch); - } - nextch(); - } - } - } else if (ch != SU) { - putch(ch); - nextch(); - } - } - - /** read fractional part of floating point number; - * Then floatVal := buf[index..], converted to a floating point number. - */ - protected void getFraction(int index) { - while (SourceRepresentation.digit2int(ch, 10) >= 0) { - nextch(); - } - token = DOUBLELIT; - if ((ch == 'e') || (ch == 'E')) { - nextch(); - if ((ch == '+') || (ch == '-')) { - byte sign = ch; - nextch(); - if (('0' > ch) || (ch > '9')) { - ch = sign; - bp--; - ccol--; - } - } - while (SourceRepresentation.digit2int(ch, 10) >= 0) { - nextch(); - } - } - double limit = Double.MAX_VALUE; - if ((ch == 'd') || (ch == 'D')) { - nextch(); - } else if ((ch == 'f') || (ch == 'F')) { - token = FLOATLIT; - limit = Float.MAX_VALUE; - nextch(); - } - try { - floatVal = Double.valueOf(new String(buf, index, bp - index)).doubleValue(); - if (floatVal > limit) - syntaxError("floating point number too large"); - } catch (NumberFormatException e) { - syntaxError("malformed floating point number"); - } - } - - /** intVal := buf[index..index+len-1], converted to an integer number. - * base = the base of the number; one of 8, 10, 16. - * max = the maximal number before an overflow. - */ - protected void makeInt (int index, int len, int base, long max) { - intVal = 0; - int divider = (base == 10 ? 1 : 2); - for (int i = 0; i < len; i++) { - int d = SourceRepresentation.digit2int(buf[index + i], base); - if (d < 0) { - syntaxError("malformed integer number"); - return; - } - if (intVal < 0 || - max / (base / divider) < intVal || - max - (d / divider) < (intVal * (base / divider) - 0)) { - syntaxError("integer number too large"); - return; - } - intVal = intVal * base + d; - } - } - - /** read a number, - * and convert buf[index..], setting either intVal or floatVal. - * base = the base of the number; one of 8, 10, 16. - */ - protected void getNumber(int index, int base) { - while (SourceRepresentation.digit2int(ch, base == 8 ? 10 : base) >= 0) { - nextch(); - } - if (base <= 10 && ch == '.') { - nextch(); - if ((ch >= '0') && (ch <= '9')) - getFraction(index); - else { - ch = buf[--bp]; ccol--; - makeInt(index, bp - index, base, Integer.MAX_VALUE); - intVal = (int)intVal; - token = INTLIT; - } - } else if (base <= 10 && - (ch == 'e' || ch == 'E' || - ch == 'f' || ch == 'F' || - ch == 'd' || ch == 'D')) - getFraction(index); - else { - if (ch == 'l' || ch == 'L') { - makeInt(index, bp - index, base, Long.MAX_VALUE); - nextch(); - token = LONGLIT; - } else { - makeInt(index, bp - index, base, Integer.MAX_VALUE); - intVal = (int)intVal; - token = INTLIT; - } - } - } - - public int name2token(Name name) { - if (name.index <= maxKey) - return key[name.index]; - else - return IDENTIFIER; - } - - public String token2string(int token) { - switch (token) { - case IDENTIFIER: - return "identifier"; - case CHARLIT: - return "character literal"; - case INTLIT: - return "integer literal"; - case LONGLIT: - return "long literal"; - case FLOATLIT: - return "float literal"; - case DOUBLELIT: - return "double literal"; - case STRINGLIT: - return "string literal"; - case SYMBOLLIT: - return "symbol literal"; - case LPAREN: - return "'('"; - case RPAREN: - return "')'"; - case LBRACE: - return "'{'"; - case RBRACE: - return "'}'"; - case LBRACKET: - return "'['"; - case RBRACKET: - return "']'"; - case EOF: - return "eof"; - case ERROR: - return "something"; - case SEMI: - return "';'"; - case COMMA: - return "','"; - case CASECLASS: - return "case class"; - case CASEOBJECT: - return "case object"; - default: - try { - return "'" + tokenName[token].toString() + "'"; - } catch (ArrayIndexOutOfBoundsException e) { - return "'<" + token + ">'"; - } catch (NullPointerException e) { - return "'<(" + token + ")>'"; - } - } - } - - public String toString() { - switch (token) { - case IDENTIFIER: - return "id(" + name + ")"; - case CHARLIT: - return "char(" + intVal + ")"; - case INTLIT: - return "int(" + intVal + ")"; - case LONGLIT: - return "long(" + intVal + ")"; - case FLOATLIT: - return "float(" + floatVal + ")"; - case DOUBLELIT: - return "double(" + floatVal + ")"; - case STRINGLIT: - return "string(" + name + ")"; - case SEMI: - return ";"; - case COMMA: - return ","; - default: - return token2string(token); - } - } - - protected void enterKeyword(String s, int tokenId) { - while (tokenId > tokenName.length) { - Name[] newTokName = new Name[tokenName.length * 2]; - System.arraycopy(tokenName, 0, newTokName, 0, newTokName.length); - tokenName = newTokName; - } - Name n = Name.fromString(s); - tokenName[tokenId] = n; - if (n.index > maxKey) - maxKey = n.index; - if (tokenId >= numToken) - numToken = tokenId + 1; - } - - protected void init() { - initKeywords(); - key = new byte[maxKey+1]; - for (int i = 0; i <= maxKey; i++) - key[i] = IDENTIFIER; - for (byte j = 0; j < numToken; j++) - if (tokenName[j] != null) - key[tokenName[j].index] = j; - } - - protected void initKeywords() { - enterKeyword("abstract", ABSTRACT); - enterKeyword("case", CASE); - enterKeyword("class", CLASS); - enterKeyword("catch", CATCH); - enterKeyword("def", DEF); - enterKeyword("do", DO); - enterKeyword("else", ELSE); - enterKeyword("extends", EXTENDS); - enterKeyword("false", FALSE); - enterKeyword("final", FINAL); - enterKeyword("finally", FINALLY); - enterKeyword("for", FOR); - enterKeyword("if", IF); - enterKeyword("import", IMPORT); - enterKeyword("new", NEW); - enterKeyword("null", NULL); - enterKeyword("object", OBJECT); - enterKeyword("override", OVERRIDE); - enterKeyword("package", PACKAGE); - enterKeyword("private", PRIVATE); - enterKeyword("protected", PROTECTED); - enterKeyword("return", RETURN); - enterKeyword("sealed", SEALED); - enterKeyword("super", SUPER); - enterKeyword("this", THIS); - enterKeyword("throw", THROW); - enterKeyword("trait", TRAIT); - enterKeyword("true", TRUE); - enterKeyword("try", TRY); - enterKeyword("type", TYPE); - enterKeyword("val", VAL); - enterKeyword("var", VAR); - enterKeyword("with", WITH); - enterKeyword("while", WHILE); - enterKeyword("yield", YIELD); - enterKeyword(".", DOT); - enterKeyword("_", USCORE); - enterKeyword(":", COLON); - enterKeyword("=", EQUALS); - enterKeyword("=>", ARROW); - enterKeyword("<-", LARROW); - enterKeyword("<:", SUBTYPE); - enterKeyword(">:", SUPERTYPE); - enterKeyword("#", HASH); - enterKeyword("@", AT); - } -} - - diff --git a/sources/scalac/ast/parser/TokenData.java b/sources/scalac/ast/parser/TokenData.java deleted file mode 100644 index d6bcac6c1c..0000000000 --- a/sources/scalac/ast/parser/TokenData.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast.parser; - -import scalac.util.Name; - -/** A class for representing a token's data. - * - * @author Matthias Zenger - * @version 1.0 - */ -public class TokenData implements Tokens { - - /** the next token - */ - public int token = EMPTY; - - /** the token's position. pos = line << Position.LINESHIFT + col - */ - public int pos = 0; - - /** the name of an identifier or token - */ - public Name name; - - /** the value of a number - */ - public long intVal; - public double floatVal; - - public void copyFrom(TokenData td) { - this.token = td.token; - this.pos = td.pos; - this.name = td.name; - this.intVal = td.intVal; - this.floatVal = td.floatVal; - } -} diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java deleted file mode 100644 index 485ce6a465..0000000000 --- a/sources/scalac/ast/parser/Tokens.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast.parser; - -public interface Tokens { - byte EMPTY = -3, - UNDEF = -2, - ERROR = -1, - EOF = 0, - - /* literals */ - CHARLIT = 1, - INTLIT = 2, - LONGLIT = 3, - FLOATLIT = 4, - DOUBLELIT = 5, - STRINGLIT = 6, - SYMBOLLIT = 7, - - /* identifier */ - IDENTIFIER = 10, - - /* keywords */ - IF = 20, - FOR = 21, - ELSE = 22, - THIS = 23, - NULL = 24, - NEW = 25, - WITH = 26, - SUPER = 27, - CASE = 28, - CASECLASS = 29, - CASEOBJECT = 30, - VAL = 31, - ABSTRACT = 32, - FINAL = 33, - PRIVATE = 34, - PROTECTED = 35, - OVERRIDE = 36, - VAR = 37, - DEF = 38, - TYPE = 39, - EXTENDS = 40, - TRUE = 41, - FALSE = 42, - OBJECT = 43, - CLASS = 44, - - IMPORT = 46, - PACKAGE = 47, - YIELD = 48, - DO = 49, - TRAIT = 50, - SEALED = 51, - THROW = 52, - TRY = 53, - CATCH = 54, - FINALLY = 55, - WHILE = 56, - RETURN = 57, - - /* special symbols */ - COMMA = 61, - SEMI = 62, - DOT = 63, - USCORE = 64, - COLON = 65, - EQUALS = 66, - LARROW = 67, - ARROW = 68, - SUBTYPE = 69, - SUPERTYPE = 70, - HASH = 71, - AT = 72, - - /* parenthesis */ - LPAREN = 90, - RPAREN = 91, - LBRACKET = 92, - RBRACKET = 93, - LBRACE = 94, - RBRACE = 95; -} - - diff --git a/sources/scalac/ast/printer/HTMLTreePrinter.java b/sources/scalac/ast/printer/HTMLTreePrinter.java deleted file mode 100644 index a4e6bb4f18..0000000000 --- a/sources/scalac/ast/printer/HTMLTreePrinter.java +++ /dev/null @@ -1,176 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -package scalac.ast.printer; - -import scalac.Unit; -import scalac.symtab.Symbol; -import scalac.util.Name; - -import java.io.PrintWriter; -import java.lang.Math; -import java.util.HashMap; - -/** - * HTML pretty printer for Scala abstract syntax trees. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class HTMLTreePrinter extends TextTreePrinter { - protected int outSectionLevel = 1; - protected boolean started = false; - - public HTMLTreePrinter(PrintWriter writer) { - super(writer); - } - - public void begin() { - assert !started; - - super.begin(); - out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); - out.println("<html>"); - out.println("<head>"); - out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">"); - out.println("<link rel=\"stylesheet\" href=\"scala.css\" type=\"text/css\">"); - out.println("<title>Scala tree</title>"); - out.println("</head>"); - out.println("<body>"); - - started = true; - } - - public void end() { - assert started; - - out.println("</body>"); - out.println("</html>"); - super.end(); - - started = false; - } - - public void beginSection(int level, String title) { - outSectionLevel = Math.min(level, 4); - beginSection1(outSectionLevel, title); - } - - protected void beginSection1(int level, String title) { - if (level == 1) - out.println("<hr/>"); - String tag = "h" + level; - startTag(tag); - print(Text.Simple(title)); - endTag(tag); - } - - protected void startTag(String tag) { - out.print('<'); out.print(tag); out.print('>'); - } - - protected void startTag(String tag, String attr1, String val1) { - out.print('<'); - out.print(tag); - out.print(' '); - out.print(attr1); - out.print("=\""); - out.print(val1); - out.print("\">"); - } - - protected void endTag(String tag) { - out.print("</"); out.print(tag); out.print(">"); - } - - protected void startSpan(String cls) { - startTag("span", "class", cls); - } - - protected void endSpan() { - endTag("span"); - } - - protected void printString(String str) { - StringBuffer buf = null; - int strLen = str.length(); - - for (int i = 0; i < strLen; ++i) { - String entity; - char c = str.charAt(i); - switch (c) { - case '<': entity = "lt"; break; - case '>': entity = "gt"; break; - case '&': entity = "amp"; break; - default: entity = null; break; - } - if (entity != null) { - out.print('&'); - out.print(entity); - out.print(';'); - } else - out.print(c); - } - } - - protected static HashMap/*<Symbol,Integer>*/ symAnchors = new HashMap(); - protected String symbolAnchor(Symbol sym, SymbolUsage usage) { - Integer anchorId = (Integer)symAnchors.get(sym); - if (anchorId == null) { - anchorId = new Integer(symAnchors.size()); - symAnchors.put(sym, anchorId); - } - if (usage == SymbolUsage.Definition) - return anchorId.toString(); - else - return "#" + anchorId.toString(); - } - - protected void print(Text text) { - switch (text) { - case Keyword(String name): - startSpan("kw"); - printString(name); - endSpan(); - break; - case Literal(String str): - startSpan("lit"); - printString(str); - endSpan(); - break; - case Identifier(Symbol symbol, Name name, SymbolUsage usage): - boolean defined = (usage == SymbolUsage.Definition); - if (defined) startSpan("idDef"); - if (symbol != null) { - String attr = (defined ? "name" : "href"); - startTag("a", attr, symbolAnchor(symbol, usage)); - if (usage == SymbolUsage.Use) - printString(symbol.simpleName().toString()); - else - printString(symbol.name.toString()); - endTag("a"); - } else - printString(name.toString()); - if (defined) endSpan(); - break; - default: - super.print(text); - } - } - - protected void printUnitHeader(Unit unit) { - beginSection1(outSectionLevel + 1, unit.source.toString()); - startTag("pre"); - } - - protected void printUnitFooter(Unit unit) { - endTag("pre"); - } -} diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java deleted file mode 100644 index 6a8be8f696..0000000000 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ /dev/null @@ -1,813 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -package scalac.ast.printer; - -import scalac.ast.*; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.Global; -import scalac.Phase; -import scalac.Unit; -import scalac.util.Name; -import scalac.util.TypeNames; - -import java.io.*; -import java.util.*; - -/** - * Text pretty printer for Scala abstract syntax trees. - * - * @author Michel Schinz, Matthias Zenger - * @version 1.0 - */ -public class TextTreePrinter implements TreePrinter { - protected final PrintWriter out; - - protected int indent = 0; - protected final int INDENT_STEP = 2; - protected String INDENT_STRING = - " "; - protected final int MAX_INDENT = INDENT_STRING.length(); - - public TextTreePrinter(PrintWriter writer) { - this.out = writer; - } - - public TextTreePrinter(Writer writer) { - this(new PrintWriter(writer)); - } - - public TextTreePrinter(OutputStream stream) { - this(new PrintWriter(stream)); - } - - public TextTreePrinter() { - this(System.out); - } - - public void begin() { } - - public void end() { - flush(); - } - - public void flush() { - out.flush(); - } - - public TreePrinter print(String str) { - out.print(str); - return this; - } - - public TreePrinter println() { - out.println(); - return this; - } - - public void beginSection(int level, String title) { - out.println("[[" + title + "]]"); - flush(); - } - - protected void indent() { - indent += Math.min(MAX_INDENT, INDENT_STEP); - } - - protected void undent() { - indent -= Math.max(0, INDENT_STEP); - } - - protected void printString(String str) { - out.print(str); - } - - protected void printNewLine() { - out.println(); - while (indent > INDENT_STRING.length()) { - INDENT_STRING = INDENT_STRING + INDENT_STRING; - } - if (indent > 0) - out.write(INDENT_STRING, 0, indent); - } - - public static class SymbolUsage { - public case Definition; - public case Use; - } - - public static class Text { - public case None; - public case Space; - public case Newline; - public case Simple(String str); - public case Literal(String str); - public case Keyword(String name); - public case Identifier(Symbol symbol, Name name, SymbolUsage usage); - public case Sequence(Text[] elements); - } - - protected void print(Text text) { - switch (text) { - case None : break; - case Space : printString(" "); break; - case Newline : printNewLine(); break; - case Simple(String str) : printString(str); break; - case Literal(String str) : printString(str); break; - case Keyword(String name) : printString(name); break; - case Identifier(Symbol sym, Name name, SymbolUsage usage) : - if (sym != null) { - if (usage == SymbolUsage.Use) - printString(sym.simpleName().toString()); - else - printString(sym.name.toString()); - if (Global.instance.uniqid) - printString("#" + Global.instance.uniqueID.id(sym)); - } else { - printString(name.toString()); - } - break; - case Sequence(Text[] elements) : print(elements); break; - } - } - - protected void print(Text[] texts) { - for (int i = 0; i < texts.length; ++i) - print(texts[i]); - } - - protected static final Text KW_ABSTRACT = Text.Keyword("abstract"); - protected static final Text KW_CASE = Text.Keyword("case"); - protected static final Text KW_CLASS = Text.Keyword("class"); - protected static final Text KW_DEF = Text.Keyword("def"); - protected static final Text KW_DO = Text.Keyword("do"); - protected static final Text KW_ELSE = Text.Keyword("else"); - protected static final Text KW_EXTENDS = Text.Keyword("extends"); - protected static final Text KW_FINAL = Text.Keyword("final"); - protected static final Text KW_SEALED = Text.Keyword("sealed"); - protected static final Text KW_FOR = Text.Keyword("for"); - protected static final Text KW_IF = Text.Keyword("if"); - protected static final Text KW_IMPORT = Text.Keyword("import"); - protected static final Text KW_INTERFACE = Text.Keyword("interface"); - protected static final Text KW_OBJECT = Text.Keyword("object"); - protected static final Text KW_NEW = Text.Keyword("new"); - protected static final Text KW_NULL = Text.Keyword("null"); - protected static final Text KW_OUTER = Text.Keyword("outer"); - protected static final Text KW_OVERRIDE = Text.Keyword("override"); - protected static final Text KW_PACKAGE = Text.Keyword("package"); - protected static final Text KW_PRIVATE = Text.Keyword("private"); - protected static final Text KW_PROTECTED = Text.Keyword("protected"); - protected static final Text KW_RETURN = Text.Keyword("return"); - protected static final Text KW_STATIC = Text.Keyword("static"); - protected static final Text KW_SUPER = Text.Keyword("super"); - protected static final Text KW_THIS = Text.Keyword("this"); - protected static final Text KW_TYPE = Text.Keyword("type"); - protected static final Text KW_VAL = Text.Keyword("val"); - protected static final Text KW_VAR = Text.Keyword("var"); - protected static final Text KW_WITH = Text.Keyword("with"); - protected static final Text KW_YIELD = Text.Keyword("yield"); - - protected static final Text TXT_ERROR = Text.Simple("<error>"); - protected static final Text TXT_UNKNOWN = Text.Simple("<unknown>"); - protected static final Text TXT_NULL = Text.Simple("<null>"); - protected static final Text TXT_OBJECT_COMMENT - = Text.Simple("/*object*/ "); - protected static final Text TXT_EMPTY = Text.Simple("<empty>"); - - protected static final Text TXT_QUOTE = Text.Simple("\""); - protected static final Text TXT_PLUS = Text.Simple("+"); - protected static final Text TXT_COLON = Text.Simple(":"); - protected static final Text TXT_SEMICOLON = Text.Simple(";"); - protected static final Text TXT_DOT = Text.Simple("."); - protected static final Text TXT_COMMA = Text.Simple(","); - protected static final Text TXT_EQUAL = Text.Simple("="); - protected static final Text TXT_SUPERTYPE = Text.Simple(">:"); - protected static final Text TXT_SUBTYPE = Text.Simple("<:"); - protected static final Text TXT_HASH = Text.Simple("#"); - protected static final Text TXT_RIGHT_ARROW = Text.Simple("=>"); - protected static final Text TXT_LEFT_PAREN = Text.Simple("("); - protected static final Text TXT_RIGHT_PAREN = Text.Simple(")"); - protected static final Text TXT_LEFT_BRACE = Text.Simple("{"); - protected static final Text TXT_RIGHT_BRACE = Text.Simple("}"); - protected static final Text TXT_LEFT_BRACKET = Text.Simple("["); - protected static final Text TXT_RIGHT_BRACKET = Text.Simple("]"); - protected static final Text TXT_BAR = Text.Simple("|"); - protected static final Text TXT_AT = Text.Simple("@"); - - protected static final Text TXT_WITH_SP = - Text.Sequence(new Text[]{ Text.Space, KW_WITH, Text.Space }); - protected static final Text TXT_BLOCK_BEGIN = - Text.Sequence(new Text[]{ TXT_LEFT_BRACE, Text.Newline }); - protected static final Text TXT_BLOCK_END = - Text.Sequence(new Text[]{ Text.Newline, TXT_RIGHT_BRACE }); - protected static final Text TXT_BLOCK_SEP = - Text.Sequence(new Text[]{ TXT_SEMICOLON, Text.Newline }); - protected static final Text TXT_COMMA_SP = - Text.Sequence(new Text[]{ TXT_COMMA, Text.Space }); - protected static final Text TXT_ELSE_NL = - Text.Sequence(new Text[]{ KW_ELSE, Text.Newline }); - protected static final Text TXT_BAR_SP = - Text.Sequence(new Text[]{ Text.Space, TXT_BAR, Text.Space }); - - public void print(Global global) { - Phase phase = global.currentPhase; - beginSection(1, "syntax trees at "+phase+" (after "+phase.prev+")"); - for (int i = 0; i < global.units.length; i++) print(global.units[i]); - } - - public void print(Unit unit) { - printUnitHeader(unit); - if (unit.body != null) { - for (int i = 0; i < unit.body.length; ++i) { - print(unit.body[i]); - print(TXT_BLOCK_SEP); - } - } else - print(TXT_NULL); - printUnitFooter(unit); - - flush(); - } - - protected void printUnitHeader(Unit unit) { - print(Text.Simple("// Scala source: " + unit.source + "\n")); - } - - protected void printUnitFooter(Unit unit) { - print(Text.Newline); - } - - public TreePrinter print(Tree tree) { - switch (tree) { - case Bad(): - print(TXT_ERROR); - break; - - case Empty: - print(TXT_EMPTY); - break; - - case ClassDef(int mods, // : - Name name, - Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, - Tree tpe, - Tree.Template impl): - printModifiers(mods); - print((mods & Modifiers.INTERFACE) != 0 - ? KW_INTERFACE - : KW_CLASS); - print(Text.Space); - printSymbolDefinition(tree.symbol(), name); - printParams(tparams); - printParams(vparams); - printOpt(TXT_COLON, tpe, false); - printTemplate(tree.symbol(), KW_EXTENDS, impl, true); - break; - - case PackageDef(Tree packaged, Tree.Template impl): - print(KW_PACKAGE); - print(Text.Space); - print(packaged); - printTemplate(null, KW_WITH, impl, true); - break; - - case ModuleDef(int mods, // : - Name name, - Tree tpe, - Tree.Template impl): - printModifiers(mods); - print(KW_OBJECT); - print(Text.Space); - printSymbolDefinition(tree.symbol(), name); - printOpt(TXT_COLON, tpe, false); - printTemplate(null, KW_EXTENDS, impl, true); - break; - - case ValDef(int mods, Name name, Tree tpe, Tree rhs): - printModifiers(mods); - if ((mods & Modifiers.MUTABLE) != 0) print(KW_VAR); - else { - if ((mods & Modifiers.MODUL) != 0) print(TXT_OBJECT_COMMENT); - print(KW_VAL); - } - print(Text.Space); - printSymbolDefinition(tree.symbol(), name); - printOpt(TXT_COLON, tpe, false); - if ((mods & Modifiers.DEFERRED) == 0) { - print(Text.Space); print(TXT_EQUAL); print(Text.Space); - if (rhs == Tree.Empty) print("_"); - else print(rhs); - } - break; - - case PatDef(int mods, Tree pat, Tree rhs): - printModifiers(mods); - print(KW_VAL); - print(Text.Space); - print(pat); - printOpt(TXT_EQUAL, rhs, true); - break; - - case DefDef(int mods, - Name name, - Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, - Tree tpe, - Tree rhs): - printModifiers(mods); - print(KW_DEF); - print(Text.Space); - if (name.isTypeName()) print(KW_THIS); - else printSymbolDefinition(tree.symbol(), name); - printParams(tparams); - printParams(vparams); - printOpt(TXT_COLON, tpe, false); - printOpt(TXT_EQUAL, rhs, true); - break; - - case AbsTypeDef(int mods, - Name name, - Tree rhs, - Tree lobound): - printModifiers(mods); - print(KW_TYPE); - print(Text.Space); - printSymbolDefinition(tree.symbol(), name); - printBounds(lobound, rhs); - break; - - case AliasTypeDef(int mods, - Name name, - Tree.AbsTypeDef[] tparams, - Tree rhs): - printModifiers(mods); - print(KW_TYPE); - print(Text.Space); - printSymbolDefinition(tree.symbol(), name); - printParams(tparams); - printOpt(TXT_EQUAL, rhs, true); - break; - - case Import(Tree expr, Name[] selectors): - print(KW_IMPORT); - print(Text.Space); - print(expr); - print(TXT_DOT); - print(TXT_LEFT_BRACE); - for (int i = 0; i < selectors.length; i = i + 2) { - if (i > 0) print(TXT_COMMA_SP); - print(selectors[i].toString()); - if (i + 1 < selectors.length && selectors[i] != selectors[i+1]) { - print(TXT_RIGHT_ARROW); - print(selectors[i+1].toString()); - } - } - print(TXT_RIGHT_BRACE); - break; - - case CaseDef(Tree pat, Tree guard, Tree body): - print(KW_CASE); - print(Text.Space); - print(pat); - printOpt(KW_IF, guard, true); - print(Text.Space); - print(TXT_RIGHT_ARROW); - print(Text.Space); - print(body); - break; - - case LabelDef(Name name, Tree.Ident[] params, Tree rhs): - printSymbolDefinition(tree.symbol(), name); - printArray(params, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - print(rhs); - break; - - case Block(Tree[] stats, Tree value): - printArray(stats, TXT_BLOCK_BEGIN, TXT_SEMICOLON, TXT_BLOCK_SEP); - indent(); - printNewLine(); - print(value); - undent(); - print(TXT_BLOCK_END); - printType(tree); - break; - - case Sequence(Tree[] trees): // sure ? was Tuple before... - printArray(trees, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP); - break; - - /* - case Subsequence(Tree[] trees): - if( trees.length > 0 ) - printArray(trees, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - else - { - print( TXT_LEFT_PAREN ); - print( TXT_COMMA ); - print( TXT_RIGHT_PAREN ); - } - break; - */ - case Alternative(Tree[] trees): - printArray(trees, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_BAR_SP); - break; - - case Bind(Name name, Tree t): - printSymbolDefinition(tree.symbol(), name); - print(Text.Space); - print(TXT_AT); - print(Text.Space); - print(TXT_LEFT_PAREN); - print( t ); - print(TXT_RIGHT_PAREN); - printType(tree); - break; - - case Visitor(Tree.CaseDef[] cases): - printArray(cases, TXT_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline); - break; - - case Function(Tree.ValDef[] vparams, Tree body): - print(TXT_LEFT_PAREN); - printParams(vparams); - print(Text.Space); - print(TXT_RIGHT_ARROW); - print(Text.Space); - print(body); - print(TXT_RIGHT_PAREN); - break; - - case Assign(Tree lhs, Tree rhs): - print(lhs); - print(Text.Space); - print(TXT_EQUAL); - print(Text.Space); - print(rhs); - break; - - case If(Tree cond, Tree thenp, Tree elsep): - print(KW_IF); - print(Text.Space); - print(TXT_LEFT_PAREN); - print(cond); - print(TXT_RIGHT_PAREN); - indent(); print(Text.Newline); - print(thenp); - undent(); print(Text.Newline); - indent(); printOpt(TXT_ELSE_NL, elsep, false); undent(); - printType(tree); - break; - - case Switch(Tree expr, int[] tags, Tree[] bodies, Tree defaultBody): - print("<switch>"); - print(Text.Space); - print(TXT_LEFT_PAREN); - print(expr); - print(TXT_RIGHT_PAREN); - print(Text.Space); - indent(); - print(TXT_BLOCK_BEGIN); - for (int i = 0; i < tags.length; i++) { - print(KW_CASE); - print(Text.Space); - print("" + tags[i]); - print(Text.Space); - print(TXT_RIGHT_ARROW); - print(Text.Space); - print(bodies[i]); - print(Text.Newline); - } - print("<default> => "); - print(defaultBody); - undent(); - print(TXT_BLOCK_END); - break; - - case Return(Tree expr): - print(KW_RETURN); - print(Text.Space); - print(expr); - break; - - case New(Tree.Template templ): - printTemplate(null, KW_NEW, templ, false); - printType(tree); - break; - - case Typed(Tree expr, Tree tpe): - print(TXT_LEFT_PAREN); - print(expr); - print(TXT_RIGHT_PAREN); - print(Text.Space); - print(TXT_COLON); - print(Text.Space); - print(tpe); - printType(tree); - break; - - case TypeApply(Tree fun, Tree[] targs): - print(fun); - printArray(targs, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP); - printType(tree); - break; - - case Apply(Tree fun, Tree[] vargs): - if (fun instanceof Tree.TypeTerm) - print(fun.type.resultType().symbol().fullName().toString()); - else - print(fun); - printArray(vargs, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - printType(tree); - break; - - case Super(Name qualifier, Name mixin): - if (qualifier != TypeNames.EMPTY) { - printSymbolUse(tree.symbol(), qualifier); - print(TXT_DOT); - } - print(KW_SUPER); - if (mixin != TypeNames.EMPTY) { - print(TXT_LEFT_PAREN); - print(mixin.toString()); - print(TXT_RIGHT_PAREN); - } - printType(tree); - break; - - case This(Name name): - if (name != TypeNames.EMPTY) { - printSymbolUse(tree.symbol(), name); - print(TXT_DOT); - } - print(KW_THIS); - printType(tree); - break; - - case Select(Tree qualifier, Name name): - if (Global.instance.debug || qualifier.symbol() == null || !qualifier.symbol().isRoot()) { - print(qualifier); - print(TXT_DOT); - } - printSymbolUse(tree.symbol(), name); - printType(tree); - break; - - case Ident(Name name): - printSymbolUse(tree.symbol(), name); - printType(tree); - break; - - case Literal(AConstant value): - print(Text.Literal(value.toString())); - printType(tree); - break; - - case TypeTerm(): - print(tree.type.toString()); - break; - - case SingletonType(Tree ref): - print(ref); - print(TXT_DOT); print(KW_TYPE); - break; - - case SelectFromType(Tree qualifier, Name selector): - print(qualifier); - print(Text.Space); print(TXT_HASH); print(Text.Space); - printSymbolUse(tree.symbol(), selector); - break; - - case FunType(Tree[] argtpes, Tree restpe): - printArray(argtpes, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - print(TXT_RIGHT_ARROW); - print(restpe); - break; - - case CompoundType(Tree[] baseTypes, Tree[] refinements): - printArray(baseTypes, Text.None, Text.None, TXT_WITH_SP); - printArray(refinements, TXT_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline); - break; - - case AppliedType(Tree tpe, Tree[] args): - print(tpe); - indent(); - print(TXT_LEFT_BRACKET); - for (int i = 0; i < args.length; ++i) { - if (i > 0) print(TXT_COMMA_SP); - print(args[i]); - } - undent(); - print(TXT_RIGHT_BRACKET); - break; - - case Template(Tree[] parents, Tree[] body): - Debug.abort("unexpected case: template"); - break; - - default: - print(TXT_UNKNOWN); - break; - } - //print("{" + tree.type + "}");//DEBUG - return this; - } - - // Printing helpers - - protected void printArray(Tree[] trees, Text open, Text close, Text sep) { - indent(); - print(open); - for (int i = 0; i < trees.length; ++i) { - if (i > 0) print(sep); - print(trees[i]); - } - undent(); - print(close); - } - - protected void printOpt(Text prefix, Tree tree, boolean spaceBefore) { - if (tree != Tree.Empty) { - if (spaceBefore) - print(Text.Space); - print(prefix); - print(Text.Space); - print(tree); - } - } - - // Printing of symbols - - protected void printSymbolDefinition(Symbol symbol, Name name) { - print(Text.Identifier(symbol, name, SymbolUsage.Definition)); - } - - protected void printSymbolUse(Symbol symbol, Name name) { - print(Text.Identifier(symbol, name, SymbolUsage.Use)); - } - - // Printing of trees - - protected void printType(Tree tree) { - if (Global.instance.printtypes) { - print(TXT_LEFT_BRACE); - if (tree.type != null) - print(Text.Simple(tree.type.toString())); - else - print(TXT_NULL); - print(TXT_RIGHT_BRACE); - } - } - - protected void printModifiers(int flags) { - if ((flags & Modifiers.ABSTRACT) != 0) { - print(KW_ABSTRACT); - print(Text.Space); - } - if ((flags & Modifiers.FINAL) != 0) { - print(KW_FINAL); - print(Text.Space); - } - if ((flags & Modifiers.SEALED) != 0) { - print(KW_SEALED); - print(Text.Space); - } - if ((flags & Modifiers.PRIVATE) != 0) { - print(KW_PRIVATE); - print(Text.Space); - } - if ((flags & Modifiers.PROTECTED) != 0) { - print(KW_PROTECTED); - print(Text.Space); - } - if ((flags & Modifiers.OVERRIDE) != 0) { - print(KW_OVERRIDE); - print(Text.Space); - } - if ((flags & Modifiers.CASE) != 0) { - print(KW_CASE); - print(Text.Space); - } - if ((flags & Modifiers.DEF) != 0) { - print(KW_DEF); - print(Text.Space); - } - } - - protected void printTemplate(Symbol symbol, - Text prefix, - Tree.Template templ, - boolean spaceBefore) { - if (! (templ.parents.length == 0 - || (templ.parents.length == 1 - && templ.parents[0] == Tree.Empty))) { - if (spaceBefore) - print(Text.Space); - print(prefix); - print(Text.Space); - printArray(templ.parents, Text.None, Text.None, TXT_WITH_SP); - } - - List types = new ArrayList(); - if (symbol != null) { - Global global = Global.instance; - if (global.currentPhase.id > global.PHASE.EXPLICITOUTER.id()) { - Scope.SymbolIterator i = symbol.members().iterator(true); - while (i.hasNext()) { - Symbol member = i.next(); - if (member.isTypeAlias() || member.isAbstractType()) - types.add(member); - } - } - } - if (templ.body.length > 0 || types.size() > 0) { - print(Text.Space); - indent(); - print(TXT_BLOCK_BEGIN); - if (types.size() > 0) { - SymbolTablePrinter printer = new SymbolTablePrinter( - INDENT_STRING.substring(0, indent)); - printer.indent(); - for (int i = 0; i < types.size(); ++i) { - if (i > 0) printer.line(); - Symbol type = (Symbol)types.get(i); - printer.printSignature(type).print(';'); - } - printer.undent(); - print(printer.toString().substring(indent)); - print(Text.Newline); - } - for (int i = 0; i < templ.body.length; ++i) { - if (i > 0) print(TXT_BLOCK_SEP); - print(templ.body[i]); - } - undent(); - print(TXT_BLOCK_END); - } - } - - protected void printParams(Tree.AbsTypeDef[] tparams) { - if (tparams.length > 0) { - print(TXT_LEFT_BRACKET); - for (int i = 0; i < tparams.length; i++) { - if (i > 0) print(TXT_COMMA_SP); - printParam(tparams[i]); - } - print(TXT_RIGHT_BRACKET); - } - } - - protected void printParams(Tree.ValDef[][] vparamss) { - for (int i = 0; i < vparamss.length; ++i) - printParams(vparamss[i]); - } - - protected void printParams(Tree.ValDef[] vparams) { - print(TXT_LEFT_PAREN); - for (int i = 0; i < vparams.length; ++i) { - if (i > 0) print(TXT_COMMA_SP); - printParam(vparams[i]); - } - print(TXT_RIGHT_PAREN); - } - - protected void printParam(Tree tree) { - switch (tree) { - case AbsTypeDef(int mods, Name name, Tree bound, Tree lobound): - printModifiers(mods); - printSymbolDefinition(tree.symbol(), name); - printBounds(lobound, bound); - break; - - case ValDef(int mods, Name name, Tree tpe, Tree.Empty): - printModifiers(mods); - printSymbolDefinition(tree.symbol(), name); - printOpt(TXT_COLON, tpe, false); - break; - - default: - Debug.abort("bad parameter: " + tree); - } - } - - protected void printBounds(Tree lobound, Tree hibound) { - Definitions definitions = Global.instance.definitions; - boolean printLoBound = lobound.type != null - ? lobound.type().symbol() != definitions.ALL_CLASS - : !"scala.All".equals(lobound.toString()); - if (printLoBound) printOpt(TXT_SUPERTYPE, lobound, true); - boolean printHiBound = hibound.type != null - ? hibound.type().symbol() != definitions.ANY_CLASS - : !"scala.Any".equals(hibound.toString()); - if (printHiBound) printOpt(TXT_SUBTYPE, hibound, true); - } - -} |