blob: fc4b78944089ffae55972fd1270cad1fca1cf7f6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package escale
import scala.concurrent.{ExecutionContext, Future}
import scala.language.experimental.macros
object Macros {
import scala.reflect.macros.blackbox._
def goImpl[A: c.WeakTypeTag](c: Context)(body: c.Expr[A])(
execContext: c.Expr[ExecutionContext]): c.Tree = {
import c.universe._
val pkg = c.mirror.staticPackage("scala.async")
q"""$pkg.Async.async($body)($execContext)"""
}
def asyncTakeImpl[A: c.WeakTypeTag](c: Context)(
channel: c.Expr[Channel[A]]): c.Tree = {
import c.universe._
val pkg = c.mirror.staticPackage("scala.async")
q"""$pkg.Async.await($channel.take())"""
}
def asyncPutImpl[A: c.WeakTypeTag](c: Context)(value: c.Expr[A]): c.Tree = {
import c.universe._
val pkg = c.mirror.staticPackage("scala.async")
q"""$pkg.Async.await(${c.prefix}.channel.put($value))"""
}
def selectImpl(c: Context)(channels: c.Expr[Channel[_]]*): c.Tree = {
import c.universe._
val pkg = c.mirror.staticPackage("scala.async")
val Channel = c.mirror.staticModule("escale.Channel")
q"""($pkg.Async.await($Channel.select(..$channels)): @unchecked)"""
}
}
package object syntax {
def chan[A](capacity: Int = 0): Channel[A] = Channel[A](capacity)
def go[A](body: => A)(implicit execContext: ExecutionContext): Future[A] =
macro Macros.goImpl[A]
def !<[A](channel: Channel[A]): A = macro Macros.asyncTakeImpl[A]
implicit class ChannelOps[A](val channel: Channel[A]) extends AnyVal {
def !<(value: A): Unit = macro Macros.asyncPutImpl[A]
}
def select(channels: Channel[_]*): (Channel[_], Any) = macro Macros.selectImpl
}
|