diff options
Diffstat (limited to 'sources/scalac/ast/parser')
-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 |
3 files changed, 85 insertions, 49 deletions
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, |