-
Notifications
You must be signed in to change notification settings - Fork 11
/
Indented.scala
36 lines (30 loc) · 1.09 KB
/
Indented.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
package org.bykn.bosatsu
import org.typelevel.paiges.{Doc, Document}
import cats.parse.{Parser => P}
case class Indented[T](spaces: Int, value: T) {
require(spaces > 0, s"need non-empty indentation: $spaces")
}
object Indented {
def spaceCount(str: String): Int =
str.foldLeft(0) {
case (s, ' ') => s + 1
case (s, '\t') => s + 4
case (_, c) => sys.error(s"unexpected space character($c) in $str")
}
implicit def document[T: Document]: Document[Indented[T]] =
Document.instance[Indented[T]] { case Indented(i, t) =>
Doc.spaces(i) + (Document[T].document(t).nested(i))
}
/** This reads a new line at a deeper indentation level than we currently are.
*
* So we are starting from the 0 column and read the current indentation
* level plus at least one space more
*/
def indy[T](p: Parser.Indy[T]): Parser.Indy[Indented[T]] =
Parser.Indy { indent =>
for {
thisIndent <- P.string0(indent).with1.soft *> Parser.spaces.string
t <- p.run(indent + thisIndent)
} yield Indented(Indented.spaceCount(thisIndent), t)
}
}