diff options
author | Martin Odersky <odersky@gmail.com> | 2006-04-11 16:22:28 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-04-11 16:22:28 +0000 |
commit | e3fc3506c7c918aba5cc7c3baabca95de8f6ac4c (patch) | |
tree | 67c1ec643f9b418914e0f82341785cd7860d77d1 /src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | |
parent | a0c48ce649c3d320623a3369b8ade2665b71f613 (diff) | |
download | scala-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.scala | 58 |
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 { |