diff options
Diffstat (limited to 'scalatexApi')
5 files changed, 121 insertions, 58 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala index 5704b2c..0ac9844 100644 --- a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala +++ b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala @@ -25,18 +25,29 @@ 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(front, parts, offset)) => - q"$curr(..${compileBlock(front, parts, offset)})" + case (curr, Ast.Block(parts, offset)) => + q"$curr(..${compileBlock(parts, offset)})" + case (curr, Ast.Header(header, block, offset)) => + q"$curr(${compileHeader(header, block, offset)})" + } } - def compileBlock(front: Option[String], parts: Seq[Ast.Block.Sub], offset: Int): Seq[c.Tree] = { + def compileBlock(parts: Seq[Ast.Block.Sub], offset: Int): Seq[c.Tree] = { parts.map{ - case Ast.Block.Text(str, offset2) => q"$str" + 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) } } - val res = q"Seq[$fragType](..${compileBlock(None, template.parts, template.offset)})" + def compileHeader(header: String, block: Ast.Block, offset: Int): c.Tree = { + val Block(stmts, expr) = c.parse(s"{$header\n ()}") + Block(stmts, wrapBlock(compileBlock(block.parts, block.offset))) + } + + def wrapBlock(items: Seq[c.Tree]) = { + q"Seq[$fragType](..$items)" + } + val res = wrapBlock(compileBlock(template.parts, template.offset)) println("::::::::::::::::::::::::::::::::::::::::::::::::") println(res) println("::::::::::::::::::::::::::::::::::::::::::::::::") diff --git a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala index 91738a7..e54cb6b 100644 --- a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala +++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala @@ -44,9 +44,9 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) { "@" ~ capture(Def | Import) } - def HeaderBlock: Rule1[Ast.Block] = rule{ - oneOrMore(Header ~ NewlineS) ~ runSubParser{new Parser(_, indent).Body0} ~> { - (head: Seq[String], body: Ast.Block) => body.copy(front = Some(head.mkString("\n"))) + def HeaderBlock: Rule1[Ast.Header] = rule{ + Header ~ zeroOrMore(capture(NewlineS) ~ Header ~> (_ + _)) ~ runSubParser{new Parser(_, indent).Body0} ~> { + (start: String, heads: Seq[String], body: Ast.Block) => Ast.Header(start + heads.mkString, body) } } @@ -92,12 +92,12 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) { } def Body = rule{ oneOrMore(BodyItem) ~> {x => - Ast.Block(None, x.flatten) + Ast.Block(x.flatten) } } def Body0 = rule{ zeroOrMore(BodyItem) ~> {x => - Ast.Block(None, x.flatten) + Ast.Block(x.flatten) } } } @@ -108,21 +108,18 @@ trait Ast{ object Ast{ /** - * @param front Any parameter lists (if it's a lambda), imports, val/def/lazy-val, - * class/object/trait declarations that occur before the parts of this - * block, and must be in scope within those parts * @param parts The various bits of text and other things which make up this block * @param offset */ - case class Block(front: Option[String], - parts: Seq[Block.Sub], + case class Block(parts: Seq[Block.Sub], offset: Int = 0) extends Chain.Sub with Block.Sub object Block{ trait Sub extends Ast case class Text(txt: String, 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/main/scala/torimatomeru/ScalaSyntax.scala b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala index 5bbd0af..bf0e0e2 100644 --- a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala +++ b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala @@ -166,7 +166,7 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif def Params: Rule0 = rule { zeroOrMore(Param).separatedBy(',') } def Param: Rule0 = rule { zeroOrMore(Annotation) ~ IdS ~ optional(':' ~ ParamType) ~ optional('=' ~ Expr) } def ClassParamClauses: Rule0 = rule { zeroOrMore(ClassParamClause) ~ optional(optional(NewlineS) ~ '(' ~ "implicit" ~ ClassParam ~ ')') } - def ClassParamClause: Rule0 = rule { optional(NewlineS) ~ '(' ~ optional(ClassParam) ~ ')' } + def ClassParamClause: Rule0 = rule { optional(NewlineS) ~ '(' ~ optional(ClassParams) ~ ')' } def ClassParams: Rule0 = rule { oneOrMore(ClassParam).separatedBy(',') } def ClassParam: Rule0 = rule { zeroOrMore(Annotation) ~ optional(zeroOrMore(Modifier) ~ ("val" | "var")) ~ IdS ~ ":" ~ ParamType ~ optional("=" ~ Expr) } diff --git a/scalatexApi/src/test/scala/scalatex/BasicTests.scala b/scalatexApi/src/test/scala/scalatex/BasicTests.scala index c7e2d6a..8acb9b7 100644 --- a/scalatexApi/src/test/scala/scalatex/BasicTests.scala +++ b/scalatexApi/src/test/scala/scalatex/BasicTests.scala @@ -48,28 +48,74 @@ object BasicTests extends TestSuite{ """ ) } -// 'imports{ -// object Whee{ -// def func(x: Int) = x * 2 -// } -// check( -// tw(""" -// @import math._ -// @import Whee.func -// @abs(-10) -// @p -// @max(1, 2) -// @func(2) -// """), -// """ -// 10 -// <p> -// 2 -// 4 -// </p> -// """ -// ) -// } + 'definitions{ + 'imports{ + object Whee{ + def func(x: Int) = x * 2 + } + check( + tw(""" + @import math._ + @import Whee.func + @abs(-10) + @p + @max(1, 2) + @func(2) + """), + """ + 10 + <p> + 2 + 4 + </p> + """ + ) + } + 'valDefVar{ + check( + tw(""" + Hello + @val x = 1 + World @x + @def y = "omg" + mooo + @y + """), + """ + Hello + World 1 + mooo + omg + """ + ) + } + 'classObjectTrait{ + check( + tw(""" + @trait Trait{ + def tt = 2 + } + Hello + @case object moo extends Trait{ + val omg = "wtf" + } + + @moo.toString + @moo.omg + @case class Foo(i: Int, s: String, b: Boolean) + TT is @moo.tt + @Foo(10, "10", true).toString + """), + """ + Hello + moo + wtf + TT is 2 + Foo(10, 10, true) + """ + ) + } + } 'parenArgumentLists{ 'attributes{ check( diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala index f6d443f..9301755 100644 --- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala +++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala @@ -12,8 +12,8 @@ object ParserTests extends utest.TestSuite{ import Ast._ import utest._ def check[T](input: String, parse: Parser => scala.util.Try[T], expected: T) = { - val parsed = parse(new Parser(input)) - assert(parsed.get == expected) + val parsed = parse(new Parser(input)).get + assert(parsed == expected) } def tests = TestSuite{ 'Trim{ @@ -100,18 +100,28 @@ object ParserTests extends utest.TestSuite{ |hello world |""".stripMargin, _.HeaderBlock.run(), - Ast.Block( - Some("import math.abs\nimport math.sin"), - Seq(Text("\n"), Text("hello world"), Text("\n")) + Ast.Header( + "import math.abs\nimport math.sin", + Ast.Block( + Seq(Text("\n"), Text("\n"), Text("hello world"), Text("\n")) + ) ) ) } + 'caseclass{ + check( + """@case class Foo(i: Int, s: String) + """.stripMargin, + _.Header.run(), + "case class Foo(i: Int, s: String)" + ) + } } 'Block{ - * - check("{i am a cow}", _.TBlock.run(), Block(None, Seq(Block.Text("i am a cow")))) + * - check("{i am a cow}", _.TBlock.run(), Block(Seq(Block.Text("i am a cow")))) * - check("{i @am a @cow}", _.TBlock.run(), - Block(None, Seq( + Block(Seq( Block.Text("i "), Chain("am",Seq()), Block.Text(" a "), @@ -131,10 +141,10 @@ object ParserTests extends utest.TestSuite{ ) * - check("@omg{bbq}.cow(moo){a @b}\n", _.ScalaChain.run(), Chain("omg",Seq( - Block(None, Seq(Block.Text("bbq"))), + Block(Seq(Block.Text("bbq"))), Chain.Prop("cow"), Chain.Args("(moo)"), - Block(None, Seq(Block.Text("a "), Chain("b", Nil))) + Block(Seq(Block.Text("a "), Chain("b", Nil))) )) ) } @@ -146,13 +156,13 @@ object ParserTests extends utest.TestSuite{ | @bbq | @lol""".stripMargin, _.Body.run(), - Block(None, Seq( + Block(Seq( Text("\n"), - Chain("omg",Seq(Block(None, Seq( + Chain("omg",Seq(Block(Seq( Text("\n "), - Chain("wtf",Seq(Block(None, Seq( + Chain("wtf",Seq(Block(Seq( Text("\n "), - Chain("bbq",Seq(Block(None, Seq( + Chain("bbq",Seq(Block(Seq( Text("\n "), Chain("lol",Seq()) )))) @@ -166,10 +176,9 @@ object ParserTests extends utest.TestSuite{ | @wtf |@bbq""".stripMargin, _.Body.run(), - Block(None, Seq( + Block(Seq( Text("\n"), Chain("omg",Seq(Block( - None, Seq( Text("\n "), Chain("wtf",Seq())) @@ -184,11 +193,11 @@ object ParserTests extends utest.TestSuite{ | @wtf |bbq""".stripMargin, _.Body.run(), - Block(None, Seq( + Block(Seq( Text("\n"), Chain("omg",Seq( Args("""("lol", 1, 2)"""), - Block(None, Seq( + Block(Seq( Text("\n "), Chain("wtf",Seq()))) )), @@ -224,7 +233,7 @@ object ParserTests extends utest.TestSuite{ | omg * 2 |}""".stripMargin, _.Body.run(), - Block(None, Seq( + Block(Seq( Text("\n"), Chain("{\"lol\" * 3}", Seq()), Text("\n"), |