@@ -0,0 +1,366 @@
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.
17+// 6 :: [a b c] [a [b c]]
21+// 10 :: +[a b] +[a b]
30+// 19 :: /[(a + a) b] /[2 /[a b]]
31+// 20 :: /[(a + a + 1) b] /[3 /[a b]]
34+// 23 :: *[a [b c] d] [*[a b c] *[a d]]
36+// 25 :: *[a 0 b] /[b a]
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]
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]
52+// 1 :: A noun is an atom or a cell.
53+public indirect enum Noun: IntegerLiteralConvertible, ArrayLiteralConvertible, Equatable, Hashable, CustomStringConvertible
55+ // 2 :: An atom is a natural number.
56+ public typealias ATOM = UIntMax
59+ // 3 :: A cell is an ordered pair of nouns.
60+ case Cell(Noun, Noun)
63+ public static var YES: Noun { return .Atom(0) }
64+ public static var NO: Noun { return .Atom(1) }
66+ public init(_ noun: Noun) { self = noun }
68+ // 6 :: [a b c] [a [b c]]
69+ public init(_ nouns: [Noun]) {
72+ var reverse = nouns.reverse().generate()
73+ self = reverse.next()!
74+ while let n = reverse.next() {
75+ self = .Cell(n, self)
80+ // protocol IntegerLiteralConvertible
81+ public typealias IntegerLiteralType = ATOM
82+ public init(integerLiteral value: IntegerLiteralType) {
86+ // protocol ArrayLiteralConvertible
87+ public typealias Element = Noun
88+ public init(arrayLiteral elements: Element...) {
89+ self = Noun(elements)
93+ public subscript(axis: ATOM) -> Noun {
94+ return fas(.Cell(.Atom(axis), self))
98+ public var hashValue: Int {
99+ //return self.description.hashValue
103+ case let .Cell(a, b):
104+ return (5381 + 31 &* a.hashValue) &+ b.hashValue
110+ // protocol CustomStringConvertible
111+ public var description: String {
115+ private func describe(depth: Int = 0) -> String {
120+ return "[%INVALID%]"
121+ case let .Atom(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))"
128+ return depth == 0 ? "[\(sub)]" : sub
132+// protocol Equatable
133+public func == (left: Noun, right: Noun) -> Bool
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
143+public func wut(noun: Noun) -> Noun
158+public func lus(noun: Noun) -> Noun
160+ if case let .Atom(a) = noun {
164+ // 10 :: +[a b] +[a b]
169+public func tis(noun: Noun) -> Noun
171+ if case let .Cell(a, b) = noun {
174+ return (a == b) ? Noun.YES : Noun.NO
181+public func fas(noun: Noun) -> Noun
185+ case let .Cell(1, a):
188+ case let .Cell(2, .Cell(a, _)):
191+ case let .Cell(3, .Cell(_, 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))))
206+public func tar(noun: Noun) -> Noun
209+ case let .Cell(a, 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]))
215+ // 25 :: *[a 0 b] /[b a]
216+ case let .Cell(0, b):
220+ case let .Cell(1, b):
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])])
227+ // 28 :: *[a 3 b] ?*[a b]
228+ case let .Cell(3, b):
229+ return wut(tar([a, b]))
231+ // 29 :: *[a 4 b] +*[a b]
232+ case let .Cell(4, b):
233+ return lus(tar([a, b]))
235+ // 30 :: *[a 5 b] =*[a b]
236+ case let .Cell(5, b):
237+ return tis(tar([a, b]))
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])
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])
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])
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])
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])
259+ // 37 :: *[a 10 b c] *[a c]
260+ case let .Cell(10, .Cell(_, c)):
274+public var nock_functions = Dictionary<Noun, Noun -> Noun>()
276+public func dao(formula: Noun) -> Noun->Noun
278+ if let cached = nock_functions[formula] {
282+ let compiler = { () -> Noun -> Noun in
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)) }
288+ case let .Cell(0, b): // Axis
289+ return { a in fas(.Cell(b, a)) }
291+ case let .Cell(1, b): // Just
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)) }
298+ case let .Cell(3, b): // Depth
300+ return { a in wut(f(a)) }
302+ case let .Cell(4, b): // Bump
304+ return { a in lus(f(a)) }
306+ case let .Cell(5, b): // Same
308+ return { a in tis(f(a)) }
310+ case let .Cell(6, .Cell(b, .Cell(c, d))): // If
311+ let (p, q, r) = (dao(b), dao(c), dao(d))
319+ return tar(.Cell(a, formula))
323+ case let .Cell(7, .Cell(b, c)): // Compose
324+ let (f, g) = (dao(b), dao(c))
325+ return { a in g(f(a)) }
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)) }
331+ case let .Cell(9, .Cell(b, c)): // Call
335+ let arm = dao(fas(.Cell(b, core)))
339+ case let .Cell(10, .Cell(.Cell(_, c), d)): // Hint
342+ return { a in ignore(a); return f(a) }
344+ case let .Cell(10, .Cell(_, c)): // Hint
346+ return { a in f(a) }
349+ return { a in tar(.Cell(a, formula)) }
354+ nock_functions[formula] = r
358+public func nock(n: Noun) -> Noun
360+ if case let .Cell(a, b) = n {