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
7fileprivate struct TokenLocation {
8 let startLine: Int
9 let startColumn: Int
10}
11
12fileprivate struct LocatedToken {
13 let token: Token
14 let location: TokenLocation
15 let lines: [String.SubSequence]
16
17 init(token: Token, location: TokenLocation) {
18 self.token = token
19 self.location = location
20 self.lines = token.text.split(separator: "\n", omittingEmptySubsequences: false)
21 }
22
23 var nextLocation: TokenLocation {
24 let startLine = location.startLine + lines.count - 1
25 let startColumn = if lines.count > 1 { lines.last!.utf16.count } else { lines.last?.utf16.count ?? location.startColumn }
26 return TokenLocation(startLine: startLine, startColumn: startColumn)
27 }
28}
29
30public struct BlockLayoutProcessor {
31 private let locatedTokens: [LocatedToken]
32
33 public init(tokens: [Token]) {
34 var locatedTokens: [LocatedToken] = []
35 var location = TokenLocation(startLine: 0, startColumn: 0)
36 for token in tokens {
37 let locatedToken = LocatedToken(token: token, location: location)
38 locatedTokens.append(locatedToken)
39 location = locatedToken.nextLocation
40 }
41
42 self.locatedTokens = locatedTokens
43 }
44
45
46 public func layout() -> [Token] {
47 var result: [Token] = []
48 var indentStack: [Int] = [0]
49 var previousLine = 0
50 var firstTokenInBlock = false
51
52 for (index, locatedToken) in locatedTokens.enumerated() {
53 guard locatedToken.token.kind != .eof else { break }
54 guard locatedToken.token.kind.canDetermineLayoutColumn else {
55 result.append(locatedToken.token)
56 continue
57 }
58
59 if locatedToken.location.startLine > previousLine {
60 while indentStack.count > 1 && locatedToken.location.startColumn < indentStack.last! {
61 indentStack.removeLast()
62 result.append(Token(kind: .blockEnd, text: ""))
63 }
64
65 if !firstTokenInBlock && indentStack.count > 1 && locatedToken.token.kind.isVisible && locatedToken.location.startColumn == indentStack.last! {
66 result.append(Token(kind: .blockSep, text: ""))
67 }
68 }
69
70 result.append(locatedToken.token)
71
72 if locatedToken.token.kind.isBlockHerald {
73 firstTokenInBlock = true
74
75 if let nextToken = locatedTokens[index...].first(where: { $0.location.startLine > locatedToken.location.startLine && $0.token.kind.canDetermineLayoutColumn }) {
76 result.append(Token(kind: .blockBegin, text: ""))
77 indentStack.append(nextToken.location.startColumn)
78 } else {
79 result.append(Token(kind: .blockBegin, text: ""))
80 result.append(Token(kind: .blockEnd, text: ""))
81 }
82 } else {
83 firstTokenInBlock = false
84 }
85
86 previousLine = locatedToken.location.startLine
87 }
88
89 while indentStack.count > 1 {
90 indentStack.removeLast()
91 result.append(Token(kind: .blockEnd, text: ""))
92 }
93
94 if let eof = locatedTokens.last, eof.token.kind == .eof {
95 result.append(eof.token)
96 }
97
98 return result
99 }
100}