From 278bba4f829bb174b51fb38586c862101c9ddef6 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Sep 2015 17:00:26 -0400 Subject: [PATCH] Add an algebraic Hash type. --- prototype/Doubt.xcodeproj/project.pbxproj | 4 +++ prototype/Doubt/Hash.swift | 41 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 prototype/Doubt/Hash.swift diff --git a/prototype/Doubt.xcodeproj/project.pbxproj b/prototype/Doubt.xcodeproj/project.pbxproj index 314c4060a..09e3336b6 100644 --- a/prototype/Doubt.xcodeproj/project.pbxproj +++ b/prototype/Doubt.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ D4C2B1421BB3474C0096F92A /* SwiftXPC.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4413FD61BB0531E00E3C3C1 /* SwiftXPC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D4C2B1431BB3474C0096F92A /* SourceKittenFramework.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4413FD41BB052ED00E3C3C1 /* SourceKittenFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D4C2B1441BB347500096F92A /* Doubt.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4AAE4FD1B5AE22E004E581F /* Doubt.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D4D7F3171BBB22E500AAB0C0 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4D7F3161BBB22E500AAB0C0 /* Hash.swift */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -109,6 +110,7 @@ D4AAE53E1B5AE2D0004E581F /* StringLiteralConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringLiteralConvertible.swift; sourceTree = ""; }; D4AAE53F1B5AE2D0004E581F /* Syntax.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Syntax.swift; sourceTree = ""; }; D4AAE54B1B5AE42D004E581F /* Equatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Equatable.swift; sourceTree = ""; }; + D4D7F3161BBB22E500AAB0C0 /* Hash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hash.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -196,6 +198,7 @@ D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */, D4413FF01BB08FDC00E3C3C1 /* JSON.swift */, D4A71DC41BB45B850051416D /* Vertex.swift */, + D4D7F3161BBB22E500AAB0C0 /* Hash.swift */, D4AAE5001B5AE22E004E581F /* Supporting Files */, ); path = Doubt; @@ -375,6 +378,7 @@ D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */, D4AAE5481B5AE2D0004E581F /* String.swift in Sources */, D4AAE5411B5AE2D0004E581F /* Diff.swift in Sources */, + D4D7F3171BBB22E500AAB0C0 /* Hash.swift in Sources */, D4AAE5401B5AE2D0004E581F /* Array.swift in Sources */, D4AAE54C1B5AE42D004E581F /* Equatable.swift in Sources */, D4A71DC51BB45B850051416D /* Vertex.swift in Sources */, diff --git a/prototype/Doubt/Hash.swift b/prototype/Doubt/Hash.swift new file mode 100644 index 000000000..38a2deb2c --- /dev/null +++ b/prototype/Doubt/Hash.swift @@ -0,0 +1,41 @@ +public enum Hash: Hashable { + case Sequence([Hash]) + case String(Swift.String) + case Int(Swift.Int) + + + public var hashValue: Swift.Int { + switch self { + case let .Sequence(s): + // Bob Jenkins’ one-at-a-time hash: https://en.wikipedia.org/wiki/Jenkins_hash_function + var hash = 0 + for each in s { + hash += each.hashValue + hash += hash << 10 + hash ^= hash >> 6 + } + hash += hash << 3 + hash ^= hash >> 11 + hash += hash << 15 + return hash + case let .String(s): + return s.hashValue + case let .Int(i): + return i.hashValue + } + } +} + +public func == (left: Hash, right: Hash) -> Bool { + switch (left, right) { + case let (.Sequence(a), .Sequence(b)): + return a == b + case let (.String(a), .String(b)): + return a == b + case let (.Int(a), .Int(b)): + return a == b + default: + return false + } +} +