1
1
mirror of https://github.com/github/semantic.git synced 2024-12-24 23:42:31 +03:00

Add Location.

This commit is contained in:
Rob Rix 2015-11-04 12:11:18 -05:00
parent 574ef530c4
commit 03def65a8e
2 changed files with 146 additions and 0 deletions

View File

@ -38,6 +38,7 @@
D45A36C91BBC667D00BE3DDE /* Categorizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45A36C81BBC667D00BE3DDE /* Categorizable.swift */; };
D46452C71BE7C6C800D7D26E /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46452C61BE7C6C800D7D26E /* Argument.swift */; };
D46452C91BE7EB2500D7D26E /* Unified.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46452C81BE7EB2500D7D26E /* Unified.swift */; };
D46452D81BEA731800D7D26E /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46452D71BEA731800D7D26E /* Location.swift */; };
D49FCBC41BBEF98E00C5E9C3 /* Free.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC31BBEF98E00C5E9C3 /* Free.swift */; };
D49FCBC61BBF214300C5E9C3 /* Patch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC51BBF214300C5E9C3 /* Patch.swift */; };
D49FCBC81BBF2C4300C5E9C3 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */; };
@ -107,6 +108,7 @@
D45A36C81BBC667D00BE3DDE /* Categorizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Categorizable.swift; sourceTree = "<group>"; };
D46452C61BE7C6C800D7D26E /* Argument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Argument.swift; sourceTree = "<group>"; };
D46452C81BE7EB2500D7D26E /* Unified.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unified.swift; sourceTree = "<group>"; };
D46452D71BEA731800D7D26E /* Location.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = "<group>"; };
D49FCBC31BBEF98E00C5E9C3 /* Free.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Free.swift; sourceTree = "<group>"; };
D49FCBC51BBF214300C5E9C3 /* Patch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Patch.swift; sourceTree = "<group>"; };
D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = "<group>"; };
@ -215,6 +217,7 @@
D1A0934A1BD188CA005A6326 /* JSONParser.swift */,
D1A0934C1BD188F5005A6326 /* JSONLeaf.swift */,
D40D72551BCFF360001B7A9E /* Interpreter.swift */,
D46452D71BEA731800D7D26E /* Location.swift */,
D4AAE5001B5AE22E004E581F /* Supporting Files */,
);
path = Doubt;
@ -444,6 +447,7 @@
files = (
D40D72561BCFF360001B7A9E /* Interpreter.swift in Sources */,
D4AAE5471B5AE2D0004E581F /* Optional.swift in Sources */,
D46452D81BEA731800D7D26E /* Location.swift in Sources */,
D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */,
D42F097E1BCEAEDA00B95610 /* Operation.swift in Sources */,
D45A36C91BBC667D00BE3DDE /* Categorizable.swift in Sources */,

View File

@ -0,0 +1,142 @@
public struct Location<A>: SequenceType {
public init(it: A, down: A -> Location?, up: A -> Location?, left: A -> Location?, right: A -> Location?) {
self.it = it
_left = left
_right = right
_up = up
_down = down
}
public let it: A
private let _down: A -> Location?
public var down: Location? {
return _down(it)
}
private let _up: A -> Location?
public var up: Location? {
return _up(it)
}
private let _left: A -> Location?
public var left: Location? {
return _left(it)
}
private let _right: A -> Location?
public var right: Location? {
return _right(it)
}
/// The root Location in the current exploration.
public var root: Location {
return up?.root ?? self
}
/// Returns the logically next `Location` after the receiver in a pre-order depth-first traversal.
public var next: Location? {
return down ?? nextAfter
}
/// Returns the logically next `Location` after the receiver and its children in a pre-order depth-first traversal.
private var nextAfter: Location? {
return right ?? up?.nextAfter
}
/// Return a new Location by replacing the current value with a new one produced by `f`.
public func modify(@noescape f: A -> A) -> Location {
return Location(it: f(it), down: _down, up: _up, left: _left, right: _right)
}
public typealias Weave = A -> Unweave
public typealias Unweave = (A -> Location?) -> Location?
// MARK: - Constructors
public static func nullary(up: A -> Location?) -> Location? {
return nil
}
public static func unary(t1: A, _ weave: Weave, _ reconstruct: A -> A)(_ up: A -> Location?) -> Location? {
return Location(flip(weave), reconstruct >>> up, t1)
}
public static func binary(t1: A, _ t2: A, _ weave: Weave, _ reconstruct: (A, A) -> A)(_ up: A -> Location?) -> Location? {
return Location(flip(weave), reconstruct >>> up, t1, t2)
}
public static func ternary(t1: A, _ t2: A, _ t3: A, _ weave: Weave, _ reconstruct: (A, A, A) -> A)(_ up: A -> Location?) -> Location? {
return Location(flip(weave), reconstruct >>> up, t1, t2, t3)
}
public static func explore(weave: Weave)(_ a : A) -> Location {
return Location(it: a, down: flip(weave)(explore(weave) >>> Optional.Some), up: const(nil), left: const(nil), right: const(nil))
}
// MARK: - Implementation details
private init?(_ weave: (A -> Location?) -> A -> Location?, _ up: A -> Location?, _ a: A) {
func into(t1: A) -> Location? {
return Location(it: t1, down: weave(into), up: up, left: const(nil), right: const(nil))
}
guard let location = into(a) else { return nil }
self = location
}
private init?(_ weave: (A -> Location?) -> A -> Location?, _ up: (A, A) -> Location?, _ t1: A, _ t2: A) {
func into1(t1: A, _ t2: A) -> Location? {
let update: ((A, A) -> Location?) -> A -> Location? = { fl in { t1 in fl(t1, t2) } }
return Location(it: t1, down: weave(update(into1)), up: update(up), left: const(nil), right: update(into2))
}
func into2(t1: A, _ t2: A) -> Location? {
let update: ((A, A) -> Location?) -> A -> Location? = { fl in { t2 in fl(t1, t2) } }
return Location(it: t2, down: weave(update(into2)), up: update(up), left: update(into1), right: const(nil))
}
guard let location = into1(t1, t2) else { return nil }
self = location
}
private init?(_ weave: (A -> Location?) -> A -> Location?, _ up: (A, A, A) -> Location?, _ t1: A, _ t2: A, _ t3: A) {
func into1(t1: A, _ t2: A, _ t3: A) -> Location? {
let update: ((A, A, A) -> Location?) -> A -> Location? = { fl in { t1 in fl(t1, t2, t3) } }
return Location(it: t1, down: weave(update(into1)), up: update(up), left: const(nil), right: update(into2))
}
func into2(t1: A, _ t2: A, _ t3: A) -> Location? {
let update: ((A, A, A) -> Location?) -> A -> Location? = { fl in { t2 in fl(t1, t2, t3) } }
return Location(it: t1, down: weave(update(into2)), up: update(up), left: update(into1), right: update(into3))
}
func into3(t1: A, _ t2: A, _ t3: A) -> Location? {
let update: ((A, A, A) -> Location?) -> A -> Location? = { fl in { t3 in fl(t1, t2, t3) } }
return Location(it: t1, down: weave(update(into3)), up: update(up), left: update(into2), right: const(nil))
}
guard let location = into1(t1, t2, t3) else { return nil }
self = location
}
// MARK: SequenceType
public func generate() -> AnyGenerator<Location> {
var current: Location? = self
return anyGenerator {
let next = current
current = current?.next
return next
}
}
}
// Flipping of curried functions.
private func flip<A, B, C>(f: A -> B -> C)(_ b: B)(_ a: A) -> C {
return f(a)(b)
}
import Prelude