@@ -1,31 +1,15 @@
1{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
1{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
3−module Nock (tar, cell, atom, Annotation (..), Noun, RawNoun (..)) where
3+module Nock (tar, hax, fas, cell, atom, Annotation (..), Noun) where
5−import Data.Hashable
5+import Data.Bits
6−import GHC.Generics (Generic)
6+import Data.Functor ((<&>))
7−import Numeric.Natural
7+import Effectful
8−import Test.QuickCheck.Arbitrary.Generic
8+import Effectful.State.Static.Local qualified as SEL
10−data Annotation = Annotation
10+import GHC.Num
11− { hash :: Int
11+import GHC.Num.BigNat (bigNatAddWord#, bigNatFromWord2#)
12− }
12+import Nock.Types
13− deriving stock (Show)
18−atom :: Natural -> Noun
19−atom nat = Atom nat Annotation {hash = hash nat}
21−cell :: Noun -> Noun -> Noun
27− { hash = hash ((annotation lhs).hash, (annotation rhs).hash)
30sig :: Noun
14sig :: Noun
31sig = atom 0
15sig = atom 0
@@ -33,83 +17,119 @@ sig = atom 0
33one :: Noun
17one :: Noun
34one = atom 1
18one = atom 1
36−annotation :: RawNoun ann -> ann
20+two :: Noun
37−annotation (Atom _ ann) = ann
21+two = atom 2
38−annotation (Cell _ _ ann) = ann
40−data RawNoun ann
23+three :: Noun
41− = Atom !Natural ann
24+three = atom 3
42− | Cell (RawNoun ann) (RawNoun ann) ann
43− deriving stock (Generic, Show)
45−instance Eq (RawNoun ann) where
26+four :: Noun
46− (Atom lhs _) == (Atom rhs _) = lhs == rhs
27+four = atom 4
47− (Cell lhslhs lhsrhs _) == (Cell rhslhs rhsrhs _) = lhslhs == rhslhs && lhsrhs == rhsrhs
50−hashEq :: Noun -> Noun -> Bool
29+twoThree :: Noun
51−hashEq (Atom lhsNat lhsAnn) (Atom rhsNat rhsAnn) =
30+twoThree = cell two three
52− lhsAnn.hash == rhsAnn.hash && lhsNat == rhsNat
53−hashEq (Cell lhslhs lhsrhs lhsAnn) (Cell rhslhs rhsrhs rhsAnn) =
54− lhsAnn.hash == rhsAnn.hash && hashEq lhslhs rhslhs && hashEq lhsrhs rhsrhs
57−type Noun = RawNoun Annotation
32+sigOne :: Noun
59wut :: Noun -> Noun
35wut :: Noun -> Noun
60wut Cell {} = sig
36wut Cell {} = sig
61wut Atom {} = one
37wut Atom {} = one
63lus :: Noun -> Noun
39lus :: Noun -> Noun
64−lus ~(Atom nat _) = atom (nat + 1)
40+lus ~(Atom nat _) = atom $ case nat of
41+ (NS n) -> case addWordC# n 1## of
43+ (# l, c #) -> NB (bigNatFromWord2# (int2Word# c) l)
44+ (NB n) -> NB (bigNatAddWord# n 1##)
66−tis :: Noun -> Noun
46+tis :: Noun -> Noun -> Eff es Noun
67−tis ~(Cell lhs rhs _) = if hashEq lhs rhs then sig else one
47+tis lhs rhs = pure $ if lhs == rhs then sig else one
69−fas :: Noun -> Noun
49+fas# :: Word# -> Noun -> Noun
70−fas ~(Cell ~(Atom lhs _) rhs _) =
50+fas# lhs rhs =
71 case lhs of
51 case lhs of
72− 1 -> rhs
52+ 1## -> rhs
73− 2 -> case rhs of
53+ 2## -> case rhs of
74 ~(Cell lhs' _ _) -> lhs'
54 ~(Cell lhs' _ _) -> lhs'
75− 3 -> case rhs of
55+ 3## -> case rhs of
76 ~(Cell _ rhs' _) -> rhs'
56 ~(Cell _ rhs' _) -> rhs'
78− | n > 0 ->
58+ let rest = fas# (uncheckedShiftRL# n 1#) rhs
79− let (d, m) = divMod n 2
59+ in case and# 1## n of
63+fas :: Natural -> Noun -> Noun
64+fas (NS w) rhs = fas# w rhs
66+ let rest = fas (unsafeShiftR n 1) rhs
71+hax# :: Word# -> Noun -> Noun -> Noun
74+ let a = uncheckedShiftRL# n 1#
75+ in case and# n 1## of
76+ 1## -> hax# a (cell (fas# (n `xor#` 1##) c) b) c
77+ _ -> hax# a (cell b (fas# (n `or#` 1##) c)) c
79+hax :: Natural -> Noun -> Noun -> Noun
80+hax (NS n) b c = hax# n b c
82+ let a = unsafeShiftR n 1
80− in if m == 0
83+ in if testBit n 0
81− then fas (cell (atom 2) (fas (cell (atom d) rhs)))
84+ then hax a (cell (fas (n - 1) c) b) c
82− else fas (cell (atom 3) (fas (cell (atom d) rhs)))
85+ else hax a (cell b (fas (n + 1) c)) c
87+tar :: Noun -> Eff es Noun
88+tar ~(Cell subject ~(Cell a b _) _) = tar' a b subject
90+tar' :: Noun -> Noun -> Noun -> Eff es Noun
91+tar' b c subject = case b of
92+ Cell x y _ -> case c of
93+ ~(Cell l k _) -> cell <$> tar' x y subject <*> tar' l k subject
83− _ -> undefined
94+ Atom (NB _) _ -> undefined
86−hax ~(Cell ~(Atom n _) ~(Cell a b _) _) =
87− let (d, m) = divMod n 2
88− in case n of
95+ Atom (NS n) _ -> case n of
89− 1 -> a
96+ 0## -> case c of
90− _ | m == 0 -> hax (cell (atom d) (cell (cell a (fas (cell (atom $ n + 1) b))) b))
97+ ~(Atom nat _) -> pure $ fas nat subject
91− _ -> hax (cell (atom d) (cell (cell (fas (cell (atom $ n + n) b)) a) b))
98+ 1## -> pure c
93−tar :: Noun -> Noun
100+ ~(Cell l k _) -> wut <$> tar' l k subject
94−tar ~(Cell a ~(Cell b c _) _) = case b of
101+ 4## -> case c of
95− Cell x y _ -> cell (tar (cell a (cell x y))) (tar (cell a c))
102+ ~(Cell l k _) -> lus <$> tar' l k subject
96− Atom n _ -> case n of
99− 3 -> wut $ tar $ cell a c
100− 4 -> lus $ tar $ cell a c
101 _ -> case c of
103 _ -> case c of
102− ~(Cell x y _) -> case n of
104+ ~(Cell x ~(Cell h j _) _) -> case n of
103− 2 -> tar $ cell (tar $ cell a x) (tar $ cell a y)
105+ 2## -> case x of
104− 5 -> tis $ cell (tar $ cell a x) (tar $ cell a y)
106+ ~(Cell l k _) ->
105− 7 -> tar $ cell (tar $ cell a x) y
107+ tar' l k subject >>= \case
106− 8 -> tar $ cell (cell (tar $ cell a x) a) y
108+ ~formula@(Cell battery ~(Cell sample _ _) _) ->
107− 9 -> tar $ cell (tar $ cell a y) $ cell (atom 2) (cell (cell sig one) (cell sig x))
109+ -- if traceShowId battery == Nock.Jets.add
108− 6 -> case y of
110+ -- then error "Found it!"
109− ~(Cell l k _) -> tar $ cell a $ tar $ cell (cell l k) $ cell sig $ tar $ cell (cell (atom 2) (atom 3)) $ cell sig $ tar $ cell a (cell (atom 4) (cell (atom 4) x))
111+ tar' h j subject >>= \case
112+ ~(Cell u v _) -> tar' u v formula
115+ p <- tar' h j subject
116+ q <- tar' l k subject
119+ ~(Cell l k _) -> tar' l k subject >>= tar' h j
122+ p <- tar' l k subject
123+ tar' h j (cell p subject)
124+ 9## -> tar' h j subject >>= tar' two (cell sigOne (cell sig x))
126+ p <- tar' four (cell four x) subject
127+ q <- tar' sig p twoThree
128+ tar' sig q (cell h j) >>= \case
129+ ~(Cell u v _) -> tar' u v subject
110− 10 -> case x of
130+ 10## -> case x of
111− ~(Cell l k _) -> hax $ cell l $ cell (tar (cell a k)) $ tar $ cell a y
131+ ~(Cell ~(Atom b' _) ~(Cell u v _) _) -> hax b' <$> tar' u v subject <*> tar' h j subject
112− 11 -> case c of
132+ 11## -> case x of
113− Cell l k _ -> tar $ cell (cell (tar $ cell a l) (tar $ cell a k)) $ cell sig (atom 3)
133+ Cell _ ~(Cell u v _) _ -> tar' h j subject
114− Atom l _ -> tar $ cell a y
134+ Atom _ _ -> tar' h j subject
115 _ -> undefined
135 _ -> undefined