diff options
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r-- | sources/scalac/ast/Tree.java | 27 | ||||
-rw-r--r-- | sources/scalac/ast/TreeGen.java | 19 | ||||
-rw-r--r-- | sources/scalac/ast/TreeInfo.java | 2 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 94 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Scanner.java | 11 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Tokens.java | 29 | ||||
-rw-r--r-- | sources/scalac/ast/printer/TextTreePrinter.java | 22 |
7 files changed, 127 insertions, 77 deletions
diff --git a/sources/scalac/ast/Tree.java b/sources/scalac/ast/Tree.java index 0c28016253..a3cc94cf3e 100644 --- a/sources/scalac/ast/Tree.java +++ b/sources/scalac/ast/Tree.java @@ -146,7 +146,7 @@ public class Tree { /** * Import declaration * - introduced by: parser - * - eliminated by: !!! ? + * - eliminated by: analyzer */ public case Import(Tree expr, Name[] selectors) { if (!expr.isTerm()) @@ -204,8 +204,8 @@ public class Tree { /** * Tuple of expressions (comma separated expressions) - * - introduced by: !!! ? - * - eliminated by: !!! ? + * - introduced by: uncurry + * - eliminated by: lambdalift */ public case Tuple(Tree[] trees) { if (trees != null) { @@ -219,14 +219,14 @@ public class Tree { /** * Visitor (a sequence of cases) * - introduced by: parser - * - eliminated by: !!! ? + * - eliminated by: transmatch */ public case Visitor(CaseDef[] cases); /** * Anonymous function * - introduced by: parser - * - eliminated by: !!! ? + * - eliminated by: analyzer */ public case Function(ValDef[] vparams, Tree body) { @@ -237,7 +237,7 @@ public class Tree { /** * Assignment * - introduced by: parser - * - eliminated by: !!! ? + * - eliminated by: - */ public case Assign(Tree lhs, Tree rhs) { @@ -283,7 +283,7 @@ public class Tree { /** * Type application * - introduced by: parser - * - eliminated by: !!! ? + * - eliminated by: erasure */ public case TypeApply(Tree fun, Tree[] args) { @@ -422,7 +422,7 @@ public class Tree { /** * Applied type * - introduced by: parser - * - eliminated by: Analyzer + * - eliminated by: analyzer */ public case AppliedType(Tree tpe, Tree[] args) { assert tpe.isType() : this; @@ -492,6 +492,17 @@ public class Tree { } } + /** Returns true if this tree is empty or error. */ + public boolean isMissing() { + switch(this) { + case Bad(): + case Empty: + return true; + default: + return false; + } + } + //######################################################################## // Public Methods - tree type diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 0c9c47eb88..ecb4705de5 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -165,13 +165,7 @@ public class TreeGen implements Kinds, Modifiers { Tree ref = mkRef(pos, pre, sym.constructor()); Tree constr = (args.length == 0) ? ref : TypeApply(ref, mkTypes(sym.pos, args)); - switch (parentType) { - case MethodType(Symbol[] params, Type restpe): - assert params.length == 0 : parentType; - return Apply(constr, Tree.EMPTY_ARRAY); - default: - return constr; - } + return Apply(constr, Tree.EMPTY_ARRAY); default: throw global.fail("invalid parent type", parentType); } @@ -357,9 +351,17 @@ public class TreeGen implements Kinds, Modifiers { return TypeApply(fn.pos, fn, args); } + public Tree If(int pos, Tree cond, Tree thenpart, Tree elsepart) { + return + make.If(pos, cond, thenpart, elsepart).setType(thenpart.type); + } + + public Tree If(Tree cond, Tree thenpart, Tree elsepart) { + return If(cond.pos, cond, thenpart, elsepart); + } + /** Build and applied type node with given function * and argument trees. - */ public Tree AppliedType(int pos, Tree fn, Tree[] args) { return make.AppliedType(pos, fn, args) .setType(Type.appliedType(fn.type, Tree.typeOf(args))); @@ -368,6 +370,7 @@ public class TreeGen implements Kinds, Modifiers { public Tree AppliedType(Tree fn, Tree[] args) { return AppliedType(fn.pos, fn, args); } + */ /** Build and attribute select node of given symbol. * It is assumed that the prefix is not empty. diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java index d07627724f..17ca034316 100644 --- a/sources/scalac/ast/TreeInfo.java +++ b/sources/scalac/ast/TreeInfo.java @@ -115,6 +115,8 @@ public class TreeInfo { tree.symbol() != null && tree.symbol().isPrimaryConstructor(); case TypeApply(Tree constr, _): return isPureConstr(constr); + case Apply(Tree fn, Tree[] args): + return args.length == 0 && isPureConstr(fn); default: return false; } diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index f525398b3c..771979fcda 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -124,7 +124,7 @@ public class Parser implements Tokens { boolean isDefIntro() { switch (s.token) { case VAL: case VAR: case DEF: case CONSTR: case TYPE: - case MODULE: case CLASS: case CASECLASS: case TRAIT: + case OBJECT: case CASEOBJECT: case CLASS: case CASECLASS: case TRAIT: return true; default: return false; @@ -193,6 +193,15 @@ public class Parser implements Tokens { return make.Select(pos, make.Ident(pos, Names.scala), name); } + Tree scalaBooleanDot(int pos, Name name) { + return make.Select(pos, scalaDot(pos, Names.Boolean), name); + } + + Tree scalaObjectConstr(int pos) { + return make.Apply( + pos, scalaDot(pos, Names.Object.toConstrName()), 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. @@ -310,6 +319,17 @@ public class Parser implements Tokens { } } + /** 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]; @@ -383,6 +403,9 @@ public class Parser implements Tokens { t = make.This(s.skipToken(), Tree.Empty); if (!thisOK || s.token == DOT) t = selectors(accept(DOT), t, typeOK); + } else if (s.token == SUPER) { + t = make.Super(s.skipToken(), Tree.Empty); + t = selectors(accept(DOT), t, typeOK); } else { t = make.Ident(s.pos, ident()); if (s.token == DOT) { @@ -413,7 +436,7 @@ public class Parser implements Tokens { } } - /** StableId ::= [[Ident `.'] this `.'] {Id `.'} Id + /** StableId ::= [[Ident `.'] this `.' | super] {Id `.'} Id */ Tree stableId() { return stableRef(false, false); @@ -498,6 +521,17 @@ public class Parser implements Tokens { } } + /** SimpleTypedOpt ::= [`:' Type] + */ + Tree simpleTypedOpt() { + if (s.token == COLON) { + s.nextToken(); + return simpleType(); + } else { + return Tree.Empty; + } + } + /** Types ::= Type {`,' Type} */ Tree[] types() { @@ -894,7 +928,8 @@ public class Parser implements Tokens { switch (res) { case Block(Tree[] stats): if (stats.length > 0) - stats[stats.length - 1] = convertToConstr(stats[stats.length - 1]); + stats[stats.length - 1] = applyConstr( + convertToConstr(stats[stats.length - 1])); else syntaxError(res.pos, "class constructor expected", false); } @@ -1337,9 +1372,7 @@ public class Parser implements Tokens { } /** TopDef ::= ([case] class | trait) ClassDef {`,' ClassDef} - * | module ModuleDef {`,' ModuleDef} - * LocalTopDef ::= class ClassDef {`,' ClassDef}//todo: keep? - * | module ModuleDef {`,' ModuleDef} + * | [case] object ModuleDef {`,' ModuleDef} */ Tree[] topDef(int mods) { TreeList ts = new TreeList(); @@ -1354,7 +1387,8 @@ public class Parser implements Tokens { ts.append(classDef(mods)); } while (s.token == COMMA); return ts.toArray(); - case MODULE: + case OBJECT: + case CASEOBJECT: do { s.nextToken(); ts.append(moduleDef(mods)); @@ -1441,10 +1475,7 @@ public class Parser implements Tokens { TypeDef[] tparams = typeParamClauseOpt(); ValDef[][] vparams = new ValDef[][]{paramClause()}; Tree restype = typedOpt(); - if (s.token == LBRACE) - return make.DefDef(pos, mods, name, tparams, vparams, - restype, blockConstr()); - else if (s.token == EQUALS || restype == Tree.Empty) { + if (s.token == EQUALS || restype == Tree.Empty) { accept(EQUALS); return make.DefDef(pos, mods, name, tparams, vparams, restype, (s.token == LBRACE) ? blockConstr() : constr()); @@ -1474,24 +1505,23 @@ public class Parser implements Tokens { } } - /** ClassDef ::= Id [TypeParamClause] [`:' Type] ClassTemplate + /** ClassDef ::= Id [TypeParamClause] [`:' SimpleType] ClassTemplate */ Tree classDef(int mods) { int pos = s.pos; Name name = ident(); TypeDef[] tparams = typeParamClauseOpt(); - ValDef[][] params; - if (s.token == LPAREN) params = new ValDef[][]{paramClause()}; - else params = Tree.ExtValDef.EMPTY_ARRAY_ARRAY; + ValDef[][] params = (s.token == LPAREN) ? new ValDef[][]{paramClause()} + : Tree.ExtValDef.EMPTY_ARRAY_ARRAY; return make.ClassDef(pos, mods, name.toTypeName(), tparams, params, - typedOpt(), classTemplate()); + simpleTypedOpt(), classTemplate()); } - /** ModuleDef ::= Id [`:' Type] ClassTemplate + /** ModuleDef ::= Id [`:' SimpleType] ClassTemplate */ Tree moduleDef(int mods) { return make.ModuleDef( - s.pos, mods, ident(), typedOpt(), classTemplate()); + s.pos, mods, ident(), simpleTypedOpt(), classTemplate()); } /** ClassTemplate ::= [`extends' Constr] {`with' Constr} [TemplateBody] @@ -1504,21 +1534,16 @@ public class Parser implements Tokens { } else if (s.token == WITH) { s.nextToken(); TreeList parents = new TreeList(); - parents.append(scalaDot(pos, Names.Object.toConstrName())); + parents.append(scalaObjectConstr(pos)); return template(parents); } else if (s.token == LBRACE) { - return (Template)make.Template(pos, - new Tree[]{scalaDot(pos, Names.Object.toConstrName())}, - templateBody()); - } else if (s.token == SEMI || s.token == COMMA || s.token == RBRACE) { - return (Template)make.Template(pos, - new Tree[]{scalaDot(pos, Names.Object.toConstrName())}, - Tree.EMPTY_ARRAY); + return (Template)make.Template( + pos, new Tree[]{scalaObjectConstr(pos)}, templateBody()); } else { - syntaxError("`extends' or `{' expected", true); - return (Template)make.Template(pos, - new Tree[]{scalaDot(pos, Names.Object.toConstrName())}, - Tree.EMPTY_ARRAY); + if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE)) + syntaxError("`extends' or `{' expected", true); + return (Template)make.Template( + pos, new Tree[]{scalaObjectConstr(pos)}, Tree.EMPTY_ARRAY); } } @@ -1550,7 +1575,7 @@ public class Parser implements Tokens { t = make.TypeApply(s.pos, t, typeArgs()); if (s.token == LPAREN) t = make.Apply(s.pos, t, argumentExprs()); - return t; + return applyConstr(t); } /** TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}' @@ -1601,11 +1626,12 @@ public class Parser implements Tokens { } else if (s.token == CLASS || s.token == CASECLASS || s.token == TRAIT || - s.token == MODULE || + s.token == OBJECT || + s.token == CASEOBJECT || isModifier()) { stats.append(topDef(modifiers())); } else if (s.token != SEMI) { - syntaxError("illegal start of class or module definition", true); + syntaxError("illegal start of class or object definition", true); } if (s.token != RBRACE && s.token != EOF) accept(SEMI); } @@ -1658,7 +1684,7 @@ public class Parser implements Tokens { /** BlockStatSeq ::= { BlockStat `;' } [Expr] * BlockStat ::= Import * | Def - * | LocalClassModifiers LocalTopDef + * | LocalClassModifiers TopDef * | Expr * | */ diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java index 82eef0d408..5cfe8292a6 100644 --- a/sources/scalac/ast/parser/Scanner.java +++ b/sources/scalac/ast/parser/Scanner.java @@ -138,6 +138,8 @@ public class Scanner extends TokenData { fetchToken(); if (token == CLASS) { token = CASECLASS; + } else if (token == OBJECT) { + token = CASEOBJECT; } else { next.copyFrom(this); this.copyFrom(prev); @@ -479,8 +481,10 @@ public class Scanner extends TokenData { void treatIdent(int start, int end) { name = Name.fromAscii(buf, start, end - start); - if (name.index <= maxKey) + if (name.index <= maxKey) { token = key[name.index]; + if (token == OBJECT1) token = OBJECT; //todo: elim + } else token = IDENTIFIER; } @@ -716,6 +720,8 @@ public class Scanner extends TokenData { return "','"; case CASECLASS: return "case class"; + case CASEOBJECT: + return "case object"; default: try { return "'" + tokenName[token].toString() + "'"; @@ -796,7 +802,8 @@ public class Scanner extends TokenData { enterKeyword("def", DEF); enterKeyword("type", TYPE); enterKeyword("extends", EXTENDS); - enterKeyword("module", MODULE); + enterKeyword("object", OBJECT); + enterKeyword("module", OBJECT1); enterKeyword("class",CLASS); enterKeyword("constr",CONSTR); enterKeyword("import", IMPORT); diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java index 10503ddd48..c4499522df 100644 --- a/sources/scalac/ast/parser/Tokens.java +++ b/sources/scalac/ast/parser/Tokens.java @@ -37,19 +37,20 @@ public interface Tokens { SUPER = 27, CASE = 28, CASECLASS = 29, - VAL = 30, - ABSTRACT = 31, - FINAL = 32, - PRIVATE = 33, - PROTECTED = 34, - OVERRIDE = 35, - VAR = 36, - DEF = 37, - TYPE = 38, - EXTENDS = 39, - TRUE = 40, - FALSE = 41, - MODULE = 43, + 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, CONSTR = 45, IMPORT = 46, @@ -60,6 +61,8 @@ public interface Tokens { DO = 51, TRAIT = 52, + OBJECT1 = 53, // todo: elim + /* special symbols */ COMMA = 61, SEMI = 62, diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java index adbad7c3ad..0d4ff6022f 100644 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ b/sources/scalac/ast/printer/TextTreePrinter.java @@ -150,7 +150,7 @@ public class TextTreePrinter implements TreePrinter { protected static final Text KW_IMPORT = Text.Keyword("import"); protected static final Text KW_INTERFACE = Text.Keyword("interface"); protected static final Text KW_LET = Text.Keyword("let"); - protected static final Text KW_MODULE = Text.Keyword("module"); + 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"); @@ -171,8 +171,8 @@ public class TextTreePrinter implements TreePrinter { 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_MODULE_COMMENT - = Text.Simple("/*module*/ "); + 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("\""); @@ -192,10 +192,6 @@ public class TextTreePrinter implements TreePrinter { protected static final Text TXT_LEFT_BRACKET = Text.Simple("["); protected static final Text TXT_RIGHT_BRACKET = Text.Simple("]"); - protected static final Text TXT_WITH_BLOCK_BEGIN = - Text.Sequence(new Text[] { - Text.Space, KW_WITH, Text.Space, TXT_LEFT_BRACE, Text.Newline - }); protected static final Text TXT_WITH_SP = Text.Sequence(new Text[]{ Text.Space, KW_WITH, Text.Space }); protected static final Text TXT_BLOCK_BEGIN = @@ -271,7 +267,7 @@ public class TextTreePrinter implements TreePrinter { Tree tpe, Tree.Template impl): printModifiers(mods); - print(KW_MODULE); + print(KW_OBJECT); print(Text.Space); printSymbolDefinition(tree.symbol(), name); printOpt(TXT_COLON, tpe, false); @@ -282,7 +278,7 @@ public class TextTreePrinter implements TreePrinter { printModifiers(mods); if ((mods & Modifiers.MUTABLE) != 0) print(KW_VAR); else { - if ((mods & Modifiers.MODUL) != 0) print(TXT_MODULE_COMMENT); + if ((mods & Modifiers.MODUL) != 0) print(TXT_OBJECT_COMMENT); print(KW_VAL); } print(Text.Space); @@ -506,7 +502,7 @@ public class TextTreePrinter implements TreePrinter { case CompoundType(Tree[] baseTypes, Tree[] refinements): printArray(baseTypes, Text.None, Text.None, TXT_WITH_SP); - printArray(refinements, TXT_WITH_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline); + printArray(refinements, TXT_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline); break; case AppliedType(Tree tpe, Tree[] args): @@ -649,8 +645,10 @@ public class TextTreePrinter implements TreePrinter { printArray(templ.parents, Text.None, Text.None, TXT_WITH_SP); } - if (templ.body.length > 0) - printArray(templ.body, TXT_WITH_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP); + if (templ.body.length > 0) { + print(Text.Space); + printArray(templ.body, TXT_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP); + } } protected void printParams(Tree.TypeDef[] tparams) { |