summaryrefslogtreecommitdiff
path: root/shared/src/main/scala/escale/syntax.scala
diff options
context:
space:
mode:
Diffstat (limited to 'shared/src/main/scala/escale/syntax.scala')
-rw-r--r--shared/src/main/scala/escale/syntax.scala53
1 files changed, 53 insertions, 0 deletions
diff --git a/shared/src/main/scala/escale/syntax.scala b/shared/src/main/scala/escale/syntax.scala
new file mode 100644
index 0000000..fc4b789
--- /dev/null
+++ b/shared/src/main/scala/escale/syntax.scala
@@ -0,0 +1,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
+
+}