-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
Rhs.scala
105 lines (86 loc) · 3.42 KB
/
Rhs.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* Copyright 2024 fs2-data Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fs2.data.esp
import cats.Show
import cats.syntax.all._
/** This is thre right-hand side of an ESP rule processor.
* It can access the context, meaning:
* - the rule parameters
* - the current state depth
* - the captured inputs
*/
sealed trait Rhs[+OutTag]
object Rhs {
/** Calls a new rule at a given depth with the given parameters. */
case class Call[T](q: Int, depth: Depth, params: List[Rhs[T]]) extends Rhs[T]
/** Calls a new rule at a given depth with the given parameters on the current input. */
case class SelfCall[T](q: Int, params: List[Rhs[T]]) extends Rhs[T]
/** Reads the rule parameter. */
case class Param(n: Int) extends Rhs[Nothing]
/** Empty RHS. */
case object Epsilon extends Rhs[Nothing]
/** Default RHS. Value is used only if the result would be epsilon */
case class Default[T](v: T) extends Rhs[T]
/** Builds a tree. */
case class Tree[OutTag](tag: OutTag, inner: Rhs[OutTag]) extends Rhs[OutTag]
/** Builds a tree with the captured node tag in pattern. */
case class CapturedTree[OutTag](inner: Rhs[OutTag]) extends Rhs[OutTag]
/** Emits a leaf value. */
case class Leaf[OutTag](value: OutTag) extends Rhs[OutTag]
/** Emits the captured input value. */
case object CapturedLeaf extends Rhs[Nothing]
/** Applies the function to a leaf value. */
case class ApplyToLeaf[OutTag](f: OutTag => Either[String, OutTag]) extends Rhs[OutTag]
/** Concatenates two RHS. */
case class Concat[OutTag](fst: Rhs[OutTag], snd: Rhs[OutTag]) extends Rhs[OutTag]
def epsilon[OutTag]: Rhs[OutTag] = Epsilon
implicit def show[O: Show]: Show[Rhs[O]] = Show.show[Rhs[O]] {
case Call(q, d, Nil) => show"q$q[$d]()"
case Call(q, d, params) => show"q$q[$d](${params.mkString_(", ")(show[O], implicitly)})"
case SelfCall(q, Nil) => show"q$q[0](x0)"
case SelfCall(q, params) => show"q$q[0](x0, ${params.mkString_(", ")(show[O], implicitly)})"
case Param(n) => show"y$n"
case Tree(tag, inner) => show"<$tag> { $inner }"
case CapturedTree(inner) => show"<%> { $inner }"
case Leaf(value) => show"$value"
case CapturedLeaf => "%"
case ApplyToLeaf(_) => "$f(%)"
case Concat(fst, snd) => show"$fst $snd"
case Epsilon => ""
case Default(v) => show"($v)?"
}
}
sealed trait Depth {
def apply(d: Int): Int =
this match {
case Depth.Value(d) => d
case Depth.Copy => d
case Depth.Increment => d + 1
case Depth.Decrement => d - 1
}
}
object Depth {
case class Value(d: Int) extends Depth
case object Copy extends Depth
case object Increment extends Depth
case object Decrement extends Depth
implicit val show: Show[Depth] = _ match {
case Value(d) => d.toString()
case Copy => "$d"
case Increment => "$d + 1"
case Decrement => "$d - 1"
}
}