this repo has no description
www.jonmsterling.com/01HC/
1// SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers
2//
3// SPDX-License-Identifier: MPL-2.0
4
5import Foundation
6
7public struct SyntaxTreeBuilder {
8 private enum Event: Equatable {
9 case open(kind: SyntaxTreeKind, metadata: SyntaxTreeMetadata?)
10 case close
11 case advance(token: Token, metadata: TokenMetadata?)
12 }
13
14 public struct MarkOpened {
15 internal let index: Int
16 }
17
18 private var events: [Event] = []
19
20 public mutating func advance(token: Token, metadata: TokenMetadata?) {
21 events.append(.advance(token: token, metadata: metadata))
22 }
23
24 public mutating func open() -> MarkOpened {
25 let mark = MarkOpened(index: events.count)
26 events.append(.open(kind: .error, metadata: nil))
27 return mark
28 }
29
30 public mutating func close(mark: MarkOpened, kind: SyntaxTreeKind, metadata: SyntaxTreeMetadata?) {
31 events[mark.index] = .open(kind: kind, metadata: metadata)
32 events.append(.close)
33 }
34
35 public var tree: SyntaxTree {
36 var events = events
37 var stack: [SyntaxTree.MutableTree] = []
38
39 precondition(events.popLast() == .close)
40
41 for event in events {
42 switch event {
43 case .open(let kind, let metadata):
44 stack.append(SyntaxTree.MutableTree(kind: kind, metadata: metadata, children: []))
45 case .close:
46 let tree = stack.popLast()!
47 stack.modifyLast { last in
48 last.children.append(.tree(tree.tree))
49 }
50 case .advance(let token, let metadata):
51 stack.modifyLast { last in
52 last.children.append(.token(token, metadata: metadata))
53 }
54 }
55 }
56
57 assert(stack.count == 1)
58 return stack.popLast()!.tree
59 }
60}
61
62
63extension Array {
64 fileprivate mutating func modifyLast(_ modifier: (inout Element) -> Void) {
65 if var last = popLast() {
66 modifier(&last)
67 append(last)
68 }
69 }
70}