on master help sign in
Nock implementation in Swift.
2c6fd0bygolohcysp
docs/nock/implementations/hoon.md+1−1
@@ -1,7 +1,7 @@
1---
1---
2navhome: /docs
2navhome: /docs
3title: Hoon
3title: Hoon
4−sort: 10
4+sort: 11
5---
5---
6
6
7# Hoon
7# Hoon
docs/nock/implementations/swift.mdnew file+366
@@ -0,0 +1,366 @@
1+---
2+navhome: /docs
3+title: Swift
4+sort: 10
5+next: true
6+---
7+
8+# Swift
9+
10+```swift
11+import Foundation
12+// 1 :: A noun is an atom or a cell.
13+// 2 :: An atom is a natural number.
14+// 3 :: A cell is an ordered pair of nouns.
15+// 4
16+// 5 :: nock(a) *a
17+// 6 :: [a b c] [a [b c]]
18+// 7
19+// 8 :: ?[a b] 0
20+// 9 :: ?a 1
21+// 10 :: +[a b] +[a b]
22+// 11 :: +a 1 + a
23+// 12 :: =[a a] 0
24+// 13 :: =[a b] 1
25+// 14 :: =a =a
26+// 15
27+// 16 :: /[1 a] a
28+// 17 :: /[2 a b] a
29+// 18 :: /[3 a b] b
30+// 19 :: /[(a + a) b] /[2 /[a b]]
31+// 20 :: /[(a + a + 1) b] /[3 /[a b]]
32+// 21 :: /a /a
33+// 22
34+// 23 :: *[a [b c] d] [*[a b c] *[a d]]
35+// 24
36+// 25 :: *[a 0 b] /[b a]
37+// 26 :: *[a 1 b] b
38+// 27 :: *[a 2 b c] *[*[a b] *[a c]]
39+// 28 :: *[a 3 b] ?*[a b]
40+// 29 :: *[a 4 b] +*[a b]
41+// 30 :: *[a 5 b] =*[a b]
42+// 31
43+// 32 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
44+// 33 :: *[a 7 b c] *[a 2 b 1 c]
45+// 34 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
46+// 35 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
47+// 36 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
48+// 37 :: *[a 10 b c] *[a c]
49+// 38
50+// 39 :: *a *a
51+
52+// 1 :: A noun is an atom or a cell.
53+public indirect enum Noun: IntegerLiteralConvertible, ArrayLiteralConvertible, Equatable, Hashable, CustomStringConvertible
54+{
55+ // 2 :: An atom is a natural number.
56+ public typealias ATOM = UIntMax
57+
58+ case Atom(ATOM)
59+ // 3 :: A cell is an ordered pair of nouns.
60+ case Cell(Noun, Noun)
61+ case Invalid
62+
63+ public static var YES: Noun { return .Atom(0) }
64+ public static var NO: Noun { return .Atom(1) }
65+
66+ public init(_ noun: Noun) { self = noun }
67+
68+ // 6 :: [a b c] [a [b c]]
69+ public init(_ nouns: [Noun]) {
70+ self = .Invalid
71+ if nouns.count > 0 {
72+ var reverse = nouns.reverse().generate()
73+ self = reverse.next()!
74+ while let n = reverse.next() {
75+ self = .Cell(n, self)
76+ }
77+ }
78+ }
79+
80+ // protocol IntegerLiteralConvertible
81+ public typealias IntegerLiteralType = ATOM
82+ public init(integerLiteral value: IntegerLiteralType) {
83+ self = .Atom(value)
84+ }
85+
86+ // protocol ArrayLiteralConvertible
87+ public typealias Element = Noun
88+ public init(arrayLiteral elements: Element...) {
89+ self = Noun(elements)
90+ }
91+
92+ // Array subscript
93+ public subscript(axis: ATOM) -> Noun {
94+ return fas(.Cell(.Atom(axis), self))
95+ }
96+
97+ // protocol Hashable
98+ public var hashValue: Int {
99+ //return self.description.hashValue
100+ switch self {
101+ case let .Atom(a):
102+ return a.hashValue
103+ case let .Cell(a, b):
104+ return (5381 + 31 &* a.hashValue) &+ b.hashValue
105+ default:
106+ abort()
107+ }
108+ }
109+
110+ // protocol CustomStringConvertible
111+ public var description: String {
112+ return describe()
113+ }
114+
115+ private func describe(depth: Int = 0) -> String {
116+ var sub = ""
117+ let next = depth+1
118+ switch self {
119+ case .Invalid:
120+ return "[%INVALID%]"
121+ case let .Atom(atom):
122+ return "\(atom)"
123+ case let .Cell(.Cell(a, b), c):
124+ sub = "[\(a.describe(next)) \(b.describe(next))] \(c.describe(next))"
125+ case let .Cell(a, b):
126+ sub = "\(a.describe(next)) \(b.describe(next))"
127+ }
128+ return depth == 0 ? "[\(sub)]" : sub
129+ }
130+}
131+
132+// protocol Equatable
133+public func == (left: Noun, right: Noun) -> Bool
134+{
135+ switch (left, right) {
136+ case let (.Atom(lhs), .Atom(rhs)): return lhs == rhs
137+ case let (.Cell(lp, lq), .Cell(rp, rq)): return lp == rp && lq == rq
138+ case (.Invalid, .Invalid): return true
139+ default: return false
140+ }
141+}
142+
143+public func wut(noun: Noun) -> Noun
144+{
145+ switch noun {
146+ // 8 :: ?[a b] 0
147+ case .Cell:
148+ return Noun.YES
149+ case .Atom:
150+ // 9 :: ?a 1
151+ return Noun.NO
152+ default:
153+ //return wut(noun)
154+ abort()
155+ }
156+}
157+
158+public func lus(noun: Noun) -> Noun
159+{
160+ if case let .Atom(a) = noun {
161+ // 11 :: +a 1 + a
162+ return .Atom(1+a)
163+ }
164+ // 10 :: +[a b] +[a b]
165+ //return lus(noun)
166+ abort()
167+}
168+
169+public func tis(noun: Noun) -> Noun
170+{
171+ if case let .Cell(a, b) = noun {
172+ // 12 :: =[a a] 0
173+ // 13 :: =[a b] 1
174+ return (a == b) ? Noun.YES : Noun.NO
175+ }
176+ // 14 :: =a =a
177+ //return tis(noun)
178+ abort()
179+}
180+
181+public func fas(noun: Noun) -> Noun
182+{
183+ switch noun {
184+ // 16 :: /[1 a] a
185+ case let .Cell(1, a):
186+ return a
187+ // 17 :: /[2 a b] a
188+ case let .Cell(2, .Cell(a, _)):
189+ return a
190+ // 18 :: /[3 a b] b
191+ case let .Cell(3, .Cell(_, b)):
192+ return b
193+ // 19 :: /[(a + a) b] /[2 /[a b]]
194+ // 20 :: /[(a + a + 1) b] /[3 /[a b]]
195+ case let .Cell(.Atom(axis), tree):
196+ let inner = Noun.Atom(axis / 2)
197+ let outer = Noun.Atom(2 + (axis % 2))
198+ return fas(.Cell(outer, fas(.Cell(inner, tree))))
199+ default:
200+ // 21 :: /a /a
201+ //return fas(noun)
202+ abort()
203+ }
204+}
205+
206+public func tar(noun: Noun) -> Noun
207+{
208+ switch noun {
209+ case let .Cell(a, formula):
210+ switch formula {
211+ // 23 :: *[a [b c] d] [*[a b c] *[a d]]
212+ case let .Cell(.Cell(b, c), d):
213+ return .Cell(tar([a, b, c]), tar([a, d]))
214+
215+ // 25 :: *[a 0 b] /[b a]
216+ case let .Cell(0, b):
217+ return fas([b, a])
218+
219+ // 26 :: *[a 1 b] b
220+ case let .Cell(1, b):
221+ return b
222+
223+ // 27 :: *[a 2 b c] *[*[a b] *[a c]]
224+ case let .Cell(2, .Cell(b, c)):
225+ return tar([tar([a, b]), tar([a, c])])
226+
227+ // 28 :: *[a 3 b] ?*[a b]
228+ case let .Cell(3, b):
229+ return wut(tar([a, b]))
230+
231+ // 29 :: *[a 4 b] +*[a b]
232+ case let .Cell(4, b):
233+ return lus(tar([a, b]))
234+
235+ // 30 :: *[a 5 b] =*[a b]
236+ case let .Cell(5, b):
237+ return tis(tar([a, b]))
238+
239+ // 32 :: *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
240+ case let .Cell(6, .Cell(b, .Cell(c, d))):
241+ return tar([a, 2, [0, 1], 2, [1, c, d], [1, 0], 2, [1, 2, 3], [1, 0], 4, 4, b])
242+
243+ // 33 :: *[a 7 b c] *[a 2 b 1 c]
244+ case let .Cell(7, .Cell(b, c)):
245+ return tar([a, 2, b, 1, c])
246+
247+ // 34 :: *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
248+ case let .Cell(8, .Cell(b, c)):
249+ return tar([a, 7, [[7, [0, 1], b], 0, 1], c])
250+
251+ // 35 :: *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
252+ case let .Cell(9, .Cell(b, c)):
253+ return tar([a, 7, c, 2, [0, 1], 0, b])
254+
255+ // 36 :: *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
256+ case let .Cell(10, .Cell(.Cell(_, c), d)):
257+ return tar([a, 8, c, 7, [0, 3], d])
258+
259+ // 37 :: *[a 10 b c] *[a c]
260+ case let .Cell(10, .Cell(_, c)):
261+ return tar([a, c]);
262+
263+ default:
264+ //return tar(noun)
265+ abort()
266+ }
267+ default:
268+ //return tar(noun)
269+ abort()
270+ }
271+}
272+
273+
274+public var nock_functions = Dictionary<Noun, Noun -> Noun>()
275+
276+public func dao(formula: Noun) -> Noun->Noun
277+{
278+ if let cached = nock_functions[formula] {
279+ return cached
280+ }
281+
282+ let compiler = { () -> Noun -> Noun in
283+ switch formula {
284+ case let .Cell(.Cell(b, c), d): // Distribution
285+ let (p, q) = (dao(.Cell(b, c)), dao(d))
286+ return { a in .Cell(p(a), q(a)) }
287+
288+ case let .Cell(0, b): // Axis
289+ return { a in fas(.Cell(b, a)) }
290+
291+ case let .Cell(1, b): // Just
292+ return { _ in b }
293+
294+ case let .Cell(2, .Cell(b, c)): // Fire
295+ let (f, g) = (dao(b), dao(c))
296+ return { a in dao(g(a))(f(a)) }
297+
298+ case let .Cell(3, b): // Depth
299+ let f = dao(b)
300+ return { a in wut(f(a)) }
301+
302+ case let .Cell(4, b): // Bump
303+ let f = dao(b)
304+ return { a in lus(f(a)) }
305+
306+ case let .Cell(5, b): // Same
307+ let f = dao(b)
308+ return { a in tis(f(a)) }
309+
310+ case let .Cell(6, .Cell(b, .Cell(c, d))): // If
311+ let (p, q, r) = (dao(b), dao(c), dao(d))
312+ return { a in
313+ switch p(a) {
314+ case Noun.self.YES:
315+ return q(a)
316+ case Noun.self.NO:
317+ return r(a)
318+ default:
319+ return tar(.Cell(a, formula))
320+ }
321+ }
322+
323+ case let .Cell(7, .Cell(b, c)): // Compose
324+ let (f, g) = (dao(b), dao(c))
325+ return { a in g(f(a)) }
326+
327+ case let .Cell(8, .Cell(b, c)): // Push
328+ let (f, g) = (dao(b), dao(c))
329+ return { a in g(.Cell(f(a), a)) }
330+
331+ case let .Cell(9, .Cell(b, c)): // Call
332+ let f = dao(c)
333+ return { a in
334+ let core = f(a)
335+ let arm = dao(fas(.Cell(b, core)))
336+ return arm(core)
337+ }
338+
339+ case let .Cell(10, .Cell(.Cell(_, c), d)): // Hint
340+ let ignore = dao(c)
341+ let f = dao(d)
342+ return { a in ignore(a); return f(a) }
343+
344+ case let .Cell(10, .Cell(_, c)): // Hint
345+ let f = dao(c)
346+ return { a in f(a) }
347+
348+ default:
349+ return { a in tar(.Cell(a, formula)) }
350+ }
351+ }
352+
353+ let r = compiler()
354+ nock_functions[formula] = r
355+ return r
356+}
357+
358+public func nock(n: Noun) -> Noun
359+{
360+ if case let .Cell(a, b) = n {
361+ let f = dao(b)
362+ return f(a)
363+ }
364+ return nock(n)
365+}
366+```