diff options
19 files changed, 615 insertions, 40 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala index f8d213013d..4fc37dab5b 100644 --- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala +++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala @@ -121,7 +121,7 @@ with RightTracers { _ : Literal => ; // no variables case _ => - error("unknown pattern node:" + tree + " = " + tree.getClass()); + cunit.error(tree.pos, "unknown pattern node:" + tree + " = " + tree.getClass()); } } traverse(pat); @@ -243,7 +243,7 @@ with RightTracers { //case _ => // Console.println(pat); // Console.println(pat.getClass()); - // scala.Predef.error(" what is this ? ") + // scala.Predef.error"( what is this ? ") } var res:List[CaseDef] = Nil; @@ -295,7 +295,8 @@ with RightTracers { */ System.out.println("" + sel + " match " + ocases); - scala.Predef.error("regular expressions not yet implemented"); + cunit.error(sel.pos, "regular expressions not yet implemented"); + sel } else { val pm = new PatternMatcher(); pm.initialize(sel, currentOwner, true ); diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 111ef5f6e5..2ba86159d8 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -964,7 +964,9 @@ trait Symbols requires SymbolTable { override def cloneSymbolImpl(owner: Symbol): Symbol = { throw new Error("should not clone a type skolem"); } - override def nameString: String = super.nameString + "&"; + override def nameString: String = + if (settings.debug.value) (super.nameString + "&") + else super.nameString; } /** A class for class symbols */ diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ea474a68bb..45367bf440 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -125,6 +125,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { } else transformMixinInfo(erasure(tp)); + val deconstMap = new TypeMap { + def apply(tp: Type): Type = tp match { + case PolyType(_, _) => mapOver(tp) + case MethodType(_, _) => mapOver(tp) + case _ => tp.deconst + } + } + // -------- boxing/unboxing -------------------------------------------------------- override def newTyper(context: Context) = new Eraser(context); @@ -477,6 +485,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { val otpe = erasure(other.tpe); val bridgeNeeded = atPhase(phase.next) ( !(other.tpe =:= member.tpe) && + !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) && { var e = bridgesScope.lookupEntry(member.name); while (e != null && !((e.sym.tpe =:= otpe) && (bridgeTarget(e.sym) == member))) e = bridgesScope.lookupNextEntry(e); diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 0da9ee6177..d4833ba155 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -71,6 +71,7 @@ trait Contexts requires Analyzer { // after the this constructor call? var reportAmbiguousErrors = false; var reportGeneralErrors = false; + var implicitsEnabled = false; var checking = false; var savedTypeBounds: List[Pair[Symbol, Type]] = List(); @@ -102,6 +103,7 @@ trait Contexts requires Analyzer { c.imports = imports; c.reportAmbiguousErrors = this.reportAmbiguousErrors; c.reportGeneralErrors = this.reportGeneralErrors; + c.implicitsEnabled = this.implicitsEnabled; c.checking = this.checking; c.outer = this; c @@ -111,6 +113,7 @@ trait Contexts requires Analyzer { val c = make(unit, EmptyTree, owner, scope, imports); c.reportAmbiguousErrors = true; c.reportGeneralErrors = true; + c.implicitsEnabled = true; c } @@ -133,6 +136,7 @@ trait Contexts requires Analyzer { val c = make(tree); c.reportAmbiguousErrors = reportAmbiguousErrors; c.reportGeneralErrors = false; + c.implicitsEnabled = false; c } diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 5df8be1170..9cabd952f0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -667,16 +667,20 @@ trait Infer requires Analyzer { /** Try inference twice, once without views and once with views, unless views are already disabled. */ def tryTwice(infer: => unit): unit = { - if (context.reportGeneralErrors) { + if (context.implicitsEnabled) { + val reportGeneralErrors = context.reportGeneralErrors; context.reportGeneralErrors = false; + context.implicitsEnabled = false; try { infer } catch { case ex: TypeError => - context.reportGeneralErrors = true; + context.reportGeneralErrors = reportGeneralErrors; + context.implicitsEnabled = true; infer } - context.reportGeneralErrors = true + context.reportGeneralErrors = reportGeneralErrors + context.implicitsEnabled = true } else infer } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 63edcdb412..78197a0ab3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -22,6 +22,8 @@ trait Typers requires Analyzer { var implcnt = 0 var impltime = 0l + final val xviews = false + private val transformed = new HashMap[Tree, Tree] private val superDefs = new HashMap[Symbol, ListBuffer[Tree]] @@ -40,7 +42,7 @@ trait Typers requires Analyzer { val infer = new Inferencer(context0) { override def isCoercible(tp: Type, pt: Type): boolean = ( tp.isError || pt.isError || - context0.reportGeneralErrors && // this condition prevents chains of views + context0.implicitsEnabled && // this condition prevents chains of views inferView(Position.NOPOS, tp, pt, false) != EmptyTree ) } @@ -56,10 +58,10 @@ trait Typers requires Analyzer { } } - private def inferView(pos: int, from: Type, name: Name, reportAmbiguous: boolean): Tree = { + private def inferView(pos: int, from: Type, name: Name, tp: Type, reportAmbiguous: boolean): Tree = { val to = refinedType(List(WildcardType), NoSymbol) val psym = (if (name.isTypeName) to.symbol.newAbstractType(pos, name) - else to.symbol.newValue(pos, name)) setInfo WildcardType + else to.symbol.newValue(pos, name)) setInfo tp to.decls.enter(psym) inferView(pos, from, to, reportAmbiguous) } @@ -101,6 +103,10 @@ trait Typers requires Analyzer { val SUPERCONSTRmode = 0x100; // Set for the `super' in a superclass constructor call // super.<init> + val SNDTRYmode = 0x200; // indicates that an application is typed for the 2nd + // time. In that case functions may no longer be + // be coerced with implicit views. + private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode /** Report a type error. @@ -121,7 +127,7 @@ trait Typers requires Analyzer { case _ => ex.getMessage() } - if (settings.debug.value) ex.printStackTrace() + //if (settings.debug.value) ex.printStackTrace()//DEBUG if (context.reportGeneralErrors) error(pos, msg) else throw new TypeError(msg) } @@ -369,7 +375,7 @@ trait Typers requires Analyzer { } else if (!tree.symbol.isConstructor && mt.paramTypes.isEmpty) { // (4.3) adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt) } else { - if (context.reportGeneralErrors) { + if (context.implicitsEnabled) { 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 @@ -451,7 +457,7 @@ trait Typers requires Analyzer { return typed(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt) case _ => } - if (context.reportGeneralErrors && !tree.tpe.isError && !pt.isError) { + if (context.implicitsEnabled && !tree.tpe.isError && !pt.isError) { // (13); the condition prevents chains of views if (settings.debug.value) log("inferring view from "+tree.tpe+" to "+pt) val coercion = inferView(tree.pos, tree.tpe, pt, true) @@ -470,15 +476,19 @@ trait Typers requires Analyzer { // adapt(tree, mode, pt) // } - def adaptToName(qual: Tree, name: Name): Tree = + def adaptToMember(qual: Tree, name: Name, tp: Type): Tree = if (qual.isTerm && (qual.symbol == null || qual.symbol.isValue) && - !phase.erasedTypes && !qual.tpe.widen.isError && - qual.tpe.nonLocalMember(name) == NoSymbol) { - val coercion = inferView(qual.pos, qual.tpe, name, true) - if (coercion != EmptyTree) typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual)))) + !phase.erasedTypes && !qual.tpe.widen.isError) { + val coercion = inferView(qual.pos, qual.tpe, name, tp, true) + if (coercion != EmptyTree) + typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual)))) else qual } else qual + def adaptToName(qual: Tree, name: Name) = + if (qual.tpe.nonLocalMember(name) != NoSymbol) qual + else adaptToMember(qual, name, WildcardType) + private def completeParentType(tpt: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = { enclTparams foreach context.scope.enter namer.enterValueParams(context.owner, vparamss) @@ -980,10 +990,12 @@ trait Typers requires Analyzer { argTyper.typed(arg, mode & stickyModes, pt) } + def typedArgs(args: List[Tree]) = + List.mapConserve(args)(arg => typedArg(arg, WildcardType)) + def typedApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { case OverloadedType(pre, alts) => - val args1 = List.mapConserve(args)(arg => - typedArg(arg, WildcardType)) + val args1 = typedArgs(args) inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt) typedApply(adapt(fun, funmode, WildcardType), args1) case MethodType(formals0, restpe) => @@ -1034,6 +1046,31 @@ trait Typers requires Analyzer { errorTree(tree, ""+fun+" does not take parameters") } + def tryTypedApply(fun: Tree, args: List[Tree]): Tree = { + val reportGeneralErrors = context.reportGeneralErrors + val reportAmbiguousErrors = context.reportAmbiguousErrors + try { + context.reportGeneralErrors = false + context.reportAmbiguousErrors = false + typedApply(fun, args) + } catch { + case ex: TypeError => + val args1 = typedArgs(args) + val Select(qual, name) = fun + context.reportGeneralErrors = reportGeneralErrors + context.reportAmbiguousErrors = reportAmbiguousErrors + val qual1 = adaptToMember(qual, name, MethodType(args1 map (.tpe), pt)) + if (qual1 eq qual) typedApply(fun, args) + else + typed1( + Apply(Select(qual1, name) setPos fun.pos, args) setPos tree.pos, + mode | SNDTRYmode, pt) + } finally { + context.reportGeneralErrors = reportGeneralErrors + context.reportAmbiguousErrors = reportAmbiguousErrors + } + } + /** Attribute a selection where `tree' is `qual.name'. * `qual' is already attributed. */ @@ -1397,7 +1434,11 @@ trait Typers requires Analyzer { fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType) } if (util.Statistics.enabled) appcnt = appcnt + 1 - typedApply(fun1, args) + if (xviews && + fun1.isInstanceOf[Select] && + !fun1.tpe.isInstanceOf[ImplicitMethodType] && + (mode & (EXPRmode | SNDTRYmode)) == EXPRmode) tryTypedApply(fun1, args) + else typedApply(fun1, args) } case Super(qual, mix) => @@ -1417,7 +1458,7 @@ trait Typers requires Analyzer { else { val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix) if (ps.isEmpty) { - System.out.println(clazz.info.parents map (.symbol.name));//debug + if (settings.debug.value) System.out.println(clazz.info.parents map (.symbol.name));//debug error(tree.pos, ""+mix+" does not name a base class of "+clazz) ErrorType } else ps.head @@ -1498,7 +1539,7 @@ trait Typers requires Analyzer { errorTree(tree, ""+tpt1.tpe+" does not take type parameters") } else { //System.out.println("\{tpt1}:\{tpt1.symbol}:\{tpt1.symbol.info}") - System.out.println(""+tpt1+":"+tpt1.symbol+":"+tpt1.symbol.info);//debug + if (settings.debug.value) System.out.println(""+tpt1+":"+tpt1.symbol+":"+tpt1.symbol.info);//debug errorTree(tree, "wrong number of type arguments for "+tpt1.tpe+", should be "+tparams.length) } case _ => @@ -1694,7 +1735,7 @@ trait Typers requires Analyzer { if (arg != EmptyTree) arg else errorTree(tree, "no implicit argument matching parameter type "+pt+" was found.") } - Apply(tree, formals map implicitArg) setPos tree.pos + Apply(tree, formals map implicitArg) setPos tree.pos } } } diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala new file mode 100755 index 0000000000..fd877f6124 --- /dev/null +++ b/src/library/scala/BigInt.scala @@ -0,0 +1,331 @@ +package scala; + +import java.math.BigInteger +import java.util.Random + +/** + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +object BigInt { + + private val minCached = -1024; + private val maxCached = 1024; + private val cache = new Array[BigInt](maxCached - minCached + 1) + + /** Constructs a BigInt whose value is equal to that of the specified integer value. + */ + def apply(i: Int): BigInt = + if (minCached <= i && i <= maxCached) { + var n = cache(i) + if (n == null) { n = new BigInt(BigInteger.valueOf(i)); cache(i) = n } + n + } else new BigInt(BigInteger.valueOf(i)) + + /** Constructs a BigInt whose value is equal to that of the specified long value. + */ + def apply(l: Long): BigInt = + if (minCached <= l && l <= maxCached) apply(l.toInt) + else new BigInt(BigInteger.valueOf(l)) + + /** Translates a byte array containing the two's-complement binary + * representation of a BigInt into a BigInt. + */ + def apply(x: Array[byte]): BigInt = + new BigInt(new BigInteger(x)) + + /** Translates the sign-magnitude representation of a BigInt into a BigInt. + */ + def apply(signum: Int, magnitude: Array[byte]): BigInt = + new BigInt(new BigInteger(signum, magnitude)) + + /** Constructs a randomly generated positive BigInt that is probably prime, + * with the specified bitLength. + */ + def apply(bitlength: Int, certaInty: Int, rnd: Random): BigInt = + new BigInt(new BigInteger(bitlength, certaInty, rnd)) + + /** Constructs a randomly generated BigInt, uniformly distributed over the range + * 0 to (2 ^ numBits - 1), inclusive. + */ + def apply(numbits: Int, rnd: Random): BigInt = + new BigInt(new BigInteger(numbits, rnd)) + + /** Translates the decimal String representation of a BigInt into a BigInt. + */ + def apply(x: String): BigInt = + new BigInt(new BigInteger(x)) + + /** Translates the String representation of a BigInt in the + * specified radix into a BigInt. + */ + def apply(x: String, radix: Int): BigInt = + new BigInt(new BigInteger(x, radix)) + + /** Returns a positive BigInt that is probably prime, with the specified bitLength. + */ + def probablePrime(bitLength: Int, rnd: Random): BigInt = + new BigInt(BigInteger.probablePrime(bitLength, rnd)) + + /** Implicit conversion from int to BigInt + */ + implicit def int2bigInt(i: Int): BigInt = apply(i) + + /** Implicit copnversion from long to BigInt + */ + implicit def long2bigInt(l: Long): BigInt = apply(l) + + /** Implicit conversion from BigInt to Ordered + */ + implicit def bigInt2ordered(x: BigInt): Ordered[BigInt] = new Ordered[BigInt] with Proxy { + def self: Any = x; + def compareTo [b >: BigInt <% Ordered[b]](y: b): Int = y match { + case y: BigInt => x.bigInteger.compareTo(y.bigInteger) + case _ => -(y compareTo x) + } + } +} + +[serializable] +class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber { + + /** Returns the hash code for this BigInt. */ + override def hashCode(): Int = this.bigInteger.hashCode() + + /** Compares this BigInt with the specified value for equality. + */ + override def equals (that: Any): boolean = that match { + case that: runtime.BoxedDouble => this.bigInteger.doubleValue == that + case that: runtime.BoxedFloat => this.bigInteger.floatValue == that + case that: runtime.BoxedNumber => this equals BigInt(that.longValue) + case _ => false + } + + /** Compares this BigInt with the specified BigInt for equality. + */ + def equals (that: BigInt): boolean = + this.bigInteger.compareTo(that.bigInteger) == 0 + + /** Compares this BigInt with the specified BigInt + */ + def compareTo (that: BigInt): int = this.bigInteger.compareTo(that.bigInteger) + + /** Less-than-or-equals comparison of BigInts + */ + def <= (that: BigInt): boolean = this.bigInteger.compareTo(that.bigInteger) <= 0 + + /** Greater-than-or-equals comparison of BigInts + */ + def >= (that: BigInt): boolean = this.bigInteger.compareTo(that.bigInteger) >= 0 + + /** Less-than of BigInts + */ + def < (that: BigInt): boolean = this.bigInteger.compareTo(that.bigInteger) < 0 + + /** Greater-than comparison of BigInts + */ + def > (that: BigInt): boolean = this.bigInteger.compareTo(that.bigInteger) >= 0 + + /** Addition of BigInts + */ + def + (that: BigInt): BigInt = new BigInt(this.bigInteger.add(that.bigInteger)) + + /** Subtraction of BigInts + */ + def - (that: BigInt): BigInt = new BigInt(this.bigInteger.subtract(that.bigInteger)) + + /** Multiplication of BigInts + */ + def * (that: BigInt): BigInt = new BigInt(this.bigInteger.multiply(that.bigInteger)) + + /** Division of BigInts + */ + def / (that: BigInt): BigInt = new BigInt(this.bigInteger.divide(that.bigInteger)) + + /** Remainder of BigInts + */ + def % (that: BigInt): BigInt = new BigInt(this.bigInteger.remainder(that.bigInteger)) + + /** Returns a pair of two BigInts containing (this / that) and (this % that). + */ + def /% (that: BigInt): Pair[BigInt, BigInt] = { + val dr = this.bigInteger.divideAndRemainder(that.bigInteger) + Pair(new BigInt(dr(0)), new BigInt(dr(1))) + } + + /** Leftshift of BigInt + */ + def << (n: Int): BigInt = new BigInt(this.bigInteger.shiftLeft(n)) + + /** (Signed) rightshift of BigInt + */ + def >> (n: Int): BigInt = new BigInt(this.bigInteger.shiftRight(n)) + + /** Bitwise and of BigInts + */ + def & (that: BigInt): BigInt = new BigInt(this.bigInteger.and(that.bigInteger)) + + /** Bitwise or of BigInts + */ + def | (that: BigInt): BigInt = new BigInt(this.bigInteger.or (that.bigInteger)) + + /** Bitwise exclusive-or of BigInts + */ + def ^ (that: BigInt): BigInt = new BigInt(this.bigInteger.xor(that.bigInteger)) + + /** Bitwise and-not of BigInts. Returns a BigInt whose value is (this & ~that). + */ + def &~ (that: BigInt): BigInt = new BigInt(this.bigInteger.andNot(that.bigInteger)) + + /** Returns the greatest common divisor of abs(this) and abs(that) + */ + def gcd (that: BigInt): BigInt = new BigInt(this.bigInteger.gcd(that.bigInteger)) + + /** Returns a BigInt whose value is (this mod m). + * This method differs from `%' in that it always returns a non-negative BigInt. + */ + def mod (that: BigInt): BigInt = new BigInt(this.bigInteger.mod(that.bigInteger)) + + /** Returns the minimum of this and that + */ + def min (that: BigInt): BigInt = new BigInt(this.bigInteger.min(that.bigInteger)) + + /** Returns the maximum of this and that + */ + def max (that: BigInt): BigInt = new BigInt(this.bigInteger.max(that.bigInteger)) + + /** Returns a BigInt whose value is (<tt>this</tt> raised to the power of <tt>exp</tt>). + */ + def pow (exp: Int): BigInt = new BigInt(this.bigInteger.pow(exp)) + + /** Returns a BigInt whose value is + * (<tt>this</tt> raised to the power of <tt>exp</tt> modulo <tt>m</tt>). + */ + def modPow (exp: BigInt, m: BigInt): BigInt = + new BigInt(this.bigInteger.modPow(exp.bigInteger, m.bigInteger)) + + /** Returns a BigInt whose value is (the inverse of <tt>this</tt> modulo <tt>m</tt>). + */ + def modInverse (m: BigInt): BigInt = new BigInt(this.bigInteger.modInverse(m.bigInteger)) + + /** Returns a BigInt whose value is the negation of this BigInt + */ + def - : BigInt = new BigInt(this.bigInteger.negate()) + + /** Returns the absolute value of this BigInt + */ + def abs: BigInt = new BigInt(this.bigInteger.abs()) + + /** Returns the sign of this BigInt, i.e. + * -1 if it is less than 0, + * +1 if it is greater than 0 + * 0 if it is equal to 0 + */ + def signum: Int = this.bigInteger.signum() + + /** Returns the bitwise complement of this BigNum + */ + def ~ : BigInt = new BigInt(this.bigInteger.not()) + + /** Returns true if and only if the designated bit is set. + */ + def testBit (n: Int): Boolean = this.bigInteger.testBit(n) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit set. + */ + def setBit (n: Int): BigInt = new BigInt(this.bigInteger.setBit(n)) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit cleared. + */ + def clearBit(n: Int): BigInt = new BigInt(this.bigInteger.clearBit(n)) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit flipped. + */ + def flipBit (n: Int): BigInt = new BigInt(this.bigInteger.flipBit(n)) + + /** Returns the index of the rightmost (lowest-order) one bit in this BigInt + * (the number of zero bits to the right of the rightmost one bit). + */ + def lowestSetBit: int = this.bigInteger.getLowestSetBit() + + /** Returns the number of bits in the minimal two's-complement representation of this BigInt, + * excluding a sign bit. + */ + def bitLength: int = this.bigInteger.bitLength() + + /** Returns the number of bits in the two's complement representation of this BigInt + * that differ from its sign bit. + */ + def bitCount: int = this.bigInteger.bitCount() + + /** Returns true if this BigInt is probably prime, false if it's definitely composite. + * @param certainty a measure of the uncertainty that the caller is willing to tolerate: + * if the call returns true the probability that this BigInt is prime + * exceeds (1 - 1/2 ^ certainty). + * The execution time of this method is proportional to the value of + * this parameter. + */ + def isProbablePrime(certainty: Int) = this.bigInteger.isProbablePrime(certainty) + + /** Converts this BigInt to a <tt>byte</tt>. + * If the BigInt is too big to fit in a byte, only the low-order 8 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + def byteValue = intValue.toByte + + /** Converts this BigInt to a <tt>short</tt>. + * If the BigInt is too big to fit in a byte, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + def shortValue = intValue.toShort + + /** Converts this BigInt to a <tt>char</tt>. + * If the BigInt is too big to fit in a char, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value and that it always returns a positive result. + */ + def charValue = intValue.toChar + + /** Converts this BigInt to an <tt>int</tt>. + * If the BigInt is too big to fit in a char, only the low-order 32 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + def intValue = this.bigInteger.intValue + + /** Converts this BigInt to a <tt>long</tt>. + * If the BigInt is too big to fit in a char, only the low-order 64 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + def longValue = this.bigInteger.longValue + + /** Converts this BigInt to a <tt>float</tt>. + * if this BigInt has too great a magnitude to represent as a float, + * it will be converted to Float.NEGATIVE_INFINITY or Float.POSITIVE_INFINITY as appropriate. + */ + def floatValue = this.bigInteger.floatValue + + /** Converts this BigInt to a <tt>double</tt>. + * if this BigInt has too great a magnitude to represent as a float, + * it will be converted to Float.NEGATIVE_INFINITY or Float.POSITIVE_INFINITY as appropriate. + */ + def doubleValue = this.bigInteger.doubleValue + + /** Returns the decimal String representation of this BigInt. + */ + override def toString(): String = this.bigInteger.toString() + + /** Returns the String representation in the specified radix of this BigInt. + */ + def toString(radix: Int): String = this.bigInteger.toString(radix) + + /** Returns a byte array containing the two's-complement representation of this BigInt. + * The byte array will be in big-endian byte-order: the most significant byte is in the + * zeroth element. The array will contain the minimum number of bytes required to represent + * this BigInt, including at least one sign bit. + */ + def toByteArray: Array[Byte] = this.bigInteger.toByteArray() +} diff --git a/src/library/scala/Seq.scala b/src/library/scala/Seq.scala index 14a9368522..66c44829e7 100644 --- a/src/library/scala/Seq.scala +++ b/src/library/scala/Seq.scala @@ -156,7 +156,7 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Iterable[A] { */ def toList: List[A] = elements.toList; - /** Converts this sequence to an Array */ + /** Converts this sequence to a fresh Array */ def toArray[B >: A]: Array[B] = elements.copyToArray(new Array[B](length), 0); /** Fills the given array <code>xs</code> with the elements of diff --git a/src/library/scala/runtime/BoxedAnyArray.scala b/src/library/scala/runtime/BoxedAnyArray.scala index 1945016977..92359d8555 100644 --- a/src/library/scala/runtime/BoxedAnyArray.scala +++ b/src/library/scala/runtime/BoxedAnyArray.scala @@ -219,4 +219,28 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var dest1 = adapt(dest) Array.copy(if (unboxed != null) unboxed else boxed, from, dest1, to, len) } + + override def subArray(start: Int, end: Int): Object = { + val result = new BoxedAnyArray(end - start); + Array.copy(this, 0, result, 0, end - start) + result + } + + override def filter(p: Any => Boolean): Object = { + val include = new Array[Boolean](length); + var len = 0; + var i = 0; + while (i < length) { + if (p(this(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new BoxedAnyArray(len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = this(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedArray.scala b/src/library/scala/runtime/BoxedArray.scala index 8fad91eb2e..c631c0292e 100644 --- a/src/library/scala/runtime/BoxedArray.scala +++ b/src/library/scala/runtime/BoxedArray.scala @@ -46,11 +46,11 @@ abstract class BoxedArray extends PartialFunction[Int, Object] with Seq[Object] Array.copy(value, from, dest, to, len) } - def subArray(from: Int, end: Int): Object = null + def subArray(from: Int, end: Int): Object - def filter(p: Any => Boolean): Object = null + def filter(p: Any => Boolean): Object - def map[b](f: Any => b): Array[b] = { + final def map[b](f: Any => b): Array[b] = { val len = length val result = new Array[b](len) var i = 0 @@ -61,7 +61,7 @@ abstract class BoxedArray extends PartialFunction[Int, Object] with Seq[Object] result } - def flatMap[b](f: Any => Array[b]): Array[b] = { + final def flatMap[b](f: Any => Array[b]): Array[b] = { val len = length val tmp = new Array[Array[b]](len) var i = 0 diff --git a/src/library/scala/runtime/BoxedBooleanArray.scala b/src/library/scala/runtime/BoxedBooleanArray.scala index bc91e555a8..a157047652 100644 --- a/src/library/scala/runtime/BoxedBooleanArray.scala +++ b/src/library/scala/runtime/BoxedBooleanArray.scala @@ -31,5 +31,29 @@ final class BoxedBooleanArray(val value: Array[Boolean]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Boolean] = { + val result = new Array[Boolean](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Boolean] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Boolean](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedByteArray.scala b/src/library/scala/runtime/BoxedByteArray.scala index fa429af1e6..d5195da463 100644 --- a/src/library/scala/runtime/BoxedByteArray.scala +++ b/src/library/scala/runtime/BoxedByteArray.scala @@ -31,5 +31,29 @@ final class BoxedByteArray(val value: Array[Byte]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Byte] = { + val result = new Array[Byte](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Byte] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Byte](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedCharArray.scala b/src/library/scala/runtime/BoxedCharArray.scala index 8510b48b21..bcf42c8d7b 100644 --- a/src/library/scala/runtime/BoxedCharArray.scala +++ b/src/library/scala/runtime/BoxedCharArray.scala @@ -31,5 +31,29 @@ final class BoxedCharArray(val value: Array[Char]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Char] = { + val result = new Array[Char](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Char] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Char](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedDoubleArray.scala b/src/library/scala/runtime/BoxedDoubleArray.scala index 4e78325513..7affbd86d3 100644 --- a/src/library/scala/runtime/BoxedDoubleArray.scala +++ b/src/library/scala/runtime/BoxedDoubleArray.scala @@ -31,5 +31,29 @@ final class BoxedDoubleArray(val value: Array[Double]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Double] = { + val result = new Array[Double](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Double] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Double](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedFloatArray.scala b/src/library/scala/runtime/BoxedFloatArray.scala index ffdba54168..cd1887408f 100644 --- a/src/library/scala/runtime/BoxedFloatArray.scala +++ b/src/library/scala/runtime/BoxedFloatArray.scala @@ -31,5 +31,29 @@ final class BoxedFloatArray(val value: Array[Float]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Float] = { + val result = new Array[Float](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Float] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Float](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedIntArray.scala b/src/library/scala/runtime/BoxedIntArray.scala index bbfc82407c..ebd51114af 100644 --- a/src/library/scala/runtime/BoxedIntArray.scala +++ b/src/library/scala/runtime/BoxedIntArray.scala @@ -32,13 +32,13 @@ final class BoxedIntArray(val value: Array[Int]) extends BoxedArray { override def hashCode(): Int = value.hashCode(); - override def subArray(start: Int, end: Int): Array[Int] = { + def subArray(start: Int, end: Int): Array[Int] = { val result = new Array[Int](end - start); Array.copy(value, 0, result, 0, end - start) result } - override def filter(p: Any => Boolean): Array[Int] = { + def filter(p: Any => Boolean): Array[Int] = { val include = new Array[Boolean](value.length); var len = 0; var i = 0; diff --git a/src/library/scala/runtime/BoxedLongArray.scala b/src/library/scala/runtime/BoxedLongArray.scala index e0cbe169b6..8eb83ee10c 100644 --- a/src/library/scala/runtime/BoxedLongArray.scala +++ b/src/library/scala/runtime/BoxedLongArray.scala @@ -31,5 +31,29 @@ final class BoxedLongArray(val value: Array[Long]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Long] = { + val result = new Array[Long](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Long] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Long](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } diff --git a/src/library/scala/runtime/BoxedObjectArray.scala b/src/library/scala/runtime/BoxedObjectArray.scala index 31db3ca428..25c4d739c5 100644 --- a/src/library/scala/runtime/BoxedObjectArray.scala +++ b/src/library/scala/runtime/BoxedObjectArray.scala @@ -53,13 +53,4 @@ final class BoxedObjectArray(val value: Array[Object]) extends BoxedArray { } result } - -/* - def map(p: Any => Any): BoxedAnyArray = { - val include = new Array - var len = 0 - for (val x <- value) if (p(x)) { tmp(len) = x; len = len + 1 } - slice(tmp, 0, len) - } -*/ } diff --git a/src/library/scala/runtime/BoxedShortArray.scala b/src/library/scala/runtime/BoxedShortArray.scala index 3ce763377b..796d82957f 100644 --- a/src/library/scala/runtime/BoxedShortArray.scala +++ b/src/library/scala/runtime/BoxedShortArray.scala @@ -31,5 +31,29 @@ final class BoxedShortArray(val value: Array[Short]) extends BoxedArray { ); override def hashCode(): Int = value.hashCode(); + + def subArray(start: Int, end: Int): Array[Short] = { + val result = new Array[Short](end - start); + Array.copy(value, 0, result, 0, end - start) + result + } + + def filter(p: Any => Boolean): Array[Short] = { + val include = new Array[Boolean](value.length); + var len = 0; + var i = 0; + while (i < value.length) { + if (p(value(i))) { include(i) = true; len = len + 1 } + i = i + 1 + } + val result = new Array[Short](len); + len = 0; + i = 0; + while (len < result.length) { + if (include(i)) { result(len) = value(i); len = len + 1 } + i = i + 1 + } + result + } } |