module Unison.Runtime.ANF.POp where

import Data.Map.Strict hiding (map)
import Data.Word

-- Note: Enum/Bounded instances should only be used for things like
-- getting a list of all ops. Using auto-generated numberings for
-- serialization, for instance, could cause observable changes to
-- formats that we want to control and version.
data POp
  = -- Int
    ADDI -- +
  | SUBI -- -
  | MULI
  | DIVI -- /
  | SGNI -- sgn
  | NEGI -- neg
  | MODI -- mod
  | POWI -- pow
  | SHLI -- shiftl
  | SHRI -- shiftr
  | ANDI -- and
  | IORI -- or
  | XORI -- xor
  | COMI -- complement
  | INCI -- inc
  | DECI -- dec
  | LEQI -- <=
  | LESI -- <
  | EQLI -- ==
  | NEQI -- !=
  | TRNC -- truncate0
  -- Nat
  | ADDN -- +
  | SUBN -- -
  | DRPN -- drop
  | MULN
  | DIVN -- /
  | MODN -- mod
  | TZRO -- trailingZeros
  | LZRO -- leadingZeros
  | POPC -- popCount
  | POWN -- pow
  | SHLN -- shiftl
  | SHRN -- shiftr
  | ANDN -- and
  | IORN -- or
  | XORN -- xor
  | COMN -- complement
  | INCN -- inc
  | DECN -- dec
  | LEQN -- <=
  | LESN -- <
  | EQLN -- ==
  | NEQN -- !=
  -- Float
  | ADDF -- +
  | SUBF -- -
  | MULF
  | DIVF -- /
  | MINF -- min
  | MAXF -- max
  | LEQF -- <=
  | LESF -- <
  | EQLF -- ==
  | NEQF -- !=
  | POWF -- pow
  | EXPF -- exp
  | SQRT -- sqrt
  | LOGF -- log
  | LOGB -- logBase
  | ABSF -- abs
  | CEIL -- ceil
  | FLOR -- floor
  | TRNF -- truncate
  | RNDF -- round
  -- Trig
  | COSF -- cos
  | ACOS -- acos
  | COSH -- cosh
  | ACSH -- acosh
  | SINF -- sin
  | ASIN -- asin
  | SINH -- sinh
  | ASNH -- asinh
  | TANF -- tan
  | ATAN -- atan
  | TANH -- tanh
  | ATNH -- atanh
  | ATN2 -- atan2
  -- Text
  | CATT -- ++
  | TAKT -- take
  | DRPT -- drop
  | SIZT -- size
  | IXOT -- indexOf
  | UCNS -- uncons
  | USNC -- unsnoc
  | EQLT -- ==
  | LEQT -- <=
  | PAKT -- pack
  | UPKT -- unpack
  -- Sequence
  | CATS -- ++
  | TAKS -- take
  | DRPS -- drop
  | SIZS -- size
  | CONS -- cons
  | SNOC -- snoc
  | IDXS -- at
  | BLDS -- build
  | VWLS -- viewl
  | VWRS -- viewr
  | SPLL -- splitl
  | SPLR -- splitr
  -- Bytes
  | PAKB -- pack
  | UPKB -- unpack
  | TAKB -- take
  | DRPB -- drop
  | IXOB -- indexOf
  | IDXB -- index
  | SIZB -- size
  | FLTB -- flatten
  | CATB -- append
  -- Conversion
  | ITOF -- intToFloat
  | NTOF -- natToFloat
  | ITOT -- intToText
  | NTOT -- natToText
  | TTOI -- textToInt
  | TTON -- textToNat
  | TTOF -- textToFloat
  | FTOT -- floatToText
  | CAST -- runtime type cast for unboxed values.
  | -- Concurrency
    FORK -- fork
  | -- Universal operations
    EQLU -- ==
  | CMPU -- compare
  | LEQU -- <=
  | LESU -- <
  | EROR -- error
  | -- Code
    MISS -- isMissing
  | CACH -- cache_
  | LKUP -- lookup
  | LOAD -- load
  | CVLD -- validate
  | SDBX -- sandbox
  | VALU -- value
  | TLTT -- Term.Link.toText
  -- Debug
  | PRNT -- print
  | INFO -- info
  | TRCE -- trace
  | DBTX -- debugText
  | -- STM
    ATOM -- atomically
  | TFRC -- try force
  | SDBL -- sandbox link list
  | SDBV -- sandbox check for Values
  -- Refs
  | REFN -- Ref.new
  | REFR -- Ref.read
  | REFW -- Ref.write
  | RCAS -- Ref.cas
  | RRFC -- Ref.readForCas
  | TIKR -- Ref.Ticket.read
  -- Bools
  | NOTB -- not
  | ANDB -- and
  | IORB -- or
  deriving (Int -> POp -> ShowS
[POp] -> ShowS
POp -> String
(Int -> POp -> ShowS)
-> (POp -> String) -> ([POp] -> ShowS) -> Show POp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> POp -> ShowS
showsPrec :: Int -> POp -> ShowS
$cshow :: POp -> String
show :: POp -> String
$cshowList :: [POp] -> ShowS
showList :: [POp] -> ShowS
Show, POp -> POp -> Bool
(POp -> POp -> Bool) -> (POp -> POp -> Bool) -> Eq POp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: POp -> POp -> Bool
== :: POp -> POp -> Bool
$c/= :: POp -> POp -> Bool
/= :: POp -> POp -> Bool
Eq, Eq POp
Eq POp =>
(POp -> POp -> Ordering)
-> (POp -> POp -> Bool)
-> (POp -> POp -> Bool)
-> (POp -> POp -> Bool)
-> (POp -> POp -> Bool)
-> (POp -> POp -> POp)
-> (POp -> POp -> POp)
-> Ord POp
POp -> POp -> Bool
POp -> POp -> Ordering
POp -> POp -> POp
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: POp -> POp -> Ordering
compare :: POp -> POp -> Ordering
$c< :: POp -> POp -> Bool
< :: POp -> POp -> Bool
$c<= :: POp -> POp -> Bool
<= :: POp -> POp -> Bool
$c> :: POp -> POp -> Bool
> :: POp -> POp -> Bool
$c>= :: POp -> POp -> Bool
>= :: POp -> POp -> Bool
$cmax :: POp -> POp -> POp
max :: POp -> POp -> POp
$cmin :: POp -> POp -> POp
min :: POp -> POp -> POp
Ord, Int -> POp
POp -> Int
POp -> [POp]
POp -> POp
POp -> POp -> [POp]
POp -> POp -> POp -> [POp]
(POp -> POp)
-> (POp -> POp)
-> (Int -> POp)
-> (POp -> Int)
-> (POp -> [POp])
-> (POp -> POp -> [POp])
-> (POp -> POp -> [POp])
-> (POp -> POp -> POp -> [POp])
-> Enum POp
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: POp -> POp
succ :: POp -> POp
$cpred :: POp -> POp
pred :: POp -> POp
$ctoEnum :: Int -> POp
toEnum :: Int -> POp
$cfromEnum :: POp -> Int
fromEnum :: POp -> Int
$cenumFrom :: POp -> [POp]
enumFrom :: POp -> [POp]
$cenumFromThen :: POp -> POp -> [POp]
enumFromThen :: POp -> POp -> [POp]
$cenumFromTo :: POp -> POp -> [POp]
enumFromTo :: POp -> POp -> [POp]
$cenumFromThenTo :: POp -> POp -> POp -> [POp]
enumFromThenTo :: POp -> POp -> POp -> [POp]
Enum, POp
POp -> POp -> Bounded POp
forall a. a -> a -> Bounded a
$cminBound :: POp
minBound :: POp
$cmaxBound :: POp
maxBound :: POp
Bounded)

