summaryrefslogtreecommitdiff
path: root/sources/scalac/ast/parser
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/ast/parser')
-rw-r--r--sources/scalac/ast/parser/Parser.java94
-rw-r--r--sources/scalac/ast/parser/Scanner.java11
-rw-r--r--sources/scalac/ast/parser/Tokens.java29
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,