Skip to content

Instantly share code, notes, and snippets.

View ochafik's full-sized avatar

Olivier Chafik ochafik

View GitHub Profile
@ochafik
ochafik / Input.scala
Last active December 13, 2015 23:49
Macro Extensions Plugin Input / Output with macro body
@scalaxy.extension[Any]
def quoted(quote: String): String = macro {
// `c` is defined as the macro Context.
// `quote` and `self` are in scope, defined as `c.Expr[Any]` and `c.Expr[String]`.
println(s"Currently expanding ${c.prefix}.quoted(${quote.tree})")
// `c.universe._` is automatically imported, so `reify` is in scope.
reify({
// Make sure we're not evaluating quote twice, in case it's a complex expression!
val q = quote.splice
q + self.splice + q
@ochafik
ochafik / Input.scala
Last active December 13, 2015 23:49
Macro Extensions Plugin Input / Output
@scalaxy.extension[Any]
def quoted(quote: String) = quote + self + quote
@ochafik
ochafik / Input.scala
Last active December 13, 2015 23:49
Runtime Extension Plugin
@extend(Any) def quoted(quote: String) = quote + self + quote
implicit def Extensions(self: Any) = new Extensions(self)
class Extensions(self: Any) {
def quoted(quote: String) = quote + self + quote
}
println(10.quoted("'")) // prints "'10'"
implicit class Extensions(self: Any) {
def quoted(quote: String) = quote + self + quote
}
println(10.quoted("'")) // prints "'10'"
@ochafik
ochafik / Macro TransformBeforeTyper.scala
Last active December 13, 2015 22:59
Example of simplified macro definition that could be made possible by a compiler plugin running before namer and typer
// Absolutely need to annotate return type!
@extend(URL) def secure: URL = macro
reify(new URL(s"https://${self.splice.getHost}${self.splice.getPath}"))
// Gets desugared to:
import scala.language.experimental.macros
import scala.reflect.macros.Context
implicit class secure(self: URL) {
def secure = macro secureImpl.secureImpl
@ochafik
ochafik / Scalaxy Compilets Parser Phase.scala
Last active December 13, 2015 22:38
Ideas on how to extend Scalaxy/Compilets to support untyped trees for much more power and flexibility.
replace(
{
// $vparamss($x) are special variables that capture all parameter groups.
// $vparams($x) would only capture one group
@extend($type) def $someMethod($vparamss: $) = $body
},
{
implicit class $someMethod(self: $type) extends AnyRef {
def $someMethod($vparamss: $) = $body
// $fresh$x is a special variable that picks a fresh name with fresh("x")
// Author: Olivier Chafik (http://ochafik.com)
// Feel free to modify and reuse this for any purpose ("public domain / I don't care").
package scalaxy.pretyping.example
import scala.reflect.internal._
import scala.tools.nsc.CompilerCommand
import scala.tools.nsc.Global
import scala.tools.nsc.Phase
import scala.tools.nsc.plugins.Plugin
import scala.tools.nsc.plugins.PluginComponent
assert x.getSize() == 2 : "Size of x is not 2"; // Java assert
@ochafik
ochafik / build.sbt
Last active December 13, 2015 20:08
// Only works with 2.10.0+
scalaVersion := "2.10.0"
// Dependency at compilation-time only (not at runtime).
libraryDependencies += "com.nativelibs4java" %% "scalaxy-debug" % "0.3-SNAPSHOT" % "provided"
// Scalaxy/Debug snapshots are published on the Sonatype repository.
resolvers += Resolver.sonatypeRepo("snapshots")