Skip to content

Instantly share code, notes, and snippets.

@Sciss
Created July 2, 2012 16:41
Show Gist options
  • Save Sciss/3034172 to your computer and use it in GitHub Desktop.
Save Sciss/3034172 to your computer and use it in GitHub Desktop.
ScalaColliderMacroRateChecking.scala
// for Scala 2.10.0-M4
import language.experimental.macros
import import scala.reflect.makro._
// ScalaCollider skeleton
sealed trait MaybeRate
object UndefinedRate extends MaybeRate
sealed trait Rate extends MaybeRate
object audio extends Rate
object control extends Rate
trait GE { def rate: MaybeRate }
// Shamelessly stolen from Jason Zaugg (https://github.com/retronym/macrocosm)
def assert1Impl(c: Context)(cond: c.Expr[Boolean]) = {
import c.universe._
val condCode = c.Expr[String](Literal(Constant(show(cond.tree))))
c.reify {
assert(cond.splice, condCode.splice)
()
}
}
def assert1(cond: Boolean): Unit = macro assert1Impl
// Crash test dummies
object WhiteNoiseAr extends GE { def rate = audio }
object LFNoiseKr extends GE { def rate = control }
object UnknownGE extends GE { def rate = UndefinedRate }
// Test enhanced graph element
object LPF {
def ar( in: GE ) : LPF = {
assert1( in.rate == UndefinedRate || in.rate == audio )
apply( audio, in )
}
}
case class LPF( rate: Rate, in: GE )
//// Tests (uncomment/eval each)
// LPF.ar( WhiteNoiseAr ) // compiles
// LPF.ar( UnknownGE ) // compiles (might throw a runtime exception later)
// LPF.ar( LFNoiseKr ) // won't compile
@Sciss
Copy link
Author

Sciss commented Jul 2, 2012

That still only gives runtime checks. What is needed is rather def ar(in: GE) : LPF = macro arImpl(in)

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