diff options
author | Martin Odersky <odersky@gmail.com> | 2006-03-31 15:53:37 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-03-31 15:53:37 +0000 |
commit | fde7c4cb46c91e05c7ff18a13d528e1b4a458422 (patch) | |
tree | 6ad3949c4aabedf640ae712a96a63d9639b94512 | |
parent | 5993e28ec5832368e1c1e8fa80679540465f75a9 (diff) | |
download | scala-fde7c4cb46c91e05c7ff18a13d528e1b4a458422.tar.gz scala-fde7c4cb46c91e05c7ff18a13d528e1b4a458422.tar.bz2 scala-fde7c4cb46c91e05c7ff18a13d528e1b4a458422.zip |
added conversion from methods to functions usin...
added conversion from methods to functions using prefix operator `&'
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 19 | ||||
-rw-r--r-- | test/files/run/Course-2002-02.scala | 12 |
3 files changed, 28 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 1cff3732f9..5ad34ef612 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -313,6 +313,7 @@ trait Parsers requires SyntaxAnalyzer { final val PLUS : Name = "+"; final val BANG : Name = "!"; final val TILDE: Name = "~"; + final val AMP : Name = "&"; final val STAR : Name = "*"; final val BAR : Name = "|"; final val OPT : Name = "?"; @@ -768,7 +769,7 @@ trait Parsers requires SyntaxAnalyzer { reduceStack(true, base, top, 0, true) } - /** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr + /** PrefixExpr ::= [`-' | `+' | `~' | `!' | `&'] SimpleExpr */ def prefixExpr(): Tree = if (in.token == IDENTIFIER && in.name == MINUS) { @@ -781,6 +782,10 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.currentPos; val name = ident(); atPos(pos) { Select(simpleExpr(), name) } + } else if (in.token == IDENTIFIER && in.name == AMP) { + val pos = in.currentPos; + val name = ident(); + atPos(pos) { Typed(simpleExpr(), Function(List(), EmptyTree)) } } else { simpleExpr() } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d556609f6b..680de70cf9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3,7 +3,7 @@ * @author Martin Odersky */ // $Id$ -//todo: rewrite or disallow new T where T is a mixin (currently: <init> not a member of T) +//todo: rewrite or disllow new T where T is a mixin (currently: <init> not a member of T) package scala.tools.nsc.typechecker import symtab.Flags._ @@ -23,7 +23,7 @@ trait Typers requires Analyzer { var implcnt = 0 var impltime = 0l - final val xviews = false + final val xviews = true private val transformed = new HashMap[Tree, Tree] @@ -386,7 +386,9 @@ trait Typers requires Analyzer { if (settings.migrate.value && !tree.symbol.isConstructor && isCompatible(mt, pt)) error(tree.pos, migrateMsg + " method can be converted to function only if an expected function type is given"); else - error(tree.pos, "missing arguments for "+tree.symbol+tree.symbol.locationString) + error(tree.pos, "missing arguments for "+tree.symbol+tree.symbol.locationString+ + if (tree.symbol.isConstructor) "" + else ";\nprefix this method with `&' if you want to treat it as a partially applied function") } setError(tree) } @@ -1431,6 +1433,17 @@ trait Typers requires Analyzer { error(tree.pos, ""+tpt1.tpe.symbol+" is abstract; cannot be instantiated") copy.New(tree, tpt1).setType(tpt1.tpe) + case Typed(expr, Function(List(), EmptyTree)) => + val expr1 = typed1(expr, mode, pt); + expr1.tpe match { + case MethodType(formals, _) => + adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) + case ErrorType => + expr1 + case _ => + errorTree(expr1, "`&' must be applied to method type; cannot be applied to " + expr1.tpe) + } + case Typed(expr, tpt @ Ident(name)) if (name == nme.WILDCARD_STAR.toTypeName) => val expr1 = typed(expr, mode & stickyModes, seqType(pt)) expr1.tpe.baseType(SeqClass) match { diff --git a/test/files/run/Course-2002-02.scala b/test/files/run/Course-2002-02.scala index 435b84484f..8983829d79 100644 --- a/test/files/run/Course-2002-02.scala +++ b/test/files/run/Course-2002-02.scala @@ -140,9 +140,9 @@ object M6 { if (a > b) 0 else f(a) + sum(f)(a + 1, b); - def sumInts: (Int, Int) => Double = sum(x => x); - def sumCubes: (Int, Int) => Double = sum(x => x * x * x); - def sumReciprocals: (Int, Int) => Double = sum(x => 1.0/x); + def sumInts = &sum(x => x); + def sumCubes = &sum(x => x * x * x); + def sumReciprocals = &sum(x => 1.0/x); def sumPi = (n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n)); Console.println(sumInts(1,4)); @@ -163,9 +163,9 @@ object M7 { iter(a, 0) } - def sumInts: (Int, Int) => Double = sum(x => x); - def sumCubes: (Int, Int) => Double = sum(x => x * x * x); - def sumReciprocals: (Int, Int) => Double = sum(x => 1.0/x); + def sumInts = &sum(x => x); + def sumCubes = &sum(x => x * x * x); + def sumReciprocals = &sum(x => 1.0/x); def sumPi = (n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n)); Console.println(sumInts(1,4)); |