summaryrefslogtreecommitdiff
path: root/api/src/main/scala/twist/stages/Compiler.scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-01 00:56:12 -0700
committerLi Haoyi <haoyi@dropbox.com>2014-11-01 00:56:12 -0700
commit3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9 (patch)
tree9f1846359c784a6e4bfc4682fddc8b6c884bf811 /api/src/main/scala/twist/stages/Compiler.scala
parent058e9bac2dd8166051bafa16d51f27ee5856929a (diff)
downloadhands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.tar.gz
hands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.tar.bz2
hands-on-scala-js-3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9.zip
works, with a compiler-plugin based architecture supporting incremental compilation
Diffstat (limited to 'api/src/main/scala/twist/stages/Compiler.scala')
-rw-r--r--api/src/main/scala/twist/stages/Compiler.scala161
1 files changed, 0 insertions, 161 deletions
diff --git a/api/src/main/scala/twist/stages/Compiler.scala b/api/src/main/scala/twist/stages/Compiler.scala
deleted file mode 100644
index e00c373..0000000
--- a/api/src/main/scala/twist/stages/Compiler.scala
+++ /dev/null
@@ -1,161 +0,0 @@
-package twist.stages
-import acyclic.file
-
-import scala.reflect.macros.Context
-import scala.reflect.internal.util.{Position, OffsetPosition}
-
-/**
- * Walks the parsed AST, converting it into an un-structured Scala source-blob
- * which when compiled results in a function that can be used to generate the
- * given Frag at runtime.
- */
-object Compiler{
- val WN = TwistNodes
- def apply(c: Context)(literalPos: c.Position, template: WN.Template): c.Tree = {
-
- import c.universe._
- def fragType = tq"scalatags.Text.all.Frag"
- def posFor(offset: Int) = {
- new OffsetPosition(
- literalPos.source,
- offset
- ).asInstanceOf[c.universe.Position]
- }
- def compileTree(frag: WN.TemplateTree): Tree = {
-
-// println(frag)
- val fragPos = posFor(literalPos.point + frag.offset)
-
-// println(s"${frag.offset}\n${literalPos.point}\n${pos.point}\n$frag\n")
-
- val f: Tree = frag match {
- case WN.Plain(text, offset) => q"$text"
- case WN.Display(exp, offset) => compileTree(exp)
- case WN.Comment(msg, offset) => q""
- case WN.ScalaExp(Seq(WN.Simple(first, _), WN.Block(ws, args, content, _)), offset)
- if first.startsWith("for(") =>
- val fresh = c.fresh()
- val skeleton: Tree = c.parse(first + s"{$fresh}").asInstanceOf[Apply]
-// println("FIRST " + first)
- skeleton.foreach{x =>
- x
- if (x.pos != NoPosition) x.pos = posFor(x.pos.point + fragPos.point + 1)
- }
- val b = content.map(compileTree(_))
- def rec(t: Tree): Tree = t match {
- case a @ Apply(fun, List(f @ Function(vparams, body))) =>
- val f2 = Function(vparams, rec(body))
- val a2 = Apply(fun, List(f2))
- a2.pos = a.pos
- f2.pos = f.pos
- a2
- case Ident(x: TermName) if x.decoded == fresh =>
- q"Seq[$fragType](..$b)"
- }
-
- val out = rec(skeleton)
-
-
- out
-
- case WN.ScalaExp(WN.Simple(first, _) +: WN.Block(_, None, content1, _) +: rest, offset)
- if first.startsWith("if(") =>
-
- val b1 = content1.map(compileTree(_))
- val tree = c.parse(first + "{}").asInstanceOf[If]
- tree.foreach{x =>
- x.pos = posFor(x.pos.point + fragPos.point + 1)
- }
- val If(cond, _, _) = tree
- val b2 = rest match{
- case Seq(WN.Simple(next, _), WN.Block(_, None, content2, _)) =>
- content2.map(compileTree(_))
- case Seq() => Nil
- }
- q"if($cond){ Seq[$fragType](..$b1): $fragType } else { Seq[$fragType](..$b2): $fragType }"
-
- case xx @ WN.ScalaExp(WN.Simple(first, _) +: rest, offset) =>
- val firstTree = c.parse(first)
-
- firstTree.foreach{x =>
- x.pos = posFor(x.pos.point + fragPos.point)
- }
-
- val s = rest.foldLeft[Tree](firstTree) {
- case (l, WN.Simple(code, _)) =>
- val fresh = c.fresh()
-
- val snippet = s"$fresh$code"
- val skeleton = c.parse(snippet)
-
- def rec(t: Tree): Tree = {
- val newPos = posFor(fragPos.point + t.pos.point + first.length - fresh.length)
- val res = t match {
- case Apply(fun, args) =>
- for(arg <- args; tree <- arg if tree.pos != NoPosition){
- tree.pos = posFor(tree.pos.point + newPos.point - t.pos.point)
- }
-
- Apply(rec(fun), args)
- case Select(qualifier, name) => Select(rec(qualifier), name)
- case Ident(x: TermName) if x.decoded == fresh => l
- }
- res.pos = newPos
-
-// println(Position.formatMessage(newPos.asInstanceOf[scala.reflect.internal.util.Position], "", true))
- res
- }
-
-
- rec(skeleton)
-
- case (l, WN.Block(ws, None, content, _)) =>
- q"$l(..${content.map(compileTree(_))})"
-
- case (l, WN.Block(ws, Some(args), content, _)) =>
- val snippet = s"{$args ()}"
- val skeleton = c.parse(snippet)
- val Function(vparamss, body) = skeleton
-
- val func = Function(vparamss, q"Seq[$fragType](..${content.map(compileTree(_))})")
- func.pos = posFor(fragPos.point + skeleton.pos.point)
- q"$l($func)"
- }
-
- s
- }
-
-// f.foreach(_.pos = pos)
-
-// println("XXX " + f.pos)
-// println("F " + f)
- f
- }
-
- def compileTemplate(tmpl: WN.Template): Tree = {
- val WN.Template(name, comment, params, topImports, imports, subs, content, offset) = tmpl
- val fullName = if (name.toString == "") c.fresh("outer") else name
-
- val DefDef(mods, realName, tparams, vparamss, tpt, rhs) = {
- val snippet = s"def $fullName$params = {}"
- val z = c.parse(snippet).asInstanceOf[DefDef]
- z
- }
-
- val innerDefs = subs.map(compileTemplate(_))
-
- val body = atPos(literalPos)(q"""{
- import scalatags.Text.all._
- ..${topImports.map(i => c.parse(i.code))}
- ..$innerDefs
-
- Seq[scalatags.Text.all.Frag](..${content.map(compileTree(_))})
- }""")
-
- if (name.toString == "") body
- else DefDef(mods, realName, tparams, vparamss, tpt, body)
- }
-
- atPos(literalPos)(q"${compileTemplate(template)}")
- }
-} \ No newline at end of file