summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-04 21:01:50 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-04 21:01:50 -0800
commitbc675b3e40882bdd8ddbb97a4a717a5672f4980f (patch)
tree568bcc6c3d901bab0ee8357a25e9b3b40df28be9
parent84d025280986302c0435a5910a6a3c9c34d8fc8c (diff)
downloadhands-on-scala-js-bc675b3e40882bdd8ddbb97a4a717a5672f4980f.tar.gz
hands-on-scala-js-bc675b3e40882bdd8ddbb97a4a717a5672f4980f.tar.bz2
hands-on-scala-js-bc675b3e40882bdd8ddbb97a4a717a5672f4980f.zip
Basic if-else-for parsing works
-rw-r--r--scalatexApi/src/main/scala/scalatex/stages/Parser.scala45
-rw-r--r--scalatexApi/src/test/scala/scalatex/BasicTests.scala51
-rw-r--r--scalatexApi/src/test/scala/scalatex/ParserTests.scala48
3 files changed, 105 insertions, 39 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
index e54cb6b..3a5fb97 100644
--- a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
+++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala
@@ -55,15 +55,30 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
def LoneScalaChain: Rule2[Ast.Block.Text, Ast.Chain] = rule {
(capture(Indent) ~> (Ast.Block.Text(_))) ~
ScalaChain ~
- zeroOrMore(BlankLine) ~
test(cursorNextIndent() > indent) ~
- runSubParser {
- new Parser(_, cursorNextIndent()).Body
- } ~> { (chain: Ast.Chain, body: Ast.Block) =>
- chain.copy(parts = chain.parts :+ body)
+ runSubParser(new Parser(_, cursorNextIndent()).Body) ~> {
+ (chain: Ast.Chain, body: Ast.Block) => chain.copy(parts = chain.parts :+ body)
}
}
+ def IfElse = rule{
+ "@" ~ capture("if" ~ "(" ~ Expr ~ ")") ~ TBlock ~ optional("else" ~ TBlock) ~>{
+ Ast.Block.IfElse(_, _, _)
+ }
+ }
+ def ForLoop = rule{
+ "@" ~
+ capture("for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}')) ~
+ TBlock ~> (Ast.Block.For(_, _))
+ }
+ def LoneForLoop = rule{
+ "@" ~
+ capture("for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}')) ~
+ test(cursorNextIndent() > indent) ~
+ runSubParser(new Parser(_, cursorNextIndent()).Body) ~>
+ (Ast.Block.For(_, _))
+ }
+
def ScalaChain = rule {
Code ~ zeroOrMore(Extension) ~> {Ast.Chain(_, _)}
}
@@ -80,15 +95,17 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) {
'(' ~ Ws ~ (optional(Exprs ~ ',' ~ Ws) ~ PostfixExpr ~ ':' ~ Ws ~ '_' ~ Ws ~ '*' ~ Ws | optional(Exprs)) ~ ')'
}
def BlockExpr2: Rule0 = rule { '{' ~ Ws ~ (CaseClauses | Block) ~ '}' }
- def TBlock = rule{ '{' ~ Body ~ '}' }
+ def TBlock: Rule1[Ast.Block] = rule{ '{' ~ Body ~ '}' }
- def BodyItem = rule{
+ def BodyItem: Rule1[Seq[Ast.Block.Sub]] = rule{
LoneScalaChain ~> (Seq(_, _)) |
- HeaderBlock ~> (Seq(_)) |
- TextNot("@}") ~> (Seq(_)) |
- (capture(Indent) ~> (x => Seq(Ast.Block.Text(x)))) |
- (capture(BlankLine) ~> (x => Seq(Ast.Block.Text(x)))) |
- ScalaChain ~> (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)))) |
+ ScalaChain ~> (Seq(_: Ast.Block.Sub))
}
def Body = rule{
oneOrMore(BodyItem) ~> {x =>
@@ -117,9 +134,11 @@ object Ast{
object Block{
trait Sub extends Ast
case class Text(txt: String, offset: Int = 0) extends Block.Sub
-
+ case class For(generators: String, block: Block, offset: Int = 0) extends Block.Sub
+ case class IfElse(condition: String, block: Block, elseBlock: Option[Block], offset: Int = 0) extends Block.Sub
}
case class Header(front: String, block: Block, offset: Int = 0) extends Block.Sub with Chain.Sub
+
/**
* @param lhs The first expression in this method-chain
* @param parts A list of follow-on items chained to the first
diff --git a/scalatexApi/src/test/scala/scalatex/BasicTests.scala b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
index 8acb9b7..f0ee4f8 100644
--- a/scalatexApi/src/test/scala/scalatex/BasicTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/BasicTests.scala
@@ -1,5 +1,6 @@
package scalatex
import utest._
+import scala.collection.mutable.ArrayBuffer
import scalatex.stages._
import scalatags.Text.all._
@@ -241,30 +242,31 @@ object BasicTests extends TestSuite{
)
}
}
-// 'mixed{
-// check(
-// tw("""
-// @div{
-// Hello
-// @div
-// @h1 WORLD @b{!!!}
-// lol
-// @p{
-// @h2{Header 2}
-// }
-// }
-// """),
-// """
-// <div>
-// Hello
-// <div>
-// <h1></h1>WORLD<b>!!!</b>lol
-// <p><h2>Header2</h2></p>
-// </div>
-// </div>
-// """
-// )
-// }
+ 'mixed{
+ check(
+ tw("""
+ @div{
+ Hello
+ @div
+ @h1
+ WORLD @b{!!!}
+ lol
+ @p{
+ @h2{Header 2}
+ }
+ }
+ """),
+ """
+ <div>
+ Hello
+ <div>
+ <h1>WORLD<b>!!!</b>lol</h1>
+ <p><h2>Header2</h2></p>
+ </div>
+ </div>
+ """
+ )
+ }
//
// 'args{
// val things = Seq(1, 2, 3)
@@ -468,4 +470,5 @@ object BasicTests extends TestSuite{
// }
}
}
+
}
diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
index 9301755..c2f35cc 100644
--- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala
+++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala
@@ -5,7 +5,7 @@ import org.parboiled2._
import torimatomeru.ScalaSyntax
import scalatex.stages.{Parser, Ast}
-import Ast.Block.Text
+import scalatex.stages.Ast.Block.{IfElse, For, Text}
import Ast.Chain.Args
object ParserTests extends utest.TestSuite{
@@ -148,6 +148,29 @@ 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 ")))))
+ )
+ }
'Body{
'indents - check(
"""
@@ -181,7 +204,28 @@ object ParserTests extends utest.TestSuite{
Chain("omg",Seq(Block(
Seq(
Text("\n "),
- Chain("wtf",Seq()))
+ Chain("wtf",Seq())
+ )
+ ))),
+ Text("\n"),
+ Chain("bbq", Seq())
+ ))
+ )
+ 'braces - check(
+ """
+ |@omg{
+ | @wtf
+ |}
+ |@bbq""".stripMargin,
+ _.Body.run(),
+ Block(Seq(
+ Text("\n"),
+ Chain("omg",Seq(Block(
+ Seq(
+ Text("\n "),
+ Chain("wtf",Seq()),
+ Text("\n")
+ )
))),
Text("\n"),
Chain("bbq", Seq())