pOpCode :: POp -> Word16
pOpCode :: POp -> Word16
pOpCode POp
op = case POp
op of
  POp
ADDI -> Word16
0
  POp
SUBI -> Word16
1
  POp
MULI -> Word16
2
  POp
DIVI -> Word16
3
  POp
SGNI -> Word16
4
  POp
NEGI -> Word16
5
  POp
MODI -> Word16
6
  POp
POWI -> Word16
7
  POp
SHLI -> Word16
8
  POp
SHRI -> Word16
9
  POp
INCI -> Word16
10
  POp
DECI -> Word16
11
  POp
LEQI -> Word16
12
  POp
EQLI -> Word16
13
  POp
ADDN -> Word16
14
  POp
SUBN -> Word16
15
  POp
MULN -> Word16
16
  POp
DIVN -> Word16
17
  POp
MODN -> Word16
18
  POp
TZRO -> Word16
19
  POp
LZRO -> Word16
20
  POp
POWN -> Word16
21
  POp
SHLN -> Word16
22
  POp
SHRN -> Word16
23
  POp
ANDN -> Word16
24
  POp
IORN -> Word16
25
  POp
XORN -> Word16
26
  POp
COMN -> Word16
27
  POp
INCN -> Word16
28
  POp
DECN -> Word16
29
  POp
LEQN -> Word16
30
  POp
EQLN -> Word16
31
  POp
ADDF -> Word16
32
  POp
SUBF -> Word16
33
  POp
MULF -> Word16
34
  POp
DIVF -> Word16
35
  POp
MINF -> Word16
36
  POp
MAXF -> Word16
37
  POp
LEQF -> Word16
38
  POp
EQLF -> Word16
39
  POp
POWF -> Word16
40
  POp
EXPF -> Word16
41
  POp
SQRT -> Word16
42
  POp
LOGF -> Word16
43
  POp
LOGB -> Word16
44
  POp
ABSF -> Word16
45
  POp
CEIL -> Word16
46
  POp
FLOR -> Word16
47
  POp
TRNF -> Word16
48
  POp
RNDF -> Word16
49
  POp
COSF -> Word16
50
  POp
ACOS -> Word16
51
  POp
COSH -> Word16
52
  POp
ACSH -> Word16
53
  POp
SINF -> Word16
54
  POp
ASIN -> Word16
55
  POp
