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
5//
6 // SPDX-License-Identifier: MPL-2.0
7
8 import Foundation
9
10public struct Lexer {
11 private let input: String
12 private var index: String.Index
13 private var tokens: [PterodactylSyntax.Token]
14
15 public init(input: String) {
16 self.input = input
17 self.index = input.startIndex
18 self.tokens = []
19 }
20
21 static let keywords: [String: Keyword] = [
22 "import": .import
23 ]
24
25 public mutating func nextToken() -> Token {
26 guard !isAtEnd else {
27 return Token(kind: .eof, text: "")
28 }
29
30 let char = currentChar
31
32 if char.isNewline {
33 advance()
34 return Token(kind: .whitespace(.newline), text: String(char))
35 }
36
37 if char.isWhitespace {
38 let text = readWhile { $0.isWhitespace && !$0.isNewline }
39 return Token(kind: .whitespace(.other), text: text)
40 }
41
42 if char.isLetter {
43 let word = readWhile { $0.isLetter || $0.isNumber || $0 == "_" }
44 let kind: TokenKind =
45 if let keyword = Self.keywords[word] {
46 .keyword(keyword)
47 } else {
48 .identifier
49 }
50 return Token(kind: kind, text: word)
51 }
52
53 advance()
54 return Token(kind: .error, text: String(char))
55 }
56
57 private mutating func readWhile(_ condition: (Character) -> Bool) -> String {
58 var result = ""
59 while !isAtEnd && condition(currentChar) {
60 result.append(currentChar)
61 advance()
62 }
63 return result
64 }
65
66 private var currentChar: Character { input[index] }
67
68 private var isAtEnd: Bool {
69 index == input.endIndex
70 }
71
72 private mutating func advance() {
73 guard index < input.endIndex else { return }
74 index = input.index(after: index)
75 }
76 }