summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-04 22:13:05 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-04 22:13:05 -0800
commita99ca0a1c4df83638d888d316a453b6516477a08 (patch)
treeea8be36353210826660582a9a2d11748c79d594b
parent938c026bef8d4ce10848831479944642ac6da853 (diff)
downloadhands-on-scala-js-a99ca0a1c4df83638d888d316a453b6516477a08.tar.gz
hands-on-scala-js-a99ca0a1c4df83638d888d316a453b6516477a08.tar.bz2
hands-on-scala-js-a99ca0a1c4df83638d888d316a453b6516477a08.zip
Narrowed it down to a problem in parboiled2??? It seem like if "f" gets printed, "B" should get printed too...
-rw-r--r--scalatexApi/src/main/scala/scalatex/stages/Compiler.scala17
-rw-r--r--scalatexApi/src/main/scala/scalatex/stages/Parser.scala19
-rw-r--r--scalatexApi/src/test/scala/scalatex/BasicTests.scala30
-rw-r--r--scalatexApi/src/test/scala/scalatex/ParserTests.scala119
4 files changed, 110 insertions, 75 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
index 0ac9844..8bb203a 100644
--- a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
+++ b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala
@@ -17,6 +17,7 @@ object Compiler{
println(template)
def compileChain(code: String, parts: Seq[Ast.Chain.Sub], offset: Int): c.Tree = {
+ println("CODE " + code)
parts.foldLeft(c.parse(code)){
case (curr, Ast.Chain.Prop(str, offset2)) => q"$curr.${TermName(str)}"
case (curr, Ast.Chain.Args(str, offset2)) =>
@@ -37,6 +38,22 @@ object Compiler{
case Ast.Block.Text(str, _) => q"$str"
case Ast.Chain(code, parts, offset) => compileChain(code, parts, offset)
case Ast.Header(header, block, offset) => compileHeader(header, block, offset)
+ case Ast.Block.For(generators, Ast.Block(parts2, offset2), offset) =>
+ val fresh = c.fresh()
+
+ val tree = c.parse(s"$generators yield $fresh" )
+ 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
+ case Ident(x: TermName) if x.decoded == fresh =>
+ q"Seq[$fragType](..${compileBlock(parts2, offset2)})"
+ }
+
+ val out = rec(tree)
+ println(out)
+ out
}
}
def compileHeader(header: String, block: Ast.Block, offset: Int): c.Tree = {
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
index 3b75d54..48138af 100644
--- a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
+++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
@@ -73,17 +73,21 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
def IfElse = rule{
(IfElse1 | IfElse2) ~> (Ast.Block.IfElse(_, _, _))
}
+
+ def ForHead = rule{
+ "@" ~ capture("for" ~ '(' ~ Enumerators ~ ')'~ run(println("f")))
+ }
def ForLoop = rule{
- "@" ~
- capture("for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}')) ~
- BraceBlock ~> (Ast.Block.For(_, _))
+ run(println("A")) ~ ForHead ~ run(println("B")) ~
+ BraceBlock ~ run(println("C")) ~> (Ast.Block.For(_, _))
}
def LoneForLoop = rule{
- "@" ~
- capture("for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}')) ~
+ (capture(Indent) ~> (Ast.Block.Text(_))) ~
+ ForHead ~
IndentBlock ~>
(Ast.Block.For(_, _))
}
+
def ScalaChain = rule {
Code ~ zeroOrMore(Extension) ~> {Ast.Chain(_, _)}
}
@@ -103,10 +107,11 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
def BraceBlock: Rule1[Ast.Block] = rule{ '{' ~ Body ~ '}' }
def BodyItem: Rule1[Seq[Ast.Block.Sub]] = rule{
+ ForLoop ~> (Seq(_)) |
+ LoneForLoop ~> (Seq(_, _)) |
+ IfElse ~> (Seq(_)) |
LoneScalaChain ~> (Seq(_, _)) |
HeaderBlock ~> (Seq(_)) |
- ForLoop ~> (Seq(_)) |
- LoneForLoop ~> (Seq(_)) |
TextNot("@}") ~> (Seq(_)) |
(capture(Indent) ~> (x => Seq(Ast.Block.Text(x)))) |
(capture(BlankLine) ~> (x => Seq(Ast.Block.Text(x)))) |
diff --git a/scalatexApi/src/test/scala/scalatex/BasicTests.scala b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
index f0ee4f8..2412456 100644
--- a/scalatexApi/src/test/scala/scalatex/BasicTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
@@ -298,24 +298,18 @@ object BasicTests extends TestSuite{
//
// 'loops {
//
-// * - check(
-// tw("""
-// @for(x <- 0 until 3)
-// lol
-// """),
-// tw("""
-// @for(x <- 0 until 3){
-// lol
-// }
-// """),
-// tw(
-// """
-// @for(x <- 0 until 3) {
-// lol
-// }
-// """),
-// "lollollol"
-// )
+ * - check(
+ tw("""
+ @for(x <- 0 until 3)
+ lol
+ """),
+ tw("""
+ @for(x <- 0 until 3){
+ lol
+ }
+ """),
+ "lollollol"
+ )
//
//
// * - check(
diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
index c012328..5cefa67 100644
--- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
@@ -4,7 +4,7 @@ package scalatex
import org.parboiled2._
import torimatomeru.ScalaSyntax
-import scalatex.stages.{Parser, Ast}
+import scalatex.stages.{Trim, Parser, Ast}
import scalatex.stages.Ast.Block.{IfElse, For, Text}
import Ast.Chain.Args
@@ -149,57 +149,76 @@ object ParserTests extends utest.TestSuite{
)
}
'ControlFlow{
- 'for - check(
- "@for(x <- 0 until 3){lol}",
- _.ForLoop.run(),
- For("for(x <- 0 until 3)", Block(Seq(Text("lol"))))
- )
- 'forBlock - check(
- """@for(x <- 0 until 3)
- | lol""".stripMargin,
- _.LoneForLoop.run(),
- For("for(x <- 0 until 3)", Block(Seq(Text("\n "), Text("lol"))))
- )
- 'if - check(
- "@if(true){lol}",
- _.IfElse.run(),
- IfElse("if(true)", Block(Seq(Text("lol"))), None)
- )
- 'ifElse - check(
- "@if(true){lol}else{ omg }",
- _.IfElse.run(),
- IfElse("if(true)", Block(Seq(Text("lol"))), Some(Block(Seq(Text(" omg ")))))
- )
- 'ifBlock- check(
- """@if(true)
- | omg""".stripMargin,
- _.IfElse.run(),
- IfElse("if(true)", Block(Seq(Text("\n "), Text("omg"))), None)
- )
- 'ifBlockElseBlock - check(
- """@if(true)
- | omg
- |@else
- | wtf""".stripMargin,
- _.IfElse.run(),
- IfElse(
- "if(true)",
- Block(Seq(Text("\n "), Text("omg"))),
- Some(Block(Seq(Text("\n "), Text("wtf"))))
+ 'for {
+ 'for - check(
+ "@for(x <- 0 until 3){lol}",
+ _.ForLoop.run(),
+ For("for(x <- 0 until 3)", Block(Seq(Text("lol"))))
)
- )
- 'ifElseBlock - check(
- """@if(true){
- | omg
- |}else
- | wtf""".stripMargin,
- _.IfElse.run(),
- IfElse(
- "if(true)",
- Block(Seq(Text("\n "), Text("omg"), Text("\n"))),
- Some(Block(Seq(Text("\n "), Text("wtf"))))
+ 'forBlock - check(
+ """
+ |@for(x <- 0 until 3)
+ | lol""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ For("for(x <- 0 until 3)", Block(Seq(Text("\n "), Text("lol"))))
+ ))
)
- )
+ 'forBlockBraces - check(
+ """
+ |@for(x <- 0 until 3){
+ | lol
+ |}""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ For("for(x <- 0 until 3)", Block(Seq(Text("\n "), Text("lol"))))
+ ))
+ )
+ }
+ 'ifElse {
+ 'if - check(
+ "@if(true){lol}",
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("lol"))), None)
+ )
+ 'ifElse - check(
+ "@if(true){lol}else{ omg }",
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("lol"))), Some(Block(Seq(Text(" omg ")))))
+ )
+ 'ifBlock - check(
+ """@if(true)
+ | omg""".stripMargin,
+ _.IfElse.run(),
+ IfElse("if(true)", Block(Seq(Text("\n "), Text("omg"))), None)
+ )
+ 'ifBlockElseBlock - check(
+ """@if(true)
+ | omg
+ |@else
+ | wtf""".stripMargin,
+ _.IfElse.run(),
+ IfElse(
+ "if(true)",
+ Block(Seq(Text("\n "), Text("omg"))),
+ Some(Block(Seq(Text("\n "), Text("wtf"))))
+ )
+ )
+ 'ifElseBlock - check(
+ """@if(true){
+ | omg
+ |}else
+ | wtf""".stripMargin,
+ _.IfElse.run(),
+ IfElse(
+ "if(true)",
+ Block(Seq(Text("\n "), Text("omg"), Text("\n"))),
+ Some(Block(Seq(Text("\n "), Text("wtf"))))
+ )
+ )
+ }
}
'Body{
'indents - check(