Skip to content

Commit

Permalink
line and column
Browse files Browse the repository at this point in the history
  • Loading branch information
ay42 committed Aug 6, 2023
1 parent 769b695 commit d491d1d
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 120 deletions.
6 changes: 5 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ let package = Package(
],
targets: [
.target(
name: "Coder"),
name: "Coder",
dependencies: [
.product(name: "Binary", package: "swift-binary")
]
),
.testTarget(
name: "CoderTests",
dependencies: ["Coder"]),
Expand Down
2 changes: 1 addition & 1 deletion Sources/Coder/Coder.swift
Original file line number Diff line number Diff line change
@@ -1 +1 @@

@_exported import Binary
12 changes: 12 additions & 0 deletions Sources/StringDecoder/Combinators/StringDecoder+Chain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,16 @@ public extension StringDecoder {

return flatMap(rest)
}

func chainRight(_ op: StringDecoder<(Element, Element) -> Element, Failure>) -> Self {
func rest(_ x: Element) -> Self {
op.flatMap { f in
self.chainRight(op).map { y in
f(x, y)
}
}.or(pure(x))
}

return self.flatMap(rest)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public extension StringDecoder {
case .success:
return self.decode(input)
case .failure:
return self.decode(State(string: "", offset: input.offset))
return self.decode(State(string: "", offset: input.offset, line: input.line, column: input.column))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public extension StringDecoder {
StringDecoder { input in
switch forwardEncoder(input) {
case .success:
return self.decode(State(string: "", offset: input.offset))
return self.decode(State(string: "", offset: input.offset, line: input.line, column: input.column))
case .failure:
return self.decode(input)
}
Expand Down
24 changes: 0 additions & 24 deletions Sources/StringDecoder/Decoders/StringDecoder+Indent.swift

This file was deleted.

13 changes: 13 additions & 0 deletions Sources/StringDecoder/Decoders/StringDecoder+Parentheses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@ import Foundation
public let leftParentheses: StringDecoder<Character, StringDecoderFailure> = match(Character("("))

public let rightParentheses: StringDecoder<Character, StringDecoderFailure> = match(Character(")"))


public let leftCurlyBracket: StringDecoder<Character, StringDecoderFailure> = match(Character("{"))
public let rightCurlyBracket: StringDecoder<Character, StringDecoderFailure> = match(Character("}"))

public extension StringDecoder where Failure == StringDecoderFailure {
var insideCurlyBrackets: Self {
self.between(
open: leftCurlyBracket.discard(whitespace()),
close: whitespace().discardThen(rightCurlyBracket)
)
}
}
5 changes: 5 additions & 0 deletions Sources/StringDecoder/Decoders/StringDecoder+Sigil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public func isSigil(_ c: Character) -> Bool {
c == "$"
}
8 changes: 8 additions & 0 deletions Sources/StringDecoder/Decoders/StringDecoder+Whitespace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ public func space() -> StringDecoder<String, StringDecoderFailure> {
public func newline() -> StringDecoder<String, StringDecoderFailure> {
match("\n")
}

public let horizontalWhitespace: StringDecoder<String, StringDecoderFailure> = tab().or(space()).many.map { String($0.flatMap { $0 }) }

public extension StringDecoder where Failure == StringDecoderFailure {
var insideHorizontalWhitespace: Self {
self.between(horizontalWhitespace)
}
}
56 changes: 44 additions & 12 deletions Sources/StringDecoder/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,66 @@ import Foundation
public struct State: Equatable {
public let string: String
public var offset: UInt64
public internal(set) var indentation: Int

public init(string: String, offset: UInt64, indentation: Int = 0) {
public var line: UInt
public var column: UInt

public init(string: String, offset: UInt64, line: UInt, column: UInt) {
self.string = string
self.offset = offset
self.indentation = indentation
self.line = line
self.column = column
}

public var head: Character? {
guard string.characters.indices.contains(Int(offset)) else { return nil }
return string.characters[Int(offset)]
}

public var next: State {
advanced(by: 1)
}

public func advanced(by count: Int) -> State {
State(string: string, offset: offset + UInt64(count), indentation: indentation)
var newLine = line
var newColumn = column
var newOffset = offset

for _ in 0..<count {
if let character = head {
if character == "\n" {
newLine += 1
newColumn = 1
} else {
newColumn += 1
}
newOffset += 1
} else {
break
}
}

return State(string: string, offset: newOffset, line: newLine, column: newColumn)
}
public func indent(by count: Int) -> State {
State(string: string, offset: offset, indentation: indentation + count)

public var positionMetadata: PositionMetadata {
PositionMetadata(offset: offset, line: line, column: column)
}
}

extension State: ExpressibleByArrayLiteral {
public init(arrayLiteral elements: Character...) {
self = State(string: String(elements), offset: 0)
self = State(string: String(elements), offset: 0, line: 1, column: 1)
}
}

public struct PositionMetadata: Equatable {
public let offset: UInt64
public let line: UInt
public let column: UInt

public init(offset: UInt64, line: UInt, column: UInt) {
self.offset = offset
self.line = line
self.column = column
}
}
3 changes: 2 additions & 1 deletion Sources/StringDecoder/StringDecoder.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
@_exported import Coder
@_exported import Binary

public struct StringDecoder<Element, Failure: Error> {
public typealias Input = State
Expand All @@ -19,7 +20,7 @@ public struct StringDecoder<Element, Failure: Error> {

public extension StringDecoder {
func callAsFunction(_ string: String) -> Output {
decode(State(string: string, offset: 0))
decode(State(string: string, offset: 0, line: 1, column: 1))
}
}

Expand Down
53 changes: 0 additions & 53 deletions Tests/StringDecoderTests/IndentTests.swift

This file was deleted.

Loading

0 comments on commit d491d1d

Please sign in to comment.