Skip to content

Instantly share code, notes, and snippets.

@biboudis
Last active December 2, 2020 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biboudis/ad8a4f448ba5c9266155d52b935b417b to your computer and use it in GitHub Desktop.
Save biboudis/ad8a4f448ba5c9266155d52b935b417b to your computer and use it in GitHub Desktop.
Virtualization in Scala 3 with givens
import scala.quoted._
import scala.quoted.util._
import scala.language.implicitConversions
trait Virtualized {
type Cde[A]
given IntPrimitiveMethods as PrimitiveMethods[Int] = IntPrimitiveMethodsImpl
protected val IntPrimitiveMethodsImpl: PrimitiveMethods[Int] = new PrimitiveMethods[Int]{ }
trait PrimitiveMethods[T](using t: NumOpsModule[T]):
extension (self: Cde[T]):
def +(c2: Cde[T])(using QuoteContext): Cde[T] = t.add(self, c2)
end extension
end PrimitiveMethods
given IntNumOpsModule as NumOpsModule[Int] = IntNumOpsModuleImpl
protected val IntNumOpsModuleImpl: NumOpsModule[Int]
trait NumOpsModule[T] { this: IntNumOpsModuleImpl.type =>
def add(c1: Cde[T], c2: Cde[T])(using QuoteContext): Cde[T]
}
def int(c1: Int)(using QuoteContext): Cde[Int]
}
object exprCode extends Cde2 {
type Cde[A] = Expr[A]
def int(c1: Int)(using QuoteContext): Cde[Int] = Expr(c1)
object IntNumOpsModuleImpl extends NumOpsModule[Int] {
def add(c1: Cde[Int], c2: Cde[Int])(using QuoteContext): Cde[Int] = '{${c1} + ${c2}}
}
}
object psCode extends Cde2 {
type Code[A] = exprCode.Cde[A]
enum Annot[A] {
case Sta[A](x: A) extends Annot[A]
case Global[A]() extends Annot[A]
case Unk[A]() extends Annot[A]
}
case class Cde[A](sta : Annot[A], dyn : Code[A])
def inj2[A, B, C](f: (Code[A], Code[B]) => Code[C]): ((Cde[A], Cde[B]) => Cde[C]) = ???
def lift2[A, B, C](fs: (A, B) => C)(lift: C => Cde[C])(fd: (Code[A], Code[B]) => Code[C]): ((Cde[A], Cde[B]) => Cde[C]) = ???
def int(c1: Int)(using QuoteContext): Cde[Int] = Cde(Annot.Sta(c1), Code.int(c1))
object IntNumOpsModuleImpl extends NumOpsModule[Int] {
def add(c1: Cde[Int], c2: Cde[Int])(using QuoteContext): Cde[Int] = lift2[Int, Int, Int](_+_)(int)(exprCode.IntNumOpsModuleImpl.add)(c1, c2)
}
}
object Test {
import psCode._
def test(using QuoteContext) = {
int(1) + int(2)
}
}
@nicolasstucki
Copy link

Does it work with the following change?

-      import ps.{given _, _}
+      import ps._

@biboudis
Copy link
Author

biboudis commented Dec 2, 2020

Indeed it works @nicolasstucki! Thanks!

Is there any way to unify the importing of ps with QuoteContext or make any other stylistic change to make the use-site nicer?

@nicolasstucki
Copy link

Maybe

   type PsCde[T] = QuoteContext ?=> Cde[T] // defined in ps

    def test: PsCde[Int] = {
      int(1) + int(2)
    } 

@biboudis
Copy link
Author

biboudis commented Dec 2, 2020

Indeed. It looks a bit better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment