Skip to content

Commit 7e3b465

Browse files
committed
more layers; broke Dotty again WIP
1 parent 957eb8b commit 7e3b465

File tree

1 file changed

+166
-49
lines changed

1 file changed

+166
-49
lines changed

src/main/scala/Polyparse.scala

Lines changed: 166 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ sealed trait Grammar[AT:Type,T:Type,ET:Type] {
88
val tType = implicitly[Type[T]]
99
val eType = implicitly[Type[ET]]
1010
val aType = implicitly[Type[AT]]
11+
type t = T
12+
type at = AT
1113
}
1214

1315
private case class Terminal[T:Type:Liftable](val v : T) extends Grammar[Unit,T,T] {
@@ -17,7 +19,7 @@ private case class ArgumentTerminal[T:Type]() extends Grammar[T,T,T]
1719
private case class ArgToVal[T:Type]() extends Grammar[T,T,Any]
1820
private case class ReadPos() extends Grammar[Unit,Int,Any]
1921
private case class Call[AT1:Type,AT2:Type,T:Type,ET:Type](val arg : Grammar[AT1,AT2,ET], val fn : Grammar[AT2,T,ET]) extends Grammar[AT1,T,ET]
20-
private case class Sequence[LAT:Type,RAT:Type,LT:Type,RT:Type,ET:Type](val left : Grammar[LAT,LT,ET], val right : Grammar[RAT,RT,ET]) extends Grammar[(LAT,RAT),(LT,RT),ET]
22+
private case class Sequence[AT:Type,LT:Type,RT:Type,ET:Type](val left : Grammar[AT,LT,ET], val right : Grammar[AT,RT,ET]) extends Grammar[AT,(LT,RT),ET]
2123
private case class Check[AT:Type,ET:Type](val g : Grammar[AT,Any,ET]) extends Grammar[AT,Unit,ET]
2224
private case class Disjunction[AT:Type,T:Type,ET:Type](val left : Grammar[AT,T,ET], val right : Grammar[AT,T,ET]) extends Grammar[AT,T,ET]
2325
private case class Condition[AT:Type,T:Type,ET:Type](val g : Grammar[AT,T,ET], val cond : Expr[T] => Expr[Boolean]) extends Grammar[AT,T,ET]
@@ -27,6 +29,34 @@ private class Recursion[AT:Type,T:Type,ET:Type](_g : =>Grammar[AT,T,ET]) extends
2729
lazy val g = _g
2830
}
2931

32+
sealed trait BlockIR[In:Type,Out:Type] {
33+
val tIn = implicitly[Type[In]]
34+
val tOut = implicitly[Type[Out]]
35+
}
36+
37+
trait BlockContext[In:Type,-Out:Type] {
38+
def fail : Expr[Unit]
39+
def arg : Expr[In]
40+
def succeed(v : Expr[Out]) : Expr[Unit]
41+
}
42+
43+
case class BranchIR[In:Type,Out:Type](val condition : BlockContext[In,Out] => Expr[Boolean], val yes : BlockIR[In,Out], val no : BlockIR[In,Out]) extends BlockIR[In,Out]
44+
case class PreserveArgIR[In:Type,Out:Type](val g : BlockIR[In,Out]) extends BlockIR[In,(In,Out)] // produces a tuple of original arg and g's result
45+
case class SeqIR[In:Type,Mid:Type,Out:Type](val from : BlockIR[In,Mid], val to : BlockIR[Mid,Out]) extends BlockIR[In,Out] // makes result of from arg of to
46+
case class CallIR[In:Type,Out:Type](val key : AnyRef) extends BlockIR[In,Out]
47+
case class RecoverIR[In:Type,Out:Type](val first : BlockIR[In,Out], val second : BlockIR[In,Out]) extends BlockIR[In,Out]
48+
case class SimpleIR[In:Type,Out:Type](val fn : BlockContext[In,Out] => Expr[Unit]) extends BlockIR[In,Out]
49+
50+
sealed trait BlockIR2[In:Type] {
51+
val tIn = implicitly[Type[In]]
52+
type in = In
53+
}
54+
55+
case class BranchIR2[In:Type](val condition : BlockContext[In,Any] => Expr[Boolean], val yes : BlockIR2[In], val no : BlockIR2[In]) extends BlockIR2[In]
56+
case class BeforeIR2[In:Type,In2:Type](val map : BlockContext[In,In2] => Expr[Unit], val next : BlockIR2[In2]) extends BlockIR2[In]
57+
case class JumpIR2[In:Type](val key : AnyRef, val ret : AnyRef) extends BlockIR2[In]
58+
case class ReturnIR2[In:Type]() extends BlockIR2[In]
59+
3060
trait SequenceContext[ET:Type] {
3161
type Mark
3262
def mark : Expr[Mark]
@@ -57,68 +87,121 @@ trait MakeSequenceContext[Seq[_]] {
5787
def makeCtx[ET:Type,Result:Type](fn : SequenceContext[ET] => Expr[Result]) : Expr[Seq[ET] => Result]
5888
}
5989

60-
case class BlockCompiler[ET:Type,Result](seqCtx : SequenceContext[ET], flowCtx : ControlFlowContext[Option[Result]],
61-
recursions : Set[Grammar[_,_,_]], recMap : Map[AnyRef,flowCtx.Label]) {
62-
def handleRec[AT:Type,T:Type](g : Grammar[AT,T,ET], arg : Expr[AT], yes : Expr[T]=>Expr[Unit], no : Expr[Unit]) : Expr[Unit] = {
63-
if recursions.contains(g) then {
64-
val recLabel = flowCtx.block(recLabel => {
65-
this.copy(recMap=recMap.+((g, recLabel))).computeValue(g, flowCtx.callReg[AT], flowCtx.ret(_), flowCtx.end('{None}))
66-
})
67-
val retLabel = flowCtx.block(yes(flowCtx.retReg[T]))
68-
flowCtx.call(recLabel, retLabel, arg)
69-
} else {
70-
computeValue(g, arg, yes, no)
71-
}
72-
}
73-
def computeValue[AT:Type,T:Type](g : Grammar[AT,T,ET], arg : Expr[AT], yes : Expr[T]=>Expr[Unit], no : Expr[Unit]) : Expr[Unit] = g match {
74-
case t@Terminal(v) => {
75-
implicit val _ = t.liftable
76-
'{
77-
if ${seqCtx.isEOF} then $no else {
78-
val curr = ${seqCtx.peek}
79-
if curr == ${v.toExpr}
80-
then {
81-
${seqCtx.next}
82-
${yes('{curr})}
83-
} else $no
84-
}
85-
}
86-
}
87-
case Disjunction(l,r) => {
88-
val lv = computeValue(l, arg, yes, no)
89-
val rv = computeValue(r, arg, yes, no)
90-
'{ // this is eager disjunction, TODO "correct" backtracking disjunction option
91-
if ${speculateReachable(l, arg)}
92-
then ${lv}
93-
else ${rv}
94-
}
95-
}
96-
case r : Recursion[AT,T,ET] => {
97-
val retLabel = flowCtx.block(yes(flowCtx.retReg[T]))
98-
flowCtx.call(recMap.get(r.g).get, retLabel, arg)
99-
}
100-
case _ => ???
101-
}
90+
case class BlockCompiler[ET:Type,Result](seqCtx : SequenceContext[ET]) {
10291
def speculateReachable[AT:Type,T:Type](g : Grammar[AT,T,ET], arg : Expr[AT]) : Expr[Boolean] = g match {
10392
case t@Terminal(v) => {
10493
implicit val _ = t.liftable
10594
'{ !${seqCtx.isEOF} && ${seqCtx.peek} == ${v.toExpr}}
10695
}
10796
case Disjunction(l,r) => '{ ${speculateReachable(l, arg)} || ${speculateReachable(r, arg)} }
97+
case Sequence(l,r) => {
98+
implicit val _ = l.tType
99+
speculateReachable(l, arg)
100+
}
101+
case ArgumentTerminal() => '{ !${seqCtx.isEOF} && ${seqCtx.peek} == $arg }
102+
case Call(l,_) => {
103+
implicit val _ = l.tType
104+
speculateReachable(l, arg)
105+
}
106+
case Condition(gg,cond) => speculateReachable(gg, arg)
107+
case MapArg(to,fn) => {
108+
implicit val _ = to.aType
109+
speculateReachable(to, fn(arg))
110+
}
111+
case MapVal(gg,_) => {
112+
implicit val _ = gg.tType
113+
speculateReachable(gg, arg)
114+
}
115+
case Check(gg) => speculateReachable(gg, arg)
108116
case r : Recursion[AT,T,ET] => speculateReachable(r.g, arg) // speculate past calls to avoid redundantly calling parser we know will fail
109117
// note: this only works if the parser terminates :) ... maybe catch obvious
110118
// non-termination later
111119
case _ => ???
112120
}
121+
def computeBlocks[AT:Type,T:Type](g : Grammar[AT,T,ET]) : Seq[(AnyRef, BlockIR[_,_])] = g match {
122+
case t@Terminal(v) => Seq(
123+
(t, SimpleIR[AT,T](ctx => {
124+
implicit val _ = t.liftable
125+
'{
126+
if !${seqCtx.isEOF} && ${seqCtx.peek} == ${v.toExpr}
127+
then ${ctx.succeed(v.toExpr)}
128+
else ${ctx.fail}
129+
}
130+
}))
131+
)
132+
case Disjunction(l, r) => Seq(
133+
(g, BranchIR[AT,T](
134+
condition=ctx => speculateReachable(l, ctx.arg),
135+
yes=CallIR[AT,T](l),
136+
no=CallIR[AT,T](r),
137+
))
138+
) ++ computeBlocks(l) ++ computeBlocks(r)
139+
case Sequence(l, r) => {
140+
implicit val _ = l.tType
141+
implicit val _1 = r.tType
142+
type LT = l.t
143+
type RT = r.t
144+
Seq(
145+
(g, SeqIR(
146+
PreserveArgIR(CallIR[AT,LT](l)),
147+
SeqIR(
148+
PreserveArgIR(SeqIR(
149+
SimpleIR[(AT,LT),AT](ctx => ctx.succeed('{${ctx.arg} match { case (in,_) => in }})),
150+
CallIR[AT,RT](r)
151+
)),
152+
SimpleIR[((AT,LT),RT),(LT,RT)](ctx => ctx.succeed('{${ctx.arg} match { case ((_,res1),res2) => (res1,res2) }}))
153+
)
154+
)),
155+
) ++ computeBlocks(l) ++ computeBlocks(r)
156+
}
157+
case Call(arg, fn) => {
158+
implicit val _ = arg.tType
159+
type AAT = arg.t
160+
Seq(
161+
(g, SeqIR(CallIR[AT,AAT](arg), CallIR[AAT,T](fn)))
162+
) ++ computeBlocks(arg) ++ computeBlocks(fn)
163+
}
164+
case ArgumentTerminal() => Seq(
165+
(g, SimpleIR(ctx => '{
166+
if !${seqCtx.isEOF} && ${seqCtx.peek} == ${ctx.arg}
167+
then ${ctx.succeed(ctx.arg)}
168+
else ${ctx.fail}
169+
}))
170+
)
171+
case Condition(gg, cond) => Seq(
172+
(g, SeqIR(CallIR[AT,T](gg), SimpleIR[T,T](ctx => '{
173+
if ${cond(ctx.arg)}
174+
then ${ctx.succeed(ctx.arg)}
175+
else ${ctx.fail}
176+
})))
177+
) ++ computeBlocks(gg)
178+
case MapArg(to,fn) => {
179+
implicit val _ = to.aType
180+
type TAT = to.at
181+
Seq(
182+
(g, SeqIR(SimpleIR[AT,TAT](ctx => ctx.succeed(fn(ctx.arg))), CallIR[TAT,T](to)))
183+
) ++ computeBlocks(to)
184+
}
185+
case MapVal(from,fn) => {
186+
implicit val _ = from.tType
187+
type FT = from.t
188+
Seq(
189+
(g, SeqIR(CallIR[AT,FT](from), SimpleIR[FT,T](ctx => ctx.succeed(fn(ctx.arg)))))
190+
) ++ computeBlocks(from)
191+
}
192+
case r : Recursion[AT,T,ET] => Seq((g, CallIR[AT,T](r.g)))
193+
case _ => ???
194+
}
113195
}
114196

115197
object PolyParse {
116198

117199
private def maybeRecurse[AT:Type,T:Type,ET:Type](g : =>Grammar[AT,T,ET]) : Grammar[AT,T,ET] = if g == null then new Recursion(g) else g
118200

119-
implicit class MaybeRecursion[AT1:Type,T:Type,ET:Type](g : =>Grammar[AT1,T,ET]) {
120-
def <|>(other : =>Grammar[AT1,T,ET]) : Grammar[AT1,T,ET] = Disjunction(maybeRecurse(g), maybeRecurse(other))
121-
def ++[AT2:Type,Other:Type](other : =>Grammar[AT2,Other,ET]) : Grammar[(AT1,AT2),(T,Other),ET] = Sequence(maybeRecurse(g), maybeRecurse(other))
201+
202+
implicit class MaybeRecursion[AT:Type,T:Type,ET:Type](g : =>Grammar[AT,T,ET]) {
203+
def <|>(other : =>Grammar[AT,T,ET]) : Grammar[AT,T,ET] = Disjunction(maybeRecurse(g), maybeRecurse(other))
204+
def ++[Other:Type](other : =>Grammar[AT,Other,ET]) : Grammar[AT,(T,Other),ET] = Sequence(maybeRecurse(g), maybeRecurse(other))
122205
//def map[T2:Type](fn : Expr[T] => Expr[T2]) : Grammar[T2,ET] = Mapping(maybeRecurse(g), fn)
123206
//def ??(cond : Expr[T] => Expr[Boolean]) : Grammar[T,ET] = Condition(maybeRecurse(g), cond)
124207
}
@@ -141,6 +224,7 @@ object PolyParse {
141224
}}
142225
}
143226

227+
144228
def makeControlFlowContext[Result:Type](fn : ControlFlowContext[Result] => Unit) : Expr[Result] = '{
145229
import collection.mutable.ArrayStack
146230
val stackPC : ArrayStack[Int] = new ArrayStack
@@ -189,6 +273,29 @@ object PolyParse {
189273
retReg_.asInstanceOf[Result]
190274
}
191275

276+
def performInlining(blocks : Seq[(AnyRef,BlockIR[_,_])]) : Seq[(AnyRef,BlockIR[_,_])] = blocks // FIXME: actually do it
277+
278+
def splitBasicBlocks[In:Type,Out:Type](b : BlockIR[In,Out], rest : BlockIR2[Out]) : (BlockIR2[In],Seq[(AnyRef,BlockIR2[_])]) = b match {
279+
case BranchIR(condition,yes,no) => {
280+
val (yBlock, yBlocks) = splitBasicBlocks(yes,rest)
281+
val (nBlock, nBlocks) = splitBasicBlocks(no,rest)
282+
(BranchIR2[In](condition,yBlock,nBlock), yBlocks ++ nBlocks)
283+
}
284+
case SeqIR(left,right) => {
285+
implicit val _ = left.tOut
286+
val (rBlock, rBlocks) = splitBasicBlocks(right,rest)
287+
val (lBlock, lBlocks) = splitBasicBlocks(left, rBlock)
288+
(lBlock, lBlocks ++ rBlocks)
289+
}
290+
case CallIR(key) => {
291+
(JumpIR2(key,(key,rest)), Seq(((key,rest),rest)))
292+
}
293+
case SimpleIR(fn) => {
294+
(BeforeIR2[In,Out](fn, rest), Seq())
295+
}
296+
case _ => ???
297+
}
298+
192299
def compile[T:Type,ET:Type,Seq[_]:MakeSequenceContext](g : Grammar[Unit,T,ET])(implicit seqT : Type[Seq[T]]) : Expr[Seq[ET] => Option[T]] = {
193300
def findRecursions[AT,T,ET](g : Grammar[AT,T,ET]) : Set[Grammar[_,_,_]] = g match {
194301
case Terminal(_) => Set.empty
@@ -203,8 +310,18 @@ object PolyParse {
203310
implicitly[MakeSequenceContext[Seq]].makeCtx(seqCtx => {
204311
makeControlFlowContext[Option[T]](flowCtx => {
205312
flowCtx.block(root => {
206-
val compiler = BlockCompiler(seqCtx, flowCtx, recursions, Map.empty.+((g, root)))
207-
compiler.handleRec(g, '{()}, res => flowCtx.end('{Some($res)}), flowCtx.end('{None}))
313+
val compiler = BlockCompiler(seqCtx)
314+
val blocks = compiler.computeBlocks(g)
315+
val inlinedBlocks = performInlining(blocks)
316+
val basicBlocks = inlinedBlocks.flatMap(block => {
317+
val (key,b) = block
318+
implicit val _ = b.tIn
319+
implicit val _1 = b.tOut
320+
val root, blocks = splitBasicBlocks(b, ReturnIR2())
321+
Seq((key,root),blocks)
322+
})
323+
println(basicBlocks)
324+
'{()}
208325
})
209326
})
210327
})
@@ -214,7 +331,7 @@ object PolyParse {
214331
import scala.quoted.Toolbox.Default._
215332
object vv {
216333
val v : Grammar[Unit,Int,Int] = term(1) <|> term(2) <|> v
217-
val v2 : Grammar[(Unit,Unit),(Int,Int),Int] = (term(1) ++ term(2)) <|> v2
334+
val v2 : Grammar[Unit,(Int,Int),Int] = (term(1) ++ term(2)) <|> v2
218335
}
219336
println(compile[Int,Int,List](vv.v).show)
220337
}

0 commit comments

Comments
 (0)