diff options
author | Martin Odersky <odersky@gmail.com> | 2007-02-16 17:38:35 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-02-16 17:38:35 +0000 |
commit | 0e94771489e75df296a84b8f772688d93e0bca19 (patch) | |
tree | 20319806ce3a4579a48aab2d3202fddc037e432d /src | |
parent | 6e23c62953e97277b3e912b81da37fd64556221b (diff) | |
download | scala-0e94771489e75df296a84b8f772688d93e0bca19.tar.gz scala-0e94771489e75df296a84b8f772688d93e0bca19.tar.bz2 scala-0e94771489e75df296a84b8f772688d93e0bca19.zip |
re-enabled stability test; added sections.
Diffstat (limited to 'src')
5 files changed, 80 insertions, 48 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 716e71a907..8934906b26 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -74,8 +74,14 @@ trait Parsers requires SyntaxAnalyzer { def freshName(prefix: String): Name = unit.fresh.newName(prefix) } + /** The implicit view parameters of the surrounding class */ var implicitClassViews: List[Tree] = Nil + /** The implicit parameters introduced by `_' in the current expression. + * Parameters appear in reverse order + */ + var implicitParams: List[ValDef] = Nil + /** this is the general parse method */ def parse(): Tree = { @@ -292,9 +298,9 @@ trait Parsers requires SyntaxAnalyzer { errorTypeTree } - /** make closure from tree */ - def makeClosure(tree: Tree): Tree = { - val pname: Name = unit.fresh.newName("x$") + /** make closure from tree staring with a `.' */ + def makeDotClosure(tree: Tree): Tree = { + val pname = unit.fresh.newName("x$") def insertParam(tree: Tree): Tree = atPos(tree.pos) { tree match { case Ident(name) => @@ -310,10 +316,7 @@ trait Parsers requires SyntaxAnalyzer { errorTermTree } } - - Function( - List(ValDef(Modifiers(Flags.PARAM), pname, TypeTree(), EmptyTree)), - insertParam(tree)) + Function(List(makeSyntheticParam(pname)), insertParam(tree)) } /////// OPERAND/OPERATOR STACK ///////////////////////////////////////////////// @@ -779,25 +782,32 @@ trait Parsers requires SyntaxAnalyzer { * (also eats trailing comma if it finds one) */ def exprs(): List[Tree] = { - val ts = new ListBuffer[Tree] + argExpr() + val savedImplicitParams = implicitParams + implicitParams = List() + var first = expr() + if (!implicitParams.isEmpty) { + first = Function(implicitParams.reverse, first) + implicitParams = List() + } + val ts = new ListBuffer[Tree] + first while (in.token == COMMA) { in.nextToken(); if (in.token == RPAREN) return List(makeTupleTerm(ts.toList, false)) - ts += argExpr() + ts += expr() + if (!implicitParams.isEmpty) { + syntaxError(implicitParams.head.pos, "section outside (...)", false) + } } + implicitParams = savedImplicitParams ts.toList } - /** expression modifiles */ - - final val IsInBlock = 2 - final val ClosureOK = 4 - /** Expr ::= (Bindings | Id) `=>' Expr + * | PostfixExpr `:' Type * | Expr1 * ResultExpr ::= (Bindings | Id `:' CompoundType) `=>' Block * | Expr1 - * Expr1 ::= if (' Expr `)' {nl} Expr [semi] else Expr] + * Expr1 ::= if `(' Expr `)' {nl} Expr [semi] else Expr] * | try `{' block `}' [catch `{' caseClauses `}'] [finally Expr] * | while `(' Expr `)' {nl} Expr * | do Expr [semi] while `(' Expr `)' @@ -816,26 +826,14 @@ trait Parsers requires SyntaxAnalyzer { * | `:' Annotation {Annotation} * | `:' `_' `*' */ - def expr(): Tree = - exprImpl(ClosureOK) + def expr(): Tree = exprImpl(false) + def blockStatExpr(): Tree = exprImpl(true) - def blockStatExpr(): Tree = { - exprImpl(IsInBlock | ClosureOK) - } - - def argExpr(): Tree = { - exprImpl(ClosureOK) - } - - def localExpr(): Tree = { - exprImpl(ClosureOK) - } - - private def exprImpl(mode: int): Tree = in.token match { + private def exprImpl(isInBlock: boolean): Tree = in.token match { case IF => val pos = in.skipToken() accept(LPAREN) - val cond = localExpr() + val cond = expr() accept(RPAREN) newLinesOpt() val thenp = expr() @@ -865,7 +863,7 @@ trait Parsers requires SyntaxAnalyzer { val lname: Name = unit.fresh.newName("while$") val pos = in.skipToken() accept(LPAREN) - val cond = localExpr() + val cond = expr() accept(RPAREN) newLinesOpt() val body = expr() @@ -877,7 +875,7 @@ trait Parsers requires SyntaxAnalyzer { if (isStatSep) in.nextToken() accept(WHILE) accept(LPAREN) - val cond = localExpr() + val cond = expr() accept(RPAREN) atPos(pos) { makeDoWhile(lname, body, cond) } case FOR => @@ -902,8 +900,7 @@ trait Parsers requires SyntaxAnalyzer { case DOT => atPos(in.skipToken()) { if (isIdent) { - makeClosure(stripParens(simpleExpr())) - // Note: makeClosure does some special treatment of liftedGenerators + makeDotClosure(stripParens(simpleExpr())) } else { syntaxErrorOrIncomplete("identifier expected", true) errorTermTree @@ -933,7 +930,7 @@ trait Parsers requires SyntaxAnalyzer { } } else if (annots.isEmpty || isTypeIntro) { t = atPos(pos) { - val tpt = if ((mode & IsInBlock) != 0) compoundType(false) else typ() + val tpt = if (isInBlock) compoundType(false) else typ() // this does not correspond to syntax, but is necessary to // accept closures. We might restrict closures to be between {...} only! Typed(t, (tpt /: annots) (makeAnnotated)) @@ -949,9 +946,9 @@ trait Parsers requires SyntaxAnalyzer { Match(stripParens(t), cases) } } - if ((mode & ClosureOK) != 0 && in.token == ARROW) { + if (in.token == ARROW) { t = atPos(in.skipToken()) { - Function(convertToParams(t), if ((mode & IsInBlock) != 0) block() else expr()) + Function(convertToParams(t), if (isInBlock) block() else expr()) } } stripParens(t) @@ -1036,6 +1033,12 @@ trait Parsers requires SyntaxAnalyzer { t = xmlp.xLiteral case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER => t = path(true, false) + case USCORE => + val pname = unit.fresh.newName("x$") + val pos = in.skipToken() + val param = makeSyntheticParam(pname) setPos pos + implicitParams = param :: implicitParams + t = atPos(pos) { Ident(pname) } case LPAREN => val pos = in.skipToken() val ts = if (in.token == RPAREN) List() else exprs() diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index b197940207..f3685365d2 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -207,6 +207,9 @@ abstract class TreeBuilder { if (valeq) ValEq(pos, pat1, rhs1) else ValFrom(pos, pat1, rhs1) } + def makeSyntheticParam(pname: Name) = + ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) + abstract class Enumerator case class ValFrom(pos: int, pat: Tree, rhs: Tree) extends Enumerator case class ValEq(pos: int, pat: Tree, rhs: Tree) extends Enumerator @@ -371,8 +374,7 @@ abstract class TreeBuilder { def makeVisitor(cases: List[CaseDef], checkExhaustive: boolean, prefix: String): Tree = { val x = freshName(prefix) val sel = if (checkExhaustive) Ident(x) else makeUnsealed(Ident(x)) - Function(List(ValDef(Modifiers(PARAM | SYNTHETIC), x, TypeTree(), EmptyTree)), - Match(sel, cases)) + Function(List(makeSyntheticParam(x)), Match(sel, cases)) } /** Create tree for case definition <case pat if guard => rhs> */ diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala index 9e8b55e678..5b26443932 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala @@ -52,11 +52,11 @@ object PickleFormat { * | 35 LITERALclass len_Nat type_Ref * | 40 ATTRIBUTE len_Nat sym_Ref info_Ref {constant_Ref} {nameRef constantRef} * | 41 CHILDREN len_Nat sym_Ref {sym_Ref} - * | 72 PosTYPEsym len_Nat pos_Nat SymbolInfo - * | 73 PosALIASsym len_Nat pos_Nat SymbolInfo - * | 74 PosCLASSsym len_Nat pos_Nat SymbolInfo [thistype_Ref] - * | 75 PosMODULEsym len_Nat pos_Nat SymbolInfo - * | 76 PosVALsym len_Nat pos_Nat SymbolInfo [alias_Ref] + * | 68 PosTYPEsym len_Nat pos_Nat SymbolInfo + * | 69 PosALIASsym len_Nat pos_Nat SymbolInfo + * | 70 PosCLASSsym len_Nat pos_Nat SymbolInfo [thistype_Ref] + * | 71 PosMODULEsym len_Nat pos_Nat SymbolInfo + * | 72 PosVALsym len_Nat pos_Nat SymbolInfo [alias_Ref] * SymbolInfo = name_Ref owner_Ref flags_Nat [privateWithin_Ref] info_Ref * NameInfo = <character sequence of length len_Nat in Utf8 format> * NumInfo = <len_Nat-byte signed number in big endian format> @@ -110,4 +110,10 @@ object PickleFormat { final val firstTypeTag = NOtpe final val lastTypeTag = POLYtpe final val PosOffset = 64 + + final val PosTYPEsym = PosOffset + TYPEsym + final val PosALIASsym = PosOffset + ALIASsym + final val PosCLASSsym = PosOffset + CLASSsym + final val PosMODULEsym = PosOffset + MODULEsym + final val PosVALsym = PosOffset + VALsym } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index ebe7c6d763..cbd18d2500 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -109,7 +109,7 @@ abstract class Pickler extends SubComponent { putType(sym.typeOfThis); putSymbol(sym.alias) if (!sym.children.isEmpty) - putChildren(sym, sym.children) + putChildren(sym, sym.children.toList.sort((x, y) => x isLess y)) for (val attr <- sym.attributes.reverse) { if (attr.atp.symbol isNonBottomSubClass definitions.StaticAnnotationClass) @@ -168,7 +168,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == ClassTag) putEntry(c.typeValue) } - private def putChildren(sym: Symbol, children: Set[Symbol]): unit = { + private def putChildren(sym: Symbol, children: List[Symbol]): unit = { assert(putEntry(Pair(sym, children))) children foreach putSymbol } @@ -285,7 +285,7 @@ abstract class Pickler extends SubComponent { for (val c <- args) writeRef(c) for (val Pair(name, c) <- assocs) { writeRef(name); writeRef(c) } ATTRIBUTE - case Pair(target: Symbol, children: Set[_]) => + case Pair(target: Symbol, children: List[_]) => writeRef(target) for (val c <- children) writeRef(c.asInstanceOf[Symbol]) CHILDREN @@ -306,6 +306,10 @@ abstract class Pickler extends SubComponent { writeNat(ep) if (settings.debug.value) log("" + ep + " entries")//debug for (val i <- 0 until ep) writeEntry(entries(i)); + if (settings.Xshowcls.value == rootName.toString) { + readIndex = 0 + ShowPickled.printFile(this, Console.out) + } } override def toString() = "" + rootName + " in " + rootOwner diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 115aa4eb9d..df7374778a 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -52,6 +52,13 @@ object ShowPickled extends Names { case LITERALstring => "LITERALstring" case LITERALnull => "LITERALnull" case LITERALclass => "LITERALclass" + case ATTRIBUTE => "ATTRIBUTE" + case CHILDREN => "CHILDREN" + case PosTYPEsym => "PosTYPEsym" + case PosALIASsym => "PosALIASsym" + case PosCLASSsym => "PosCLASSsym" + case PosMODULEsym => "PosMODULEsym" + case PosVALsym => "PosVALsym" case _ => "***BAD TAG***(" + tag + ")" } @@ -103,6 +110,10 @@ object ShowPickled extends Names { case TYPEsym | ALIASsym | CLASSsym | MODULEsym | VALsym => printSymInfo() if (tag == CLASSsym && (buf.readIndex < end)) printTypeRef() + case PosTYPEsym | PosALIASsym | PosCLASSsym | PosMODULEsym | PosVALsym => + printNat() + printSymInfo() + if (tag == CLASSsym && (buf.readIndex < end)) printTypeRef() case EXTref | EXTMODCLASSref => printNameRef() if (buf.readIndex < end) { printSymbolRef() } @@ -144,6 +155,12 @@ object ShowPickled extends Names { printNameRef() case LITERALnull => out.print(" <null>") + case LITERALclass => + printTypeRef() + case ATTRIBUTE => + printSymbolRef(); printTypeRef(); buf.until(end, printConstantRef) + case CHILDREN => + printSymbolRef(); buf.until(end, printSymbolRef) case _ => } out.println() |