this repo has no description
www.jonmsterling.com/01HC/
1import Foundation
2
3public struct SyntaxTree: Codable, Sendable {
4 public let kind: SyntaxTreeKind
5 public let metadata: SyntaxTreeMetadata?
6 public let children: [Child]
7 public let utf16Length: Int
8
9 public enum Child: Codable, Sendable {
10 case token(Token, metadata: TokenMetadata?)
11 case tree(SyntaxTree)
12 }
13
14 public init(kind: SyntaxTreeKind, metadata: SyntaxTreeMetadata?, children: [SyntaxTree.Child]) {
15 self.kind = kind
16 self.metadata = metadata
17 self.children = children
18 self.utf16Length = children.reduce(0) { length, child in
19 length + child.utf16Length
20 }
21 }
22}
23
24extension SyntaxTree {
25 public var text: String {
26 children.map(\.text).joined()
27 }
28}
29
30extension SyntaxTree.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, _): 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 SyntaxTree: 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}