Skip to content

Commit c3fe70c

Browse files
committed
Tests and some refinements
1 parent e7324e7 commit c3fe70c

File tree

6 files changed

+85
-5
lines changed

6 files changed

+85
-5
lines changed

library/src/scala/util/FromDigits.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ object FromDigits {
2323

2424
abstract class FromDigitsException(msg: String) extends NumberFormatException(msg)
2525

26-
class NumberTooLarge extends FromDigitsException("number too large")
27-
class NumberTooSmall extends FromDigitsException("number too small")
28-
class MalformedNumber extends FromDigitsException("malformed number literal")
26+
class NumberTooLarge(msg: String = "number too large") extends FromDigitsException(msg)
27+
class NumberTooSmall(msg: String = "number too small") extends FromDigitsException(msg)
28+
class MalformedNumber(msg: String = "malformed number literal") extends FromDigitsException(msg)
2929

3030
/** Convert digits and radix to integer value (either int or Long)
3131
* This is tricky because of the max negative value.
@@ -66,7 +66,7 @@ object FromDigits {
6666
* Legal strings consist only of digits conforming to radix,
6767
* possibly preceded by a "-" sign.
6868
*/
69-
def intFromDigits(digits: String, radix: Int): Int =
69+
def intFromDigits(digits: String, radix: Int = 10): Int =
7070
integerFromDigits(digits, radix, Int.MaxValue).toInt
7171

7272
/** Convert digit string to Long number
@@ -77,7 +77,7 @@ object FromDigits {
7777
* Legal strings consist only of digits conforming to radix,
7878
* possibly preceded by a "-" sign.
7979
*/
80-
def longFromDigits(digits: String, radix: Int): Long =
80+
def longFromDigits(digits: String, radix: Int = 10): Long =
8181
integerFromDigits(digits, radix, Long.MaxValue)
8282

8383
@sharable private val zeroFloat = raw"-?[0.]+(?:[eE][+-]?[0-9]+)?[fFdD]?".r

tests/neg/GenericNumLits/Even_1.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import scala.util.FromDigits
2+
import scala.quoted._
3+
import scala.quoted.matching._
4+
5+
case class Even(n: Int)
6+
object Even {
7+
8+
private def evenFromDigits(digits: String): Even = {
9+
val intValue = FromDigits.intFromDigits(digits)
10+
if (intValue % 2 == 0) Even(intValue)
11+
else throw FromDigits.MalformedNumber(s"$digits is odd")
12+
}
13+
14+
private def evenFromDigitsImpl(digits: Expr[String]) given (ctx: QuoteContext): Expr[Even] = digits match {
15+
case Const(ds) =>
16+
val ev =
17+
try evenFromDigits(ds)
18+
catch {
19+
case ex: FromDigits.FromDigitsException =>
20+
ctx.error(ex.getMessage)
21+
Even(0)
22+
}
23+
'{Even(${ev.n.toExpr})}
24+
case _ =>
25+
'{evenFromDigits($digits)}
26+
}
27+
28+
class EvenFromDigits extends FromDigits[Even] {
29+
def fromDigits(digits: String) = evenFromDigits(digits)
30+
}
31+
32+
given as EvenFromDigits {
33+
override inline def fromDigits(digits: String) = ${
34+
evenFromDigitsImpl('digits)
35+
}
36+
}
37+
}

tests/neg/GenericNumLits/Test_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test extends App {
2+
3+
val e1: Even = 1234
4+
val e2: Even = 123 // error: 123 is odd
5+
}

tests/neg/GenericNumLits/Test_3.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test extends App {
2+
val e3: Even = 123456789101111 // error: number too large
3+
}

tests/run/genericNumLits.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
13232202002020202020202
2+
-50390822187678765893036
3+
132322020020.223
4+
Even(1234)
5+
malformed

tests/run/genericNumLits.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import scala.util.FromDigits
2+
object Test extends App {
3+
4+
val x: BigInt = 13232202002020202020202
5+
val y: BigInt = -0xaabb12345ACF12345AC
6+
val z: BigDecimal = 132322020020.223
7+
8+
case class Even(n: Int)
9+
10+
given as FromDigits[Even] {
11+
def fromDigits(digits: String): Even = {
12+
val intValue = digits.toInt
13+
if (intValue % 2 == 0) Even(intValue)
14+
else throw FromDigits.MalformedNumber()
15+
}
16+
}
17+
18+
val e: Even = 1234
19+
20+
println(x)
21+
println(y)
22+
println(z)
23+
println(e)
24+
25+
try println(123: Even)
26+
catch {
27+
case ex: FromDigits.MalformedNumber => println("malformed")
28+
}
29+
30+
}

0 commit comments

Comments
 (0)