summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-04-11 16:22:28 +0000
committerMartin Odersky <odersky@gmail.com>2006-04-11 16:22:28 +0000
commite3fc3506c7c918aba5cc7c3baabca95de8f6ac4c (patch)
tree67c1ec643f9b418914e0f82341785cd7860d77d1 /src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
parenta0c48ce649c3d320623a3369b8ade2665b71f613 (diff)
downloadscala-e3fc3506c7c918aba5cc7c3baabca95de8f6ac4c.tar.gz
scala-e3fc3506c7c918aba5cc7c3baabca95de8f6ac4c.tar.bz2
scala-e3fc3506c7c918aba5cc7c3baabca95de8f6ac4c.zip
1. Allowed local implicits
2. Small change in syntax to make postfix operators more robust 3. Suppresses duplicate and redundant error messages 4. Improve `bad signature' diagnostics
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/Parsers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala58
1 files changed, 34 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 1d73da9005..35bb620932 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -151,7 +151,7 @@ trait Parsers requires SyntaxAnalyzer {
}
def isLocalModifier: boolean = in.token match {
- case ABSTRACT | FINAL | SEALED => true
+ case ABSTRACT | FINAL | SEALED | IMPLICIT => true
case _ => false
}
@@ -166,7 +166,7 @@ trait Parsers requires SyntaxAnalyzer {
case _ => false
}
- def isExprIntro: boolean = in.token match {
+ def isExprIntroToken(token: int): boolean = token match {
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL | IDENTIFIER |
THIS | SUPER | IF | FOR | NEW | USCORE | TRY | WHILE |
@@ -174,6 +174,8 @@ trait Parsers requires SyntaxAnalyzer {
case _ => false
}
+ def isExprIntro: boolean = isExprIntroToken(in.token)
+
/////// COMMENT AND ATTRIBUTE COLLECTION //////////////////////////////////////
/** Join the comment associated with a definition
@@ -467,8 +469,15 @@ trait Parsers requires SyntaxAnalyzer {
in.nextToken();
}
- def newLineOptWhenFollowedBy(token: int): unit =
- if (in.token == NEWLINE && in.next.token == token) newLineOpt();
+ def newLineOptWhenFollowedBy(token: int): unit = {
+ // note: next is defined here because current == NEWLINE
+ if (in.token == NEWLINE && in.next.token == token) newLineOpt()
+ }
+
+ def newLineOptWhenFollowing(p: int => boolean): unit = {
+ // note: next is defined here because current == NEWLINE
+ if (in.token == NEWLINE && p(in.next.token)) newLineOpt()
+ }
//////// TYPES ///////////////////////////////////////////////////////////////
@@ -755,7 +764,7 @@ trait Parsers requires SyntaxAnalyzer {
true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name));
opstack = OpInfo(top, in.name, in.currentPos) :: opstack;
ident();
- newLineOpt();
+ newLineOptWhenFollowing(isExprIntroToken);
if (isExprIntro) {
top = prefixExpr();
} else {
@@ -1116,9 +1125,9 @@ trait Parsers requires SyntaxAnalyzer {
////////// MODIFIERS ////////////////////////////////////////////////////////////
/** Modifiers ::= {Modifier}
- * Modifier ::= LocalClassModifier
+ * Modifier ::= LocalModifier
* | private [ "[" Id "]" ]
- * | protected | override | implicit
+ * | protected | override
*/
def modifiers(): Modifiers = {
var privateWithin: Name = nme.EMPTY.toTypeName;
@@ -1153,10 +1162,10 @@ trait Parsers requires SyntaxAnalyzer {
Modifiers(mods, privateWithin)
}
- /** LocalClassModifiers ::= {LocalClassModifier}
- * LocalClassModifier ::= abstract | mixin | final | sealed
+ /** LocalModifiers ::= {LocalModifier}
+ * LocalModifier ::= abstract | final | sealed | implicit
*/
- def localClassModifiers(): Modifiers = {
+ def localModifiers(): Modifiers = {
def loop(mods: int): int = in.token match {
case ABSTRACT =>
loop(addMod(mods, Flags.ABSTRACT))
@@ -1164,6 +1173,8 @@ trait Parsers requires SyntaxAnalyzer {
loop(addMod(mods, Flags.FINAL))
case SEALED =>
loop(addMod(mods, Flags.SEALED))
+ case IMPLICIT =>
+ loop(addMod(mods, Flags.IMPLICIT))
case _ =>
mods
}
@@ -1828,12 +1839,22 @@ trait Parsers requires SyntaxAnalyzer {
/** BlockStatSeq ::= { BlockStat StatementSeparator } [ResultExpr]
* BlockStat ::= Import
- * | Def
+ * | [implicit] Def
* | LocalModifiers TmplDef
* | Expr1
* |
*/
def blockStatSeq(stats: ListBuffer[Tree]): List[Tree] = {
+ def localDef(mods: Modifiers) = {
+ if (!(mods hasFlag ~Flags.IMPLICIT)) stats ++= defOrDcl(mods)
+ else stats += tmplDef(mods)
+ if (in.token == RBRACE || in.token == CASE)
+ syntaxError("block must end in result expression, not in definition", false)
+ else
+ acceptStatSep()
+ if (in.token == RBRACE || in.token == CASE)
+ stats += Literal(()).setPos(in.currentPos)
+ }
while ((in.token != RBRACE) && (in.token != EOF) && (in.token != CASE)) {
if (in.token == IMPORT) {
stats ++= importClause();
@@ -1842,20 +1863,9 @@ trait Parsers requires SyntaxAnalyzer {
stats += expr(false, true);
if (in.token != RBRACE && in.token != CASE) acceptStatSep();
} else if (isDefIntro) {
- stats ++= defOrDcl(NoMods);
- if (in.token == RBRACE || in.token == CASE)
- syntaxError("block must end in result expression, not in definition", false)
- else
- acceptStatSep();
- if (in.token == RBRACE || in.token == CASE) {
- stats += Literal(()).setPos(in.currentPos)
- }
+ localDef(NoMods)
} else if (isLocalModifier) {
- stats += tmplDef(localClassModifiers());
- acceptStatSep();
- if (in.token == RBRACE || in.token == CASE) {
- stats += Literal(()).setPos(in.currentPos)
- }
+ localDef(localModifiers())
} else if (in.token == SEMI || in.token == NEWLINE) {
in.nextToken();
} else {