aboutsummaryrefslogtreecommitdiff
path: root/Sources/WmapParser/WmapParser.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Sources/WmapParser/WmapParser.swift')
-rw-r--r--Sources/WmapParser/WmapParser.swift125
1 files changed, 63 insertions, 62 deletions
diff --git a/Sources/WmapParser/WmapParser.swift b/Sources/WmapParser/WmapParser.swift
index 41843b3..ef203ec 100644
--- a/Sources/WmapParser/WmapParser.swift
+++ b/Sources/WmapParser/WmapParser.swift
@@ -2,75 +2,76 @@ import Foundation
public struct WmapParser {
- // Public API //////////////////////////////////////////////////////////////////
+ // Public API //////////////////////////////////////////////////////////////////
- /// Parses a wmap source string.
- public static func parse(_ source: String) -> Map {
- source.utf8.withContiguousStorageIfAvailable { bytes in
- parseBytes(bytes)
- } ?? parseBytes(Array(source.utf8))
- }
-
- // Parsers /////////////////////////////////////////////////////////////////////
+ /// Parses a wmap source string.
+ public static func parse(_ source: String) -> Map {
+ source.utf8.withContiguousStorageIfAvailable { bytes in
+ parseBytes(bytes)
+ } ?? parseBytes(Array(source.utf8))
+ }
- /// Main parsing function, we work on bytes as it's faster.
- private static func parseBytes<T: Collection>(_ bytes: T) -> Map where T.Element == UInt8, T.Index == Int {
- let estimatedLines = bytes.count / 30
+ // Parsers /////////////////////////////////////////////////////////////////////
- var context = LineParserContext(
- components: [],
- dependencies: [],
- keywordContext: KeywordParserContext(
- stages: [],
- notes: [],
- groups: [],
- inertias: [],
- evolutions: []
- )
- )
+ /// Main parsing function, we work on bytes as it's faster.
+ private static func parseBytes<T: Collection>(_ bytes: T) -> Map
+ where T.Element == UInt8, T.Index == Int {
+ let estimatedLines = bytes.count / 30
- context.components.reserveCapacity(estimatedLines)
- context.dependencies.reserveCapacity(estimatedLines)
- context.keywordContext.notes.reserveCapacity(estimatedLines / 10)
- context.keywordContext.stages.reserveCapacity(4)
- context.keywordContext.groups.reserveCapacity(estimatedLines / 20)
- context.keywordContext.inertias.reserveCapacity(estimatedLines / 20)
- context.keywordContext.evolutions.reserveCapacity(estimatedLines / 20)
+ var context = LineParserContext(
+ components: [],
+ dependencies: [],
+ keywordContext: KeywordParserContext(
+ stages: [],
+ notes: [],
+ groups: [],
+ inertias: [],
+ evolutions: []
+ )
+ )
- var index = 0
- let length = bytes.count
+ context.components.reserveCapacity(estimatedLines)
+ context.dependencies.reserveCapacity(estimatedLines)
+ context.keywordContext.notes.reserveCapacity(estimatedLines / 10)
+ context.keywordContext.stages.reserveCapacity(4)
+ context.keywordContext.groups.reserveCapacity(estimatedLines / 20)
+ context.keywordContext.inertias.reserveCapacity(estimatedLines / 20)
+ context.keywordContext.evolutions.reserveCapacity(estimatedLines / 20)
- while index < length {
- guard let (start, end) = extractLine(bytes, &index, length) else { continue }
- parseLine(bytes, start, end, &context)
- }
+ var index = 0
+ let length = bytes.count
- return Map(
- components: context.components,
- dependencies: context.dependencies,
- notes: context.keywordContext.notes,
- stages: context.keywordContext.stages,
- groups: context.keywordContext.groups,
- inertias: context.keywordContext.inertias,
- evolutions: context.keywordContext.evolutions
- )
+ while index < length {
+ guard let (start, end) = extractLine(bytes, &index, length) else { continue }
+ parseLine(bytes, start, end, &context)
}
- /// Given a trimmed line, checks if it's a keyword, dependency or component
- /// and parses it.
- @inline(__always)
- private static func parseLine<T: Collection>(
- _ bytes: T, _ start: Int, _ end: Int,
- _ context: inout LineParserContext
- ) where T.Element == UInt8, T.Index == Int {
- if bytes[start] == kOpenSquareBracket {
- parseKeywordLine(bytes, start, end, &context.keywordContext)
- } else if let separatorIndex = hasDependency(bytes, start, end) {
- if let dependency = parseDependency(bytes, start, end, separatorIndex) {
- context.dependencies.append(dependency)
- }
- } else if let component = parseComponent(bytes, start, end) {
- context.components.append(component)
- }
- }
+ return Map(
+ components: context.components,
+ dependencies: context.dependencies,
+ notes: context.keywordContext.notes,
+ stages: context.keywordContext.stages,
+ groups: context.keywordContext.groups,
+ inertias: context.keywordContext.inertias,
+ evolutions: context.keywordContext.evolutions
+ )
+ }
+
+ /// Given a trimmed line, checks if it's a keyword, dependency or component
+ /// and parses it.
+ @inline(__always)
+ private static func parseLine<T: Collection>(
+ _ bytes: T, _ start: Int, _ end: Int,
+ _ context: inout LineParserContext
+ ) where T.Element == UInt8, T.Index == Int {
+ if bytes[start] == kOpenSquareBracket {
+ parseKeywordLine(bytes, start, end, &context.keywordContext)
+ } else if let separatorIndex = hasDependency(bytes, start, end) {
+ if let dependency = parseDependency(bytes, start, end, separatorIndex) {
+ context.dependencies.append(dependency)
+ }
+ } else if let component = parseComponent(bytes, start, end) {
+ context.components.append(component)
+ }
+ }
}