SINH -> Word16
56
  POp
ASNH -> Word16
57
  POp
TANF -> Word16
58
  POp
ATAN -> Word16
59
  POp
TANH -> Word16
60
  POp
ATNH -> Word16
61
  POp
ATN2 -> Word16
62
  POp
CATT -> Word16
63
  POp
TAKT -> Word16
64
  POp
DRPT -> Word16
65
  POp
SIZT -> Word16
66
  POp
UCNS -> Word16
67
  POp
USNC -> Word16
68
  POp
EQLT -> Word16
69
  POp
LEQT -> Word16
70
  POp
PAKT -> Word16
71
  POp
UPKT -> Word16
72
  POp
CATS -> Word16
73
  POp
TAKS -> Word16
74
  POp
DRPS -> Word16
75
  POp
SIZS -> Word16
76
  POp
CONS -> Word16
77
  POp
SNOC -> Word16
78
  POp
IDXS -> Word16
79
  POp
BLDS -> Word16
80
  POp
VWLS -> Word16
81
  POp
VWRS -> Word16
82
  POp
SPLL -> Word16
83
  POp
SPLR -> Word16
84
  POp
PAKB -> Word16
85
  POp
UPKB -> Word16
86
  POp
TAKB -> Word16
87
  POp
DRPB -> Word16
88
  POp
IDXB -> Word16
89
  POp
SIZB -> Word16
90
  POp
FLTB -> Word16
91
  POp
CATB -> Word16
92
  POp
ITOF -> Word16
93
  POp
NTOF -> Word16
94
  POp
ITOT -> Word16
95
  POp
NTOT -> Word16
96
  POp
TTOI -> Word16
97
  POp
TTON -> Word16
98
  POp
TTOF -> Word16
99
  POp
FTOT -> Word16
100
  POp
FORK -> Word16
101
  POp
EQLU -> Word16
102
  POp
CMPU -> Word16
103
  POp
EROR -> Word16
104
  POp
PRNT -> Word16
105
  POp
INFO -> Word16
106
  POp
POPC -> Word16
107
  POp
MISS -> Word16
108
  POp
CACH -> Word16
109
  POp
LKUP -> Word16
110
  POp
LOAD -> Word16
111
  POp
CVLD -> Word16
112
  POp
SDBX -> Word16
113
  POp
VALU -> Word16
114
  POp
TLTT -> Word16
115
  POp
TRCE -> Word16
116
  POp
ATOM -> Word16
117
  POp
TFRC -> Word16
118
  POp
DBTX -> Word16
119
  POp
IXOT -> Word16
120
  POp
IXOB -> Word16
121
  POp
SDBL -> Word16
122
  POp
SDBV -> Word16
123
  POp
CAST -> Word16
124
  POp
ANDI -> Word16
125
  POp
IORI -> Word16
126
  POp
XORI -> Word16
127
  POp
COMI -> Word16
128
  POp
DRPN -> Word16
129
  POp
TRNC -> Word16
130
  POp
REFN -> Word16
131
  POp
REFR -> Word16
132
  POp
REFW -> Word16
133
  POp
RCAS -> Word16
134
  POp
RRFC -> Word16
135
  POp
TIKR -> Word16
136
  POp
LESI -> Word16
137
  POp
NEQI -> Word16
138
  POp
LESN -> Word16
139
  POp
NEQN -> Word16
140
  POp
LESF -> Word16
141
  POp
NEQF -> Word16
142
  POp
LEQU -> Word16
143
  POp
LESU -> Word16
144
  POp
NOTB -> Word16
145
  POp
ANDB -> Word16
146
  POp
IORB -> Word16
147

pOpAssoc :: [(POp, Word16)]
pOpAssoc :: [(POp, Word16)]
pOpAssoc = (POp -> (POp, Word16)) -> [POp] -> [(POp, Word16)]
forall a b. (a -> b) -> [a] -> [b]
map (\POp
op -> (POp
op, POp -> Word16
pOpCode POp
op)) [POp
forall a. Bounded a => a
minBound .. POp
forall a. Bounded a => a
maxBound]

pop2word :: Map POp Word16
pop2word :: Map POp Word16
pop2word = [(POp, Word16)] -> Map POp Word16
forall k a. Ord k => [(k, a)] -> Map k a
fromList [(POp, Word16)]
pOpAssoc

word2pop :: Map Word16 POp
word2pop :: Map Word16 POp
word2pop = [(Word16, POp)] -> Map Word16 POp
forall k a. Ord k => [(k, a)] -> Map k a
fromList ([(Word16, POp)] -> Map Word16 POp)
-> [(Word16, POp)] -> Map Word16 POp
forall a b. (a -> b) -> a -> b
$ (POp, Word16) -> (Word16, POp)
forall {b} {a}. (b, a) -> (a, b)
swap ((POp, Word16) -> (Word16, POp))
-> [(POp, Word16)] -> [(Word16, POp)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(POp, Word16)]
pOpAssoc
  where
    swap :: (b, a) -> (a, b)
swap (b
x, a
y) = (a
y, b
x)