Skip to content

Commit

Permalink
Specialize liftable for IArrays
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Jul 27, 2019
1 parent 232b3fa commit dc81415
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 5 deletions.
62 changes: 57 additions & 5 deletions library/src/scala/quoted/Liftable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,63 @@ object Liftable {
}
}

given [T: Type: Liftable: ClassTag] as Liftable[IArray[T]] = new Liftable[IArray[T]] {
def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] = '{
val array = new Array[T](${iarray.length.toExpr})(ClassTag(${the[ClassTag[T]].runtimeClass.toExpr}))
${ Expr.block(List.tabulate(iarray.length)(i => '{ array(${i.toExpr}) = ${iarray(i).toExpr} }), '{ array.asInstanceOf[IArray[T]] }) }
}
given [T: Type] as Liftable[ClassTag[T]] = new Liftable[ClassTag[T]] {
def toExpr(x: ClassTag[T]): given QuoteContext => Expr[ClassTag[T]] =
'{ ClassTag(${x.runtimeClass.toExpr}) }
}

given IArrayIsLiftable [T: Type: Liftable: ClassTag] as Liftable[IArray[T]] = new Liftable[IArray[T]] {
def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] =
if (iarray.length == 0) '{ IArray.empty[T](${the[ClassTag[T]].toExpr}) }
else '{ IArray(${iarray.asInstanceOf[Array[T]].toSeq.toExpr}: _*)(${the[ClassTag[T]].toExpr}) }
}

given IArrayOfBooleanIsLiftable as Liftable[IArray[Boolean]] = new Liftable[IArray[Boolean]] {
def toExpr(iarray: IArray[Boolean]): given QuoteContext => Expr[IArray[Boolean]] =
if (iarray.length == 0) '{ Array.emptyBooleanArray.asInstanceOf[IArray[Boolean]] } // TODO use IArray.emptyBooleanIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Boolean]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfByteIsLiftable as Liftable[IArray[Byte]] = new Liftable[IArray[Byte]] {
def toExpr(iarray: IArray[Byte]): given QuoteContext => Expr[IArray[Byte]] =
if (iarray.length == 0) '{ Array.emptyByteArray.asInstanceOf[IArray[Byte]] } // TODO use IArray.emptyByteIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Byte]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfShortIsLiftable as Liftable[IArray[Short]] = new Liftable[IArray[Short]] {
def toExpr(iarray: IArray[Short]): given QuoteContext => Expr[IArray[Short]] =
if (iarray.length == 0) '{ Array.emptyShortArray.asInstanceOf[IArray[Short]] } // TODO use IArray.emptyShortIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Short]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfCharIsLiftable as Liftable[IArray[Char]] = new Liftable[IArray[Char]] {
def toExpr(iarray: IArray[Char]): given QuoteContext => Expr[IArray[Char]] =
if (iarray.length == 0) '{ Array.emptyCharArray.asInstanceOf[IArray[Char]] } // TODO use IArray.emptyCharIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Char]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfIntIsLiftable as Liftable[IArray[Int]] = new Liftable[IArray[Int]] {
def toExpr(iarray: IArray[Int]): given QuoteContext => Expr[IArray[Int]] =
if (iarray.length == 0) '{ Array.emptyIntArray.asInstanceOf[IArray[Int]] } // TODO use IArray.emptyIntIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Int]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfLongIsLiftable as Liftable[IArray[Long]] = new Liftable[IArray[Long]] {
def toExpr(iarray: IArray[Long]): given QuoteContext => Expr[IArray[Long]] =
if (iarray.length == 0) '{ Array.emptyLongArray.asInstanceOf[IArray[Long]] } // TODO use IArray.emptyLongIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Long]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfFloatIsLiftable as Liftable[IArray[Float]] = new Liftable[IArray[Float]] {
def toExpr(iarray: IArray[Float]): given QuoteContext => Expr[IArray[Float]] =
if (iarray.length == 0) '{ Array.emptyFloatArray.asInstanceOf[IArray[Float]] } // TODO use IArray.emptyFloatIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Float]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given IArrayOfDoubleIsLiftable as Liftable[IArray[Double]] = new Liftable[IArray[Double]] {
def toExpr(iarray: IArray[Double]): given QuoteContext => Expr[IArray[Double]] =
if (iarray.length == 0) '{ Array.emptyDoubleArray.asInstanceOf[IArray[Double]] } // TODO use IArray.emptyDoubleIArray
else '{ IArray(${iarray(0).toExpr}, ${iarray.asInstanceOf[Array[Double]].toSeq.tail.toExpr}: _*) } // TODO use IArray.toSeq
}

given [T: Type: Liftable] as Liftable[Seq[T]] = new Liftable[Seq[T]] {
Expand Down
13 changes: 13 additions & 0 deletions tests/run-with-compiler/quote-lib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ object Test {
val iarray: IArray[Int] = IArray(1, 2, 3)
val liftedIArray: Expr[IArray[Int]] = iarray

val iarray2: IArray[String] = IArray("a", "b", "c")
iarray2.toExpr

IArray(false).toExpr
IArray(1: Byte).toExpr
IArray(1: Short).toExpr
IArray(1).toExpr
IArray(1L).toExpr
IArray(1.1f).toExpr
IArray(1.1d).toExpr
IArray('a').toExpr
IArray((1, 3)).toExpr

val some: Option[Int] = Some(2)
val none: Option[Int] = Some(2)
val liftedSome: Expr[Option[Int]] = some
Expand Down
Empty file.
32 changes: 32 additions & 0 deletions tests/run-with-compiler/quote-lift-IArray.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import scala.quoted._
import scala.quoted.autolift._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = run {
'{
def p[T](arr: IArray[T]): Unit = {
println(arr.asInstanceOf[Array[_]].mkString("[", ", ", "]"))
}
p(${IArray.empty[Boolean]})
p(${IArray.empty[Byte]})
p(${IArray.empty[Short]})
p(${IArray.empty[Char]})
p(${IArray.empty[Int]})
p(${IArray.empty[Long]})
p(${IArray.empty[Float]})
p(${IArray.empty[Double]})
p(${IArray.empty[String]})
println()
p(${IArray(true)})
p(${IArray[Byte](1, 2)})
p(${IArray[Short](2, 3)})
p(${IArray[Char]('a', 'b')})
p(${IArray[Int](4, 5)})
p(${IArray[Long](6L, 7L)})
p(${IArray[Float](2.1f, 3.2f)})
p(${IArray[Double](2.2, 3.3)})
p(${IArray("abc", "xyz")})
}
}
}

0 comments on commit dc81415

Please sign in to comment.