this repo has no description
www.jonmsterling.com/01HC/
1import Foundation
2
3public struct Tree<L: Language>: Sendable {
4 public let kind: L.TreeKind
5 public let metadata: L.TreeMetadata?
6 public let children: [Child<L>]
7 public let utf16Length: Int
8
9 public init(kind: L.TreeKind, metadata: L.TreeMetadata?, children: [Child<L>]) {
10 self.kind = kind
11 self.metadata = metadata
12 self.children = children
13 self.utf16Length = children.reduce(0) { length, child in
14 length + child.utf16Length
15 }
16 }
17}
18
19public enum Child<L: Language>: Sendable {
20 case token(Token<L.TokenKind>, metadata: L.TokenMetadata?)
21 case tree(Tree<L>)
22}
23
24extension Tree {
25 public var text: String {
26 children.map(\.text).joined()
27 }
28}
29
30extension Child {
31 var text: String {
32 switch self {
33 case let .token(tok, _): tok.text
34 case let .tree(tree): tree.text
35 }
36 }
37
38 var utf16Length: Int {
39 switch self {
40 case let .token(token, metadata): token.utf16Length
41 case let .tree(tree): tree.utf16Length
42 }
43 }
44
45 var children: [Self] {
46 switch self {
47 case .token: []
48 case let .tree(tree): tree.children
49 }
50 }
51}
52
53extension Tree: CustomStringConvertible {
54 public var description: String {
55 prettyPrint()
56 }
57
58 /// Pretty-print the tree with indentation.
59 func prettyPrint(indent: String = "") -> String {
60 var result = "\(indent)\(kind)"
61 for child in children {
62 switch child {
63 case .token(let token, _):
64 result += "\n\(indent) \(token.kind): \(token.text.replacingOccurrences(of: "\n", with: "\\n"))"
65 case .tree(let subtree):
66 result += "\n" + subtree.prettyPrint(indent: indent + " ")
67 }
68 }
69 return result
70 }
71}