Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>While Scalas syntax is powerful, it is not flexible enough to create arbitrary delimiters for symbols. Thus, there is no way to leave commas and replace them only with spaces.</p> <p>Nevertheless, it is possible to use macros and parse a string with arbitrary content at compile time. It is not an "easy" solution, but one that works:</p> <pre><code>object AlgDefDSL { import language.experimental.macros import scala.reflect.macros.Context implicit class DefDSL(sc: StringContext) { def dsl(): Definition = macro __dsl_impl } def __dsl_impl(c: Context)(): c.Expr[Definition] = { import c.universe._ val defn = c.prefix.tree match { case Apply(_, List(Apply(_, List(Literal(Constant(s: String)))))) =&gt; def toAST[A : TypeTag](xs: Tree*): Tree = Apply( Select(Ident(typeOf[A].typeSymbol.companionSymbol), newTermName("apply")), xs.toList ) def toVarAST(varObj: Var) = toAST[Var](c.literal(varObj.name).tree) def toEqAST(eqObj: Eq) = toAST[Eq]((eqObj.head +: eqObj.body).map(toVarAST(_)): _*) def toDefAST(defObj: Definition) = toAST[Definition](c.literal(defObj.name).tree +: defObj.body.map(toEqAST(_)): _*) parsers.parse(s) match { case parsers.Success(defn, _) =&gt; toDefAST(defn) case parsers.NoSuccess(msg, _) =&gt; c.abort(c.enclosingPosition, msg) } } c.Expr(defn) } import scala.util.parsing.combinator.JavaTokenParsers private object parsers extends JavaTokenParsers { override val whiteSpace = "[ \t]*".r lazy val newlines = opt(rep("\n")) lazy val varP = "[a-z]+".r ^^ Var lazy val eqP = (varP &lt;~ "=") ~ rep(varP) ^^ { case lhs ~ rhs =&gt; Eq(lhs, rhs: _*) } lazy val defHead = newlines ~&gt; ("[a-zA-Z]+".r &lt;~ "{") &lt;~ newlines lazy val defBody = rep(eqP &lt;~ rep("\n")) lazy val defEnd = "}" ~ newlines lazy val defP = defHead ~ defBody &lt;~ defEnd ^^ { case name ~ eqs =&gt; Definition(name, eqs: _*) } def parse(s: String) = parseAll(defP, s) } case class Var(name: String) case class Eq(head: Var, body: Var*) case class Definition(name: String, body: Eq*) } </code></pre> <p>It can be used with something like this:</p> <pre><code>scala&gt; import AlgDefDSL._ import AlgDefDSL._ scala&gt; dsl""" | Dummy { | x = y z | y = x z | } | """ res12: AlgDefDSL.Definition = Definition(Dummy,WrappedArray(Eq(Var(x),WrappedArray(Var(y), Var(z))), Eq(Var(y),WrappedArray(Var(x), Var(z))))) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload