summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/ast/parser
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-04-28 17:37:27 +0000
committerMartin Odersky <odersky@gmail.com>2005-04-28 17:37:27 +0000
commit0baff379fd40abb757551c7a02676b051b1c8e17 (patch)
tree7352cfd392c87bd78781a66a74df0e00346c829e /sources/scala/tools/nsc/ast/parser
parent6d81466523463b6a7795e841a7cfdf7ad3e06356 (diff)
downloadscala-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.scala4
-rwxr-xr-xsources/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.scala26
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;