diff options
author | Martin Odersky <odersky@gmail.com> | 2005-04-28 17:37:27 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-04-28 17:37:27 +0000 |
commit | 0baff379fd40abb757551c7a02676b051b1c8e17 (patch) | |
tree | 7352cfd392c87bd78781a66a74df0e00346c829e /sources/scala/tools/nsc/ast/parser | |
parent | 6d81466523463b6a7795e841a7cfdf7ad3e06356 (diff) | |
download | scala-0baff379fd40abb757551c7a02676b051b1c8e17.tar.gz scala-0baff379fd40abb757551c7a02676b051b1c8e17.tar.bz2 scala-0baff379fd40abb757551c7a02676b051b1c8e17.zip |
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc/ast/parser')
-rw-r--r-- | sources/scala/tools/nsc/ast/parser/ParserPhase.scala | 4 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/ast/parser/Parsers.scala (renamed from sources/scala/tools/nsc/ast/parser/Syntactic.scala) | 178 | ||||
-rwxr-xr-x[-rw-r--r--] | sources/scala/tools/nsc/ast/parser/Scanners.scala (renamed from sources/scala/tools/nsc/ast/parser/Lexical.scala) | 6 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/parser/Tokens.scala | 26 |
4 files changed, 121 insertions, 93 deletions
diff --git a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala index 0e4e9643a1..008ba70c00 100644 --- a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala +++ b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala @@ -7,8 +7,8 @@ package scala.tools.nsc.ast.parser; abstract class ParserPhase(prev: Phase) extends StdPhase(prev) - with Lexical - with Syntactic { + with Scanners + with Parsers { def name = "parser"; def apply(unit: global.CompilationUnit): unit = { global.informProgress("parsing " + unit); diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Parsers.scala index 479e0a65d6..4e8b098707 100755 --- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala +++ b/sources/scala/tools/nsc/ast/parser/Parsers.scala @@ -6,7 +6,7 @@ package scala.tools.nsc.ast.parser; import scala.tools.util.Position; -import scala.collection.mutable.ListBuffer; +import util.ListBuffer; import symtab.Flags; import Tokens._; @@ -38,7 +38,7 @@ import Tokens._; * (4) Wraps naked case definitions in a match as follows: * { cases } ==> (x => x.match {cases}), except when already argument to match */ -abstract class Syntactic: ParserPhase { +abstract class Parsers: ParserPhase { import global._; import posAssigner.atPos; @@ -56,7 +56,7 @@ abstract class Syntactic: ParserPhase { var loopNestingDepth = 0; object treeBuilder extends TreeBuilder { - val global: Syntactic.this.global.type = Syntactic.this.global; + val global: Parsers.this.global.type = Parsers.this.global; def freshName(prefix: String): Name = unit.fresh.newName(prefix); } import treeBuilder._; @@ -126,7 +126,7 @@ abstract class Syntactic: ParserPhase { /////// TOKEN CLASSES ////////////////////////////////////////////////////// def isModifier: boolean = in.token match { - case ABSTRACT | FINAL | SEALED | PRIVATE | PROTECTED | OVERRIDE => true + case ABSTRACT | FINAL | SEALED | PRIVATE | PROTECTED | OVERRIDE | IMPLICIT => true case _ => false } @@ -741,12 +741,13 @@ abstract class Syntactic: ParserPhase { simpleExpr() } - /* SimpleExpr ::= literal + /* SimpleExpr ::= new SimpleType [`(' [Exprs] `)'] {`with' SimpleType} [TemplateBody] + * | SimpleExpr1 + * SimpleExpr1 ::= literal * | xLiteral * | StableRef * | `(' [Expr] `)' * | BlockExpr - * | new SimpleType [`(' [Exprs] `)'] {`with' SimpleType} [TemplateBody] * | SimpleExpr `.' Id * | SimpleExpr TypeArgs * | SimpleExpr ArgumentExprs @@ -784,7 +785,7 @@ abstract class Syntactic: ParserPhase { case LBRACE => t = blockExpr() case NEW => - t = atPos(in.skipToken()) { + return atPos(in.skipToken()) { val parents = new ListBuffer[Tree] + simpleType(); var args: List[Tree] = List(); if (in.token == LPAREN) args = argumentExprs(); @@ -1058,6 +1059,8 @@ abstract class Syntactic: ParserPhase { loop(addMod(mods, Flags.PROTECTED)) case OVERRIDE => loop(addMod(mods, Flags.OVERRIDE)) + case IMPLICIT => + loop(addMod(mods, Flags.IMPLICIT)) case _ => mods } @@ -1091,48 +1094,60 @@ abstract class Syntactic: ParserPhase { //////// PARAMETERS ////////////////////////////////////////////////////////// - /** ParamClauses ::= {ParamClause} - */ - def paramClauses(ofClass: boolean): List[List[ValDef]] = { - val vds = new ListBuffer[List[ValDef]]; - while (in.token == LPAREN) vds += paramClause(ofClass); - vds.toList - } - - /** ParamClause ::= `(' [Param {`,' Param}] `)' - * ClassParamClause ::= `(' [ClassParam {`,' ClassParam}] `)' - */ - def paramClause(ofClass: boolean): List[ValDef] = { - accept(LPAREN); - val params = new ListBuffer[ValDef]; - if (in.token != RPAREN) { - params += param(ofClass); - while (in.token == COMMA) { - in.nextToken(); params += param(ofClass) - } - } - accept(RPAREN); - params.toList - } - - /** Param ::= Id `:' ParamType + /** ParamClauses ::= {`(' [Param {`,' Param}] ')'} + * [`(' implicit Param {`,' Param} `)'] + * Param ::= Id `:' ParamType + * ClassParamClauses ::= {`(' [ClassParam {`' ClassParam}] ')'} + * [`(' implicit ClassParam {`,' ClassParam} `)'] * ClassParam ::= [[modifiers] val] Param */ - def param(ofClass: boolean): ValDef = { - atPos(in.pos) { - var mods = Flags.PARAM; - if (ofClass) { - mods = modifiers() | Flags.PARAMACCESSOR; - if (in.token == VAL) in.nextToken() - else { - if (mods != Flags.PARAMACCESSOR) accept(VAL); - mods = mods | Flags.PRIVATE | Flags.LOCAL; + def paramClauses(owner: Name, implicitViews: List[Tree], ofCaseClass: boolean): List[List[ValDef]] = { + var implicitmod = 0; + def param(): ValDef = { + atPos(in.pos) { + var mods = Flags.PARAM; + if (owner.isTypeName) { + mods = modifiers() | Flags.PARAMACCESSOR; + if (in.token == VAL) in.nextToken() + else { + if (mods != Flags.PARAMACCESSOR) accept(VAL); + if (!ofCaseClass) mods = mods | Flags.PRIVATE | Flags.LOCAL; + } } + val name = ident(); + accept(COLON); + ValDef(mods | implicitmod, name, paramType(), EmptyTree) } - val name = ident(); - accept(COLON); - ValDef(mods, name, paramType(), EmptyTree) } + def paramClause(): List[ValDef] = { + val params = new ListBuffer[ValDef]; + if (in.token != RPAREN) { + if (in.token == IMPLICIT) { + if (!implicitViews.isEmpty) + syntaxError("cannot have both view bounds `<%' and implicit parameters", false); + in.nextToken(); + implicitmod = Flags.IMPLICIT + } + params += param(); + while (in.token == COMMA) { + in.nextToken(); params += param() + } + } + params.toList + } + val vds = new ListBuffer[List[ValDef]]; + val pos = in.pos; + while (implicitmod == 0 && in.token == LPAREN) { + in.nextToken(); + vds += paramClause(); + accept(RPAREN); + } + val result = vds.toList; + if (owner == nme.CONSTRUCTOR && + (result.isEmpty || (!result.head.isEmpty && + (result.head.head.mods & Flags.IMPLICIT) != 0))) + syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false); + addImplicitViews(result, implicitViews) } /** ParamType ::= Type | `=>' Type | Type `*' @@ -1152,39 +1167,43 @@ abstract class Syntactic: ParserPhase { } /** TypeParamClauseOpt ::= [`[' TypeParam {`,' TypeParam} `]'] + * TypeParam ::= [`+' | `-'] FunTypeParam * FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]'] + * FunTypeParam ::= Id TypeBounds */ - def typeParamClauseOpt(ofClass: boolean): List[AbsTypeDef] = { + def typeParamClauseOpt(owner: Name, implicitViews: ListBuffer[Tree]): List[AbsTypeDef] = { + def typeParam(): AbsTypeDef = { + var mods = Flags.PARAM; + if (owner.isTypeName && in.token == IDENTIFIER) { + if (in.name == PLUS) { + in.nextToken(); + mods = mods | Flags.COVARIANT; + } else if (in.name == MINUS) { + in.nextToken(); + mods = mods | Flags.CONTRAVARIANT; + } + } + val pname = ident(); + val param = atPos(in.pos) { typeBounds(mods, pname) } + if (in.token == VIEWBOUND && (implicitViews != null)) + implicitViews += atPos(in.skipToken()) { + makeFunctionTypeTree(List(Ident(pname.toTypeName)), typ()) + } + param + } val params = new ListBuffer[AbsTypeDef]; if (in.token == LBRACKET) { in.nextToken(); - params += typeParam(ofClass); + params += typeParam(); while (in.token == COMMA) { in.nextToken(); - params += typeParam(ofClass); + params += typeParam(); } accept(RBRACKET); } params.toList } - /** TypeParam ::= [`+' | `-'] FunTypeParam - * FunTypeParam ::= Id TypeBounds - */ - def typeParam(ofClass: boolean): AbsTypeDef = { - var mods = Flags.PARAM; - if (ofClass && in.token == IDENTIFIER) { - if (in.name == PLUS) { - in.nextToken(); - mods = mods | Flags.COVARIANT; - } else if (in.name == MINUS) { - in.nextToken(); - mods = mods | Flags.CONTRAVARIANT; - } - } - atPos(in.pos) { typeBounds(mods, ident()) } - } - /** TypeBounds ::= [`>:' Type] [`<:' Type] */ def typeBounds(mods: int, name: Name): AbsTypeDef = { @@ -1321,14 +1340,14 @@ abstract class Syntactic: ParserPhase { } while (in.token == COMMA); val tp = typedOpt(); val rhs = - if (tp == EmptyTree || in.token == EQUALS) equalsExpr() + if (tp.isEmpty || in.token == EQUALS) equalsExpr() else { newmods = newmods | Flags.DEFERRED; EmptyTree } def mkDefs(p: Tree): List[Tree] = { val trees = - makePatDef(newmods, if (tp == EmptyTree) p else Typed(p, tp), rhs.duplicate) + makePatDef(newmods, if (tp.isEmpty) p else Typed(p, tp), rhs.duplicate) map atPos(p.pos); if (rhs == EmptyTree) { trees match { @@ -1352,7 +1371,7 @@ abstract class Syntactic: ParserPhase { lhs += Pair(in.skipToken(), ident()) } while (in.token == COMMA); val tp = typedOpt(); - val rhs = if (tp == EmptyTree || in.token == EQUALS) { + val rhs = if (tp.isEmpty || in.token == EQUALS) { accept(EQUALS); if (tp != EmptyTree && in.token == USCORE) { in.nextToken(); @@ -1368,7 +1387,7 @@ abstract class Syntactic: ParserPhase { } /** FunDef ::= FunSig `:' Type `=' Expr - * | this ParamClause `=' ConstrExpr + * | this ParamClause ParamClauses `=' ConstrExpr * FunDcl ::= FunSig `:' Type * FunSig ::= id [FunTypeParamClause] ParamClauses */ @@ -1376,17 +1395,18 @@ abstract class Syntactic: ParserPhase { atPos(in.skipToken()) { if (in.token == THIS) { in.nextToken(); - val vparams = List(paramClause(false)); + val vparamss = paramClauses(nme.CONSTRUCTOR, List(), false); accept(EQUALS); - DefDef(mods, nme.CONSTRUCTOR, List(), vparams, TypeTree(), constrExpr()) + DefDef(mods, nme.CONSTRUCTOR, List(), vparamss, TypeTree(), constrExpr()) } else { var newmods = mods; val name = ident(); - val tparams = typeParamClauseOpt(false); - val vparamss = paramClauses(false); + val implicitViews = new ListBuffer[Tree]; + val tparams = typeParamClauseOpt(name, implicitViews); + val vparamss = paramClauses(name, implicitViews.toList, false); val restype = typedOpt(); val rhs = - if (restype == EmptyTree || in.token == EQUALS) equalsExpr(); + if (restype.isEmpty || in.token == EQUALS) equalsExpr(); else { newmods = newmods | Flags.DEFERRED; EmptyTree @@ -1425,7 +1445,7 @@ abstract class Syntactic: ParserPhase { val name = ident().toTypeName; in.token match { case LBRACKET => - val tparams = typeParamClauseOpt(true); + val tparams = typeParamClauseOpt(name, null); accept(EQUALS); AliasTypeDef(mods, name, tparams, typ()) case EQUALS => @@ -1464,11 +1484,15 @@ abstract class Syntactic: ParserPhase { def classDef(mods: int): Tree = atPos(in.skipToken()) { val name = ident().toTypeName; - val tparams = typeParamClauseOpt(true); + val implicitViews = new ListBuffer[Tree]; + val tparams = typeParamClauseOpt(name, implicitViews); if ((mods & Flags.CASE) != 0 && in.token != LPAREN) accept(LPAREN); - val vparamss = paramClauses(true); + val vparamss = paramClauses(name, implicitViews.toList, (mods & Flags.CASE) != 0); val thistpe = simpleTypedOpt(); - val mods1 = if (vparamss.isEmpty && (mods & ABSTRACT) != 0) mods | Flags.TRAIT else mods; + val mods1 = if (vparamss.isEmpty && (mods & Flags.ABSTRACT) != 0) { + if (settings.debug.value) System.out.println("is trait: " + name);//debug + mods | Flags.TRAIT + } else mods; val template = classTemplate(mods1, vparamss); ClassDef(mods1, name, tparams, thistpe, template) } diff --git a/sources/scala/tools/nsc/ast/parser/Lexical.scala b/sources/scala/tools/nsc/ast/parser/Scanners.scala index 318ae77395..91da9b67f0 100644..100755 --- a/sources/scala/tools/nsc/ast/parser/Lexical.scala +++ b/sources/scala/tools/nsc/ast/parser/Scanners.scala @@ -10,7 +10,7 @@ import scala.tools.util.{Position, SourceFile} import SourceFile.{LF, FF, CR, SU} import scala.tools.nsc.util.CharArrayReader; -abstract class Lexical: ParserPhase { +abstract class Scanners: ParserPhase { import global._; @@ -102,7 +102,7 @@ abstract class Lexical: ParserPhase { token match { case ELSE | EXTENDS | WITH | YIELD | CATCH | FINALLY | COMMA | SEMI | DOT | COLON | EQUALS | ARROW | - LARROW | SUBTYPE | SUPERTYPE | HASH | AT | + LARROW | SUBTYPE | VIEWBOUND | SUPERTYPE | HASH | AT | RPAREN | RBRACKET | RBRACE => case _ => if (token == EOF || Position.line(pos) > Position.line(prevpos)) { @@ -728,6 +728,7 @@ abstract class Lexical: ParserPhase { enterKeyword("finally", FINALLY); enterKeyword("for", FOR); enterKeyword("if", IF); + enterKeyword("implicit", IMPLICIT); enterKeyword("import", IMPORT); enterKeyword("match", MATCH); enterKeyword("new", NEW); @@ -758,6 +759,7 @@ abstract class Lexical: ParserPhase { enterKeyword("=>", ARROW); enterKeyword("<-", LARROW); enterKeyword("<:", SUBTYPE); + enterKeyword("<%", VIEWBOUND); enterKeyword(">:", SUPERTYPE); enterKeyword("#", HASH); enterKeyword("@", AT); diff --git a/sources/scala/tools/nsc/ast/parser/Tokens.scala b/sources/scala/tools/nsc/ast/parser/Tokens.scala index 1908ee70f1..90d1b7ad7b 100644 --- a/sources/scala/tools/nsc/ast/parser/Tokens.scala +++ b/sources/scala/tools/nsc/ast/parser/Tokens.scala @@ -43,14 +43,15 @@ object Tokens { val PRIVATE = 34; val PROTECTED = 35; val OVERRIDE = 36; - val VAR = 37; - val DEF = 38; - val TYPE = 39; - val EXTENDS = 40; - val TRUE = 41; - val FALSE = 42; - val OBJECT = 43; - val CLASS = 44; + val IMPLICIT = 37; + val VAR = 38; + val DEF = 39; + val TYPE = 40; + val EXTENDS = 41; + val TRUE = 42; + val FALSE = 43; + val OBJECT = 44; + val CLASS = 45; val IMPORT = 46; val PACKAGE = 47; @@ -75,10 +76,11 @@ object Tokens { val EQUALS = 66; val LARROW = 67; val ARROW = 68; - val SUBTYPE = 69; - val SUPERTYPE = 70; - val HASH = 71; - val AT = 72; + val SUBTYPE = 70; + val SUPERTYPE = 71; + val HASH = 72; + val AT = 73; + val VIEWBOUND = 74; //todo: elim /** parenthesis */ val LPAREN = 90; |