summaryrefslogtreecommitdiff
path: root/scalatexApi/src/main/scala/scalatex
diff options
context:
space:
mode:
Diffstat (limited to 'scalatexApi/src/main/scala/scalatex')
-rw-r--r--scalatexApi/src/main/scala/scalatex/package.scala15
-rw-r--r--scalatexApi/src/main/scala/scalatex/stages/Compiler.scala150
-rw-r--r--scalatexApi/src/main/scala/scalatex/stages/Parser.scala (renamed from scalatexApi/src/main/scala/scalatex/ScalatexParser.scala)34
3 files changed, 40 insertions, 159 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/package.scala b/scalatexApi/src/main/scala/scalatex/package.scala
index a55f3e3..eb3ba6e 100644
--- a/scalatexApi/src/main/scala/scalatex/package.scala
+++ b/scalatexApi/src/main/scala/scalatex/package.scala
@@ -2,7 +2,7 @@ import scala.reflect.internal.util.{BatchSourceFile, SourceFile, OffsetPosition}
import scala.reflect.io.{PlainFile, AbstractFile}
import scala.reflect.macros.{TypecheckException, Context}
import scalatags.Text.all._
-import scalatex.stages.Compiler
+import scalatex.stages.{Parser, Compiler}
import scala.language.experimental.macros
import acyclic.file
@@ -69,7 +69,7 @@ package object scalatex {
}
def compileThing(c: Context)
- (s: String,
+ (scalatexSource: String,
source: SourceFile,
point: Int,
runtimeErrors: Boolean,
@@ -78,12 +78,17 @@ package object scalatex {
def compile(s: String): c.Tree = {
val realPos = new OffsetPosition(source, point).asInstanceOf[c.universe.Position]
- Compiler(c)(realPos, new ScalatexParser(s).Body.run().get)
+ Compiler(c)(realPos, new Parser(s).Body.run().get)
}
-
+ def normalize(str: String) = {
+ val lines = str.split("\n")
+ val offset = lines.iterator.map(_.takeWhile(_ == ' ').length).min
+ lines.iterator.map(_.drop(offset)).mkString("\n")
+ }
+
import c.Position
try {
- val compiled = compile(s)
+ val compiled = compile(scalatexSource)
if (debug) println(compiled)
c.Expr[Frag](c.typeCheck(compiled))
} catch {
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
index 5127945..a305199 100644
--- a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
+++ b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
@@ -2,7 +2,7 @@ package scalatex
package stages
import acyclic.file
-import scala.reflect.macros.Context
+import scala.reflect.macros.whitebox.Context
import scala.reflect.internal.util.{Position, OffsetPosition}
/**
@@ -27,150 +27,20 @@ object Compiler{
case (curr, Ast.Chain.TypeArgs(str, offset2)) =>
val TypeApply(fun, args) = c.parse(s"omg$str")
TypeApply(curr, args)
+ case (curr, Ast.Block(parts, offset)) =>
+ q"$curr(..${compileBlock(parts, offset)})"
}
-
}
- def compileBlock(parts: Seq[Ast.Block.Sub], offset: Int): c.Tree = {
- val compiledParts = parts.map{
+ def compileBlock(parts: Seq[Ast.Block.Sub], offset: Int): Seq[c.Tree] = {
+ parts.map{
case Ast.Block.Text(str, offset2) => q"$str"
case Ast.Chain(code, parts, offset) => compileChain(code, parts, offset)
}
- q"Seq[$fragType](..$compiledParts)"
}
- ???
-// def compileTree(frag: Ast): Tree = frag match{
-// case Ast.Block(parts, offset)
-//
-//// println(s"${frag.offset}\n${literalPos.point}\n${pos.point}\n$frag\n")
-//
-// val f: Tree = frag match {
-// case Ast.Block.Text(text, offset) => fragPos.at(q"$text", 0)
-// 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) fragPos.set(x, x.pos.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))
-// atPos(a.pos)(a2)
-// atPos(f.pos)(f2)
-// a2
-// case Ident(x: TermName) if x.decoded == fresh =>
-// q"Seq[$fragType](..$b)"
-// }
-// rec(skeleton)
-//
-// 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 =>
-// fragPos.set(x, x.pos.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 =>
-// fragPos.set(x, x.pos.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 res = t match {
-// case Apply(fun, args) =>
-// for(arg <- args; tree <- arg if tree.pos != NoPosition){
-// fragPos.set(tree, tree.pos.point + first.length - fresh.length)
-// }
-//
-// Apply(rec(fun), args)
-// case Select(qualifier, name) => Select(rec(qualifier), name)
-// case Ident(x: TermName) if x.decoded == fresh => l
-// }
-// fragPos.at(res, t.pos.point + first.length - fresh.length)
-//// println(Position.formatMessage(newPos.asInstanceOf[scala.reflect.internal.util.Position], "", true))
-// res
-// }
-// rec(skeleton)
-//
-// case (l, WN.Block(ws, None, content, offset)) =>
-// val contentTrees = content.map(compileTree(_))
-// fragPos.at(q"$l(..$contentTrees)", offset)
-//
-// case (l, WN.Block(ws, Some(args), content, offset)) =>
-//
-// val snippet = s"{$args ()}"
-// val skeleton = c.parse(snippet)
-//
-// val Function(vparams, body) = skeleton
-//
-// vparams.map(_.foreach { t =>
-// if (t.pos != NoPosition)
-// fragPos.set(t, t.pos.point)
-// })
-// val contentTrees = content.map{compileTree(_)}
-//
-// val func = Function(vparams, q"Seq[$fragType](..$contentTrees)")
-// fragPos.at(func, skeleton.pos.point)
-// val res = q"$l($func)"
-// fragPos.at(res, offset)
-// res
-// }
-//
-// s
-// }
-// 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"""{
-// ..${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)}")
+ val res = q"Seq[$fragType](..${compileBlock(template.parts, template.offset)})"
+ println("::::::::::::::::::::::::::::::::::::::::::::::::")
+ println(res)
+ println("::::::::::::::::::::::::::::::::::::::::::::::::")
+ res
}
} \ No newline at end of file
diff --git a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
index a36d2d8..d8878de 100644
--- a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala
+++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
@@ -1,8 +1,9 @@
package scalatex
+package stages
import org.parboiled2._
import torimatomeru.ScalaSyntax
-
+import Util._
trait Ast{
def offset: Int
}
@@ -21,7 +22,12 @@ object Ast{
case class Args(str: String, offset: Int = 0) extends Sub
}
}
-class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
+object Parser{
+ def parse(input: String): Ast.Block = {
+ new Parser(input).Body.run().get
+ }
+}
+class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
val txt = input.sliceString(0, input.length)
val indentTable = txt.split('\n').map{ s =>
if (s.trim == "") -1
@@ -35,7 +41,7 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in
def cursorNextIndent() = {
nextIndentTable(txt.take(cursor).count(_ == '\n'))
}
- println("INDENT " + indent)
+
def TextNot(chars: String) = rule {
capture(oneOrMore(noneOf(chars + "\n") | "@@")) ~> {
x => Ast.Block.Text(x.replace("@@", "@"))
@@ -47,13 +53,13 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in
}
def BlankLine = rule{ '\n' ~ zeroOrMore(' ') ~ &('\n') }
def Indent = rule{ '\n' ~ indent.times(' ') ~ zeroOrMore(' ') }
- def LoneScalaChain: Rule1[Ast.Chain] = rule {
- Indent ~
+ def LoneScalaChain: Rule2[Ast.Block.Text, Ast.Chain] = rule {
+ (capture(Indent) ~> (Ast.Block.Text(_))) ~
ScalaChain ~
zeroOrMore(BlankLine) ~
test(cursorNextIndent() > indent) ~
runSubParser {
- new ScalatexParser(_, cursorNextIndent()).Body
+ new Parser(_, cursorNextIndent()).Body
} ~> { (chain: Ast.Chain, body: Ast.Block) =>
chain.copy(parts = chain.parts :+ body)
}
@@ -63,7 +69,7 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in
Code ~ zeroOrMore(Extension) ~> {Ast.Chain(_, _)}
}
def Extension: Rule1[Ast.Chain.Sub] = rule {
- (capture('.' ~ Id) ~> (Ast.Chain.Prop(_))) |
+ ('.' ~ capture(Id) ~> (Ast.Chain.Prop(_))) |
(capture(TypeArgs2) ~> (Ast.Chain.TypeArgs(_))) |
(capture(ArgumentExprs2) ~> (Ast.Chain.Args(_))) |
TBlock
@@ -78,14 +84,14 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in
def TBlock = rule{ '{' ~ Body ~ '}' }
def Body = rule{
- zeroOrMore(
- LoneScalaChain |
- TextNot("@}") |
- (capture(Indent) ~> (Ast.Block.Text(_))) |
- (capture(BlankLine) ~> (Ast.Block.Text(_))) |
- ScalaChain
+ oneOrMore(
+ LoneScalaChain ~> (Seq(_, _)) |
+ TextNot("@}") ~> (Seq(_)) |
+ (capture(Indent) ~> (x => Seq(Ast.Block.Text(x)))) |
+ (capture(BlankLine) ~> (x => Seq(Ast.Block.Text(x)))) |
+ ScalaChain ~> (Seq(_))
) ~> {x =>
- Ast.Block(x)
+ Ast.Block(x.flatten)
}
}
}