-
Notifications
You must be signed in to change notification settings - Fork 267
/
Builtin.hs
2919 lines (2585 loc) · 93.2 KB
/
Builtin.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
module Unison.Runtime.Builtin
( builtinLookup,
builtinTermNumbering,
builtinTypeNumbering,
builtinTermBackref,
builtinTypeBackref,
builtinForeigns,
numberedTermLookup,
Sandbox (..),
baseSandboxInfo,
)
where
import Control.Concurrent (ThreadId)
import Control.Concurrent as SYS
( killThread,
threadDelay,
)
import Control.Concurrent.MVar as SYS
import qualified Control.Concurrent.STM as STM
import Control.DeepSeq (NFData)
import qualified Control.Exception.Safe as Exception
import Control.Monad.Catch (MonadCatch)
import qualified Control.Monad.Primitive as PA
import Control.Monad.State.Strict (State, execState, modify)
import qualified Crypto.Hash as Hash
import qualified Crypto.MAC.HMAC as HMAC
import Data.Bits (shiftL, shiftR, (.|.))
import qualified Data.ByteArray as BA
import Data.ByteString (hGet, hGetSome, hPut)
import qualified Data.ByteString.Lazy as L
import Data.Default (def)
import Data.IORef as SYS
( IORef,
newIORef,
readIORef,
writeIORef,
)
import qualified Data.Map as Map
import Data.PEM (PEM, pemContent, pemParseLBS)
import qualified Data.Primitive as PA
import Data.Set (insert)
import qualified Data.Set as Set
import qualified Data.Text
import qualified Data.Text.IO as Text.IO
import Data.Time.Clock.POSIX as SYS
( getPOSIXTime,
utcTimeToPOSIXSeconds,
)
import qualified Data.X509 as X
import qualified Data.X509.CertificateStore as X
import qualified Data.X509.Memory as X
import qualified GHC.Conc as STM
import GHC.IO (IO (IO))
import Network.Simple.TCP as SYS
( HostPreference (..),
bindSock,
closeSock,
connectSock,
listenSock,
recv,
send,
)
import Network.Socket as SYS
( Socket,
accept,
socketPort,
)
import Network.TLS as TLS
import Network.TLS.Extra.Cipher as Cipher
import System.Clock (Clock (..), getTime, nsec, sec)
import System.Directory as SYS
( createDirectoryIfMissing,
doesDirectoryExist,
doesPathExist,
getCurrentDirectory,
getDirectoryContents,
getFileSize,
getModificationTime,
getTemporaryDirectory,
removeDirectoryRecursive,
removeFile,
renameDirectory,
renameFile,
setCurrentDirectory,
)
import System.Environment as SYS
( getArgs,
getEnv,
)
import System.IO (Handle)
import System.IO as SYS
( IOMode (..),
hClose,
hGetBuffering,
hIsEOF,
hIsOpen,
hIsSeekable,
hSeek,
hSetBuffering,
hTell,
openFile,
stderr,
stdin,
stdout,
)
import System.IO.Temp (createTempDirectory)
import qualified System.X509 as X
import Unison.ABT.Normalized hiding (TTm)
import qualified Unison.Builtin as Ty (builtinTypes)
import qualified Unison.Builtin.Decls as Ty
import Unison.Prelude hiding (Text, some)
import Unison.Reference
import Unison.Referent (pattern Ref)
import Unison.Runtime.ANF as ANF
import Unison.Runtime.ANF.Serialize as ANF
import Unison.Runtime.Foreign
( Foreign (Wrap),
HashAlgorithm (..),
pattern Failure,
)
import qualified Unison.Runtime.Foreign as F
import Unison.Runtime.Foreign.Function
import Unison.Runtime.Stack (Closure)
import qualified Unison.Runtime.Stack as Closure
import Unison.Symbol
import qualified Unison.Type as Ty
import qualified Unison.Util.Bytes as Bytes
import Unison.Util.EnumContainers as EC
import Unison.Util.Text (Text)
import qualified Unison.Util.Text as Util.Text
import Unison.Var
type Failure = F.Failure Closure
freshes :: Var v => Int -> [v]
freshes = freshes' mempty
freshes' :: Var v => Set v -> Int -> [v]
freshes' avoid0 = go avoid0 []
where
go _ vs 0 = vs
go avoid vs n =
let v = freshIn avoid $ typed ANFBlank
in go (insert v avoid) (v : vs) (n - 1)
fresh1 :: Var v => v
fresh1 = head $ freshes 1
fresh2 :: Var v => (v, v)
fresh2 = (v1, v2)
where
[v1, v2] = freshes 2
fresh3 :: Var v => (v, v, v)
fresh3 = (v1, v2, v3)
where
[v1, v2, v3] = freshes 3
fresh4 :: Var v => (v, v, v, v)
fresh4 = (v1, v2, v3, v4)
where
[v1, v2, v3, v4] = freshes 4
fresh6 :: Var v => (v, v, v, v, v, v)
fresh6 = (v1, v2, v3, v4, v5, v6)
where
[v1, v2, v3, v4, v5, v6] = freshes 6
fresh7 :: Var v => (v, v, v, v, v, v, v)
fresh7 = (v1, v2, v3, v4, v5, v6, v7)
where
[v1, v2, v3, v4, v5, v6, v7] = freshes 7
fresh8 :: Var v => (v, v, v, v, v, v, v, v)
fresh8 = (v1, v2, v3, v4, v5, v6, v7, v8)
where
[v1, v2, v3, v4, v5, v6, v7, v8] = freshes 8
fresh9 :: Var v => (v, v, v, v, v, v, v, v, v)
fresh9 = (v1, v2, v3, v4, v5, v6, v7, v8, v9)
where
[v1, v2, v3, v4, v5, v6, v7, v8, v9] = freshes 9
fresh10 :: Var v => (v, v, v, v, v, v, v, v, v, v)
fresh10 = (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
where
[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] = freshes 10
fresh11 :: Var v => (v, v, v, v, v, v, v, v, v, v, v)
fresh11 = (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
where
[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11] = freshes 11
fresh13 :: Var v => (v, v, v, v, v, v, v, v, v, v, v, v, v)
fresh13 = (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
where
[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13] = freshes 13
fls, tru :: Var v => ANormal v
fls = TCon Ty.booleanRef 0 []
tru = TCon Ty.booleanRef 1 []
none :: Var v => ANormal v
none = TCon Ty.optionalRef (fromIntegral Ty.noneId) []
some, left, right :: Var v => v -> ANormal v
some a = TCon Ty.optionalRef (fromIntegral Ty.someId) [a]
left x = TCon Ty.eitherRef (fromIntegral Ty.eitherLeftId) [x]
right x = TCon Ty.eitherRef (fromIntegral Ty.eitherRightId) [x]
seqViewEmpty :: Var v => ANormal v
seqViewEmpty = TCon Ty.seqViewRef (fromIntegral Ty.seqViewEmpty) []
seqViewElem :: Var v => v -> v -> ANormal v
seqViewElem l r = TCon Ty.seqViewRef (fromIntegral Ty.seqViewElem) [l, r]
boolift :: Var v => v -> ANormal v
boolift v =
TMatch v $ MatchIntegral (mapFromList [(0, fls), (1, tru)]) Nothing
notlift :: Var v => v -> ANormal v
notlift v =
TMatch v $ MatchIntegral (mapFromList [(1, fls), (0, tru)]) Nothing
unbox :: Var v => v -> Reference -> v -> ANormal v -> ANormal v
unbox v0 r v b =
TMatch v0 $
MatchData r (mapSingleton 0 $ ([UN], TAbs v b)) Nothing
unenum :: Var v => Int -> v -> Reference -> v -> ANormal v -> ANormal v
unenum n v0 r v nx =
TMatch v0 $ MatchData r cases Nothing
where
mkCase i = (toEnum i, ([], TLetD v UN (TLit . I $ fromIntegral i) nx))
cases = mapFromList . fmap mkCase $ [0 .. n - 1]
unop0 :: Var v => Int -> ([v] -> ANormal v) -> SuperNormal v
unop0 n f =
Lambda [BX]
. TAbss [x0]
$ f xs
where
xs@(x0 : _) = freshes (1 + n)
binop0 :: Var v => Int -> ([v] -> ANormal v) -> SuperNormal v
binop0 n f =
Lambda [BX, BX]
. TAbss [x0, y0]
$ f xs
where
xs@(x0 : y0 : _) = freshes (2 + n)
unop :: Var v => POp -> Reference -> SuperNormal v
unop pop rf = unop' pop rf rf
unop' :: Var v => POp -> Reference -> Reference -> SuperNormal v
unop' pop rfi rfo =
unop0 2 $ \[x0, x, r] ->
unbox x0 rfi x
. TLetD r UN (TPrm pop [x])
$ TCon rfo 0 [r]
binop :: Var v => POp -> Reference -> SuperNormal v
binop pop rf = binop' pop rf rf rf
binop' ::
Var v =>
POp ->
Reference ->
Reference ->
Reference ->
SuperNormal v
binop' pop rfx rfy rfr =
binop0 3 $ \[x0, y0, x, y, r] ->
unbox x0 rfx x
. unbox y0 rfy y
. TLetD r UN (TPrm pop [x, y])
$ TCon rfr 0 [r]
cmpop :: Var v => POp -> Reference -> SuperNormal v
cmpop pop rf =
binop0 3 $ \[x0, y0, x, y, b] ->
unbox x0 rf x
. unbox y0 rf y
. TLetD b UN (TPrm pop [x, y])
$ boolift b
cmpopb :: Var v => POp -> Reference -> SuperNormal v
cmpopb pop rf =
binop0 3 $ \[x0, y0, x, y, b] ->
unbox x0 rf x
. unbox y0 rf y
. TLetD b UN (TPrm pop [y, x])
$ boolift b
cmpopn :: Var v => POp -> Reference -> SuperNormal v
cmpopn pop rf =
binop0 3 $ \[x0, y0, x, y, b] ->
unbox x0 rf x
. unbox y0 rf y
. TLetD b UN (TPrm pop [x, y])
$ notlift b
cmpopbn :: Var v => POp -> Reference -> SuperNormal v
cmpopbn pop rf =
binop0 3 $ \[x0, y0, x, y, b] ->
unbox x0 rf x
. unbox y0 rf y
. TLetD b UN (TPrm pop [y, x])
$ notlift b
addi, subi, muli, divi, modi, shli, shri, powi :: Var v => SuperNormal v
addi = binop ADDI Ty.intRef
subi = binop SUBI Ty.intRef
muli = binop MULI Ty.intRef
divi = binop DIVI Ty.intRef
modi = binop MODI Ty.intRef
shli = binop' SHLI Ty.intRef Ty.natRef Ty.intRef
shri = binop' SHRI Ty.intRef Ty.natRef Ty.intRef
powi = binop' POWI Ty.intRef Ty.natRef Ty.intRef
addn, subn, muln, divn, modn, shln, shrn, pown :: Var v => SuperNormal v
addn = binop ADDN Ty.natRef
subn = binop' SUBN Ty.natRef Ty.natRef Ty.intRef
muln = binop MULN Ty.natRef
divn = binop DIVN Ty.natRef
modn = binop MODN Ty.natRef
shln = binop SHLN Ty.natRef
shrn = binop SHRN Ty.natRef
pown = binop POWN Ty.natRef
eqi, eqn, lti, ltn, lei, len :: Var v => SuperNormal v
eqi = cmpop EQLI Ty.intRef
lti = cmpopbn LEQI Ty.intRef
lei = cmpop LEQI Ty.intRef
eqn = cmpop EQLN Ty.natRef
ltn = cmpopbn LEQN Ty.natRef
len = cmpop LEQN Ty.natRef
gti, gtn, gei, gen :: Var v => SuperNormal v
gti = cmpopn LEQI Ty.intRef
gei = cmpopb LEQI Ty.intRef
gtn = cmpopn LEQN Ty.intRef
gen = cmpopb LEQN Ty.intRef
inci, incn :: Var v => SuperNormal v
inci = unop INCI Ty.intRef
incn = unop INCN Ty.natRef
sgni, negi :: Var v => SuperNormal v
sgni = unop SGNI Ty.intRef
negi = unop NEGI Ty.intRef
lzeron, tzeron, lzeroi, tzeroi, popn, popi :: Var v => SuperNormal v
lzeron = unop LZRO Ty.natRef
tzeron = unop TZRO Ty.natRef
popn = unop POPC Ty.natRef
popi = unop' POPC Ty.intRef Ty.natRef
lzeroi = unop' LZRO Ty.intRef Ty.natRef
tzeroi = unop' TZRO Ty.intRef Ty.natRef
andn, orn, xorn, compln, andi, ori, xori, compli :: Var v => SuperNormal v
andn = binop ANDN Ty.natRef
orn = binop IORN Ty.natRef
xorn = binop XORN Ty.natRef
compln = unop COMN Ty.natRef
andi = binop ANDN Ty.intRef
ori = binop IORN Ty.intRef
xori = binop XORN Ty.intRef
compli = unop COMN Ty.intRef
addf,
subf,
mulf,
divf,
powf,
sqrtf,
logf,
logbf ::
Var v => SuperNormal v
addf = binop ADDF Ty.floatRef
subf = binop SUBF Ty.floatRef
mulf = binop MULF Ty.floatRef
divf = binop DIVF Ty.floatRef
powf = binop POWF Ty.floatRef
sqrtf = unop SQRT Ty.floatRef
logf = unop LOGF Ty.floatRef
logbf = binop LOGB Ty.floatRef
expf, absf :: Var v => SuperNormal v
expf = unop EXPF Ty.floatRef
absf = unop ABSF Ty.floatRef
cosf, sinf, tanf, acosf, asinf, atanf :: Var v => SuperNormal v
cosf = unop COSF Ty.floatRef
sinf = unop SINF Ty.floatRef
tanf = unop TANF Ty.floatRef
acosf = unop ACOS Ty.floatRef
asinf = unop ASIN Ty.floatRef
atanf = unop ATAN Ty.floatRef
coshf,
sinhf,
tanhf,
acoshf,
asinhf,
atanhf,
atan2f ::
Var v => SuperNormal v
coshf = unop COSH Ty.floatRef
sinhf = unop SINH Ty.floatRef
tanhf = unop TANH Ty.floatRef
acoshf = unop ACSH Ty.floatRef
asinhf = unop ASNH Ty.floatRef
atanhf = unop ATNH Ty.floatRef
atan2f = binop ATN2 Ty.floatRef
ltf, gtf, lef, gef, eqf, neqf :: Var v => SuperNormal v
ltf = cmpopbn LEQF Ty.floatRef
gtf = cmpopn LEQF Ty.floatRef
lef = cmpop LEQF Ty.floatRef
gef = cmpopb LEQF Ty.floatRef
eqf = cmpop EQLF Ty.floatRef
neqf = cmpopn EQLF Ty.floatRef
minf, maxf :: Var v => SuperNormal v
minf = binop MINF Ty.floatRef
maxf = binop MAXF Ty.floatRef
ceilf, floorf, truncf, roundf, i2f, n2f :: Var v => SuperNormal v
ceilf = unop' CEIL Ty.floatRef Ty.intRef
floorf = unop' FLOR Ty.floatRef Ty.intRef
truncf = unop' TRNF Ty.floatRef Ty.intRef
roundf = unop' RNDF Ty.floatRef Ty.intRef
i2f = unop' ITOF Ty.intRef Ty.floatRef
n2f = unop' NTOF Ty.natRef Ty.floatRef
trni :: Var v => SuperNormal v
trni = unop0 3 $ \[x0, x, z, b] ->
unbox x0 Ty.intRef x
. TLetD z UN (TLit $ I 0)
. TLetD b UN (TPrm LEQI [x, z])
. TMatch b
$ MatchIntegral
(mapSingleton 1 $ TCon Ty.natRef 0 [z])
(Just $ TCon Ty.natRef 0 [x])
modular :: Var v => POp -> (Bool -> ANormal v) -> SuperNormal v
modular pop ret =
unop0 3 $ \[x0, x, m, t] ->
unbox x0 Ty.intRef x
. TLetD t UN (TLit $ I 2)
. TLetD m UN (TPrm pop [x, t])
. TMatch m
$ MatchIntegral
(mapSingleton 1 $ ret True)
(Just $ ret False)
evni, evnn, oddi, oddn :: Var v => SuperNormal v
evni = modular MODI (\b -> if b then fls else tru)
oddi = modular MODI (\b -> if b then tru else fls)
evnn = modular MODN (\b -> if b then fls else tru)
oddn = modular MODN (\b -> if b then tru else fls)
dropn :: Var v => SuperNormal v
dropn = binop0 4 $ \[x0, y0, x, y, b, r] ->
unbox x0 Ty.natRef x
. unbox y0 Ty.natRef y
. TLetD b UN (TPrm LEQN [x, y])
. TLet
(Indirect 1)
r
UN
( TMatch b $
MatchIntegral
(mapSingleton 1 $ TLit $ N 0)
(Just $ TPrm SUBN [x, y])
)
$ TCon Ty.natRef 0 [r]
appendt, taket, dropt, sizet, unconst, unsnoct :: Var v => SuperNormal v
appendt = binop0 0 $ \[x, y] -> TPrm CATT [x, y]
taket = binop0 1 $ \[x0, y, x] ->
unbox x0 Ty.natRef x $
TPrm TAKT [x, y]
dropt = binop0 1 $ \[x0, y, x] ->
unbox x0 Ty.natRef x $
TPrm DRPT [x, y]
sizet = unop0 1 $ \[x, r] ->
TLetD r UN (TPrm SIZT [x]) $
TCon Ty.natRef 0 [r]
unconst = unop0 7 $ \[x, t, c0, c, y, p, u, yp] ->
TLetD t UN (TPrm UCNS [x])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [UN, BX],
TAbss [c0, y]
. TLetD u BX (TCon Ty.unitRef 0 [])
. TLetD yp BX (TCon Ty.pairRef 0 [y, u])
. TLetD c BX (TCon Ty.charRef 0 [c0])
. TLetD p BX (TCon Ty.pairRef 0 [c, yp])
$ some p
)
)
]
unsnoct = unop0 7 $ \[x, t, c0, c, y, p, u, cp] ->
TLetD t UN (TPrm USNC [x])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [BX, UN],
TAbss [y, c0]
. TLetD u BX (TCon Ty.unitRef 0 [])
. TLetD c BX (TCon Ty.charRef 0 [c0])
. TLetD cp BX (TCon Ty.pairRef 0 [c, u])
. TLetD p BX (TCon Ty.pairRef 0 [y, cp])
$ some p
)
)
]
appends, conss, snocs :: Var v => SuperNormal v
appends = binop0 0 $ \[x, y] -> TPrm CATS [x, y]
conss = binop0 0 $ \[x, y] -> TPrm CONS [x, y]
snocs = binop0 0 $ \[x, y] -> TPrm SNOC [x, y]
coerceType :: Var v => Reference -> Reference -> SuperNormal v
coerceType fromType toType = unop0 1 $ \[x, r] ->
unbox x fromType r $
TCon toType 0 [r]
takes, drops, sizes, ats, emptys :: Var v => SuperNormal v
takes = binop0 1 $ \[x0, y, x] ->
unbox x0 Ty.natRef x $
TPrm TAKS [x, y]
drops = binop0 1 $ \[x0, y, x] ->
unbox x0 Ty.natRef x $
TPrm DRPS [x, y]
sizes = unop0 1 $ \[x, r] ->
TLetD r UN (TPrm SIZS [x]) $
TCon Ty.natRef 0 [r]
ats = binop0 3 $ \[x0, y, x, t, r] ->
unbox x0 Ty.natRef x
. TLetD t UN (TPrm IDXS [x, y])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
(1, ([BX], TAbs r $ some r))
]
emptys = Lambda [] $ TPrm BLDS []
viewls, viewrs :: Var v => SuperNormal v
viewls = unop0 3 $ \[s, u, h, t] ->
TLetD u UN (TPrm VWLS [s])
. TMatch u
. MatchSum
$ mapFromList
[ (0, ([], seqViewEmpty)),
(1, ([BX, BX], TAbss [h, t] $ seqViewElem h t))
]
viewrs = unop0 3 $ \[s, u, i, l] ->
TLetD u UN (TPrm VWRS [s])
. TMatch u
. MatchSum
$ mapFromList
[ (0, ([], seqViewEmpty)),
(1, ([BX, BX], TAbss [i, l] $ seqViewElem i l))
]
eqt, neqt, leqt, geqt, lesst, great :: SuperNormal Symbol
eqt = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm EQLT [x, y]) $
boolift b
neqt = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm EQLT [x, y]) $
notlift b
leqt = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm LEQT [x, y]) $
boolift b
geqt = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm LEQT [y, x]) $
boolift b
lesst = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm LEQT [y, x]) $
notlift b
great = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm LEQT [x, y]) $
notlift b
packt, unpackt :: SuperNormal Symbol
packt = unop0 0 $ \[s] -> TPrm PAKT [s]
unpackt = unop0 0 $ \[t] -> TPrm UPKT [t]
packb, unpackb, emptyb, appendb :: SuperNormal Symbol
packb = unop0 0 $ \[s] -> TPrm PAKB [s]
unpackb = unop0 0 $ \[b] -> TPrm UPKB [b]
emptyb =
Lambda []
. TLetD es BX (TPrm BLDS [])
$ TPrm PAKB [es]
where
es = fresh1
appendb = binop0 0 $ \[x, y] -> TPrm CATB [x, y]
takeb, dropb, atb, sizeb, flattenb :: SuperNormal Symbol
takeb = binop0 1 $ \[n0, b, n] ->
unbox n0 Ty.natRef n $
TPrm TAKB [n, b]
dropb = binop0 1 $ \[n0, b, n] ->
unbox n0 Ty.natRef n $
TPrm DRPB [n, b]
atb = binop0 4 $ \[n0, b, n, t, r0, r] ->
unbox n0 Ty.natRef n
. TLetD t UN (TPrm IDXB [n, b])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [UN],
TAbs r0
. TLetD r BX (TCon Ty.natRef 0 [r0])
$ some r
)
)
]
sizeb = unop0 1 $ \[b, n] ->
TLetD n UN (TPrm SIZB [b]) $
TCon Ty.natRef 0 [n]
flattenb = unop0 0 $ \[b] -> TPrm FLTB [b]
i2t, n2t, f2t :: SuperNormal Symbol
i2t = unop0 1 $ \[n0, n] ->
unbox n0 Ty.intRef n $
TPrm ITOT [n]
n2t = unop0 1 $ \[n0, n] ->
unbox n0 Ty.natRef n $
TPrm NTOT [n]
f2t = unop0 1 $ \[f0, f] ->
unbox f0 Ty.floatRef f $
TPrm FTOT [f]
t2i, t2n, t2f :: SuperNormal Symbol
t2i = unop0 3 $ \[x, t, n0, n] ->
TLetD t UN (TPrm TTOI [x])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [UN],
TAbs n0
. TLetD n BX (TCon Ty.intRef 0 [n0])
$ some n
)
)
]
t2n = unop0 3 $ \[x, t, n0, n] ->
TLetD t UN (TPrm TTON [x])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [UN],
TAbs n0
. TLetD n BX (TCon Ty.natRef 0 [n0])
$ some n
)
)
]
t2f = unop0 3 $ \[x, t, f0, f] ->
TLetD t UN (TPrm TTOF [x])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
( 1,
( [UN],
TAbs f0
. TLetD f BX (TCon Ty.floatRef 0 [f0])
$ some f
)
)
]
equ :: SuperNormal Symbol
equ = binop0 1 $ \[x, y, b] ->
TLetD b UN (TPrm EQLU [x, y]) $
boolift b
cmpu :: SuperNormal Symbol
cmpu = binop0 2 $ \[x, y, c, i] ->
TLetD c UN (TPrm CMPU [x, y])
. TLetD i UN (TPrm DECI [c])
$ TCon Ty.intRef 0 [i]
ltu :: SuperNormal Symbol
ltu = binop0 1 $ \[x, y, c] ->
TLetD c UN (TPrm CMPU [x, y])
. TMatch c
$ MatchIntegral
(mapFromList [(0, TCon Ty.booleanRef 1 [])])
(Just $ TCon Ty.booleanRef 0 [])
gtu :: SuperNormal Symbol
gtu = binop0 1 $ \[x, y, c] ->
TLetD c UN (TPrm CMPU [x, y])
. TMatch c
$ MatchIntegral
(mapFromList [(2, TCon Ty.booleanRef 1 [])])
(Just $ TCon Ty.booleanRef 0 [])
geu :: SuperNormal Symbol
geu = binop0 1 $ \[x, y, c] ->
TLetD c UN (TPrm CMPU [x, y])
. TMatch c
$ MatchIntegral
(mapFromList [(0, TCon Ty.booleanRef 0 [])])
(Just $ TCon Ty.booleanRef 1 [])
leu :: SuperNormal Symbol
leu = binop0 1 $ \[x, y, c] ->
TLetD c UN (TPrm CMPU [x, y])
. TMatch c
$ MatchIntegral
(mapFromList [(2, TCon Ty.booleanRef 0 [])])
(Just $ TCon Ty.booleanRef 1 [])
notb :: SuperNormal Symbol
notb = unop0 0 $ \[b] ->
TMatch b . flip (MatchData Ty.booleanRef) Nothing $
mapFromList [(0, ([], tru)), (1, ([], fls))]
orb :: SuperNormal Symbol
orb = binop0 0 $ \[p, q] ->
TMatch p . flip (MatchData Ty.booleanRef) Nothing $
mapFromList [(1, ([], tru)), (0, ([], TVar q))]
andb :: SuperNormal Symbol
andb = binop0 0 $ \[p, q] ->
TMatch p . flip (MatchData Ty.booleanRef) Nothing $
mapFromList [(0, ([], fls)), (1, ([], TVar q))]
-- unsafeCoerce, used for numeric types where conversion is a
-- no-op on the representation. Ideally this will be inlined and
-- eliminated so that no instruction is necessary.
cast :: Reference -> Reference -> SuperNormal Symbol
cast ri ro =
unop0 1 $ \[x0, x] ->
unbox x0 ri x $
TCon ro 0 [x]
-- This version of unsafeCoerce is the identity function. It works
-- only if the two types being coerced between are actually the same,
-- because it keeps the same representation. It is not capable of
-- e.g. correctly translating between two types with compatible bit
-- representations, because tagging information will be retained.
poly'coerce :: SuperNormal Symbol
poly'coerce = unop0 0 $ \[x] -> TVar x
jumpk :: SuperNormal Symbol
jumpk = binop0 0 $ \[k, a] -> TKon k [a]
scope'run :: SuperNormal Symbol
scope'run =
unop0 1 $ \[e, un] ->
TLetD un BX (TCon Ty.unitRef 0 []) $
TApp (FVar e) [un]
fork'comp :: SuperNormal Symbol
fork'comp =
Lambda [BX]
. TAbs act
. TLetD unit BX (TCon Ty.unitRef 0 [])
. TName lz (Right act) [unit]
$ TPrm FORK [lz]
where
(act, unit, lz) = fresh3
bug :: Util.Text.Text -> SuperNormal Symbol
bug name =
unop0 1 $ \[x, n] ->
TLetD n BX (TLit $ T name) $
TPrm EROR [n, x]
watch :: SuperNormal Symbol
watch =
binop0 0 $ \[t, v] ->
TLets Direct [] [] (TPrm PRNT [t]) $
TVar v
raise :: SuperNormal Symbol
raise =
unop0 4 $ \[r, f, n, j, k] ->
TMatch r . flip (MatchData Ty.exceptionRef) Nothing $
mapFromList
[ (0, ([BX], TAbs f $ TVar f)),
( i,
( [UN, BX],
TAbss [j, f]
. TShift Ty.exceptionRef k
. TLetD n BX (TLit $ T "builtin.raise")
$ TPrm EROR [n, f]
)
)
]
where
i = fromIntegral $ builtinTypeNumbering Map.! Ty.exceptionRef
gen'trace :: SuperNormal Symbol
gen'trace =
binop0 0 $ \[t, v] ->
TLets Direct [] [] (TPrm TRCE [t, v]) $
TCon Ty.unitRef 0 []
code'missing :: SuperNormal Symbol
code'missing =
unop0 1 $ \[link, b] ->
TLetD b UN (TPrm MISS [link]) $
boolift b
code'cache :: SuperNormal Symbol
code'cache = unop0 0 $ \[new] -> TPrm CACH [new]
code'lookup :: SuperNormal Symbol
code'lookup =
unop0 2 $ \[link, t, r] ->
TLetD t UN (TPrm LKUP [link])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([], none)),
(1, ([BX], TAbs r $ some r))
]
code'validate :: SuperNormal Symbol
code'validate =
unop0 5 $ \[item, t, ref, msg, extra, fail] ->
TLetD t UN (TPrm CVLD [item])
. TMatch t
. MatchSum
$ mapFromList
[ ( 1,
([BX, BX, BX],)
. TAbss [ref, msg, extra]
. TLetD fail BX (TCon Ty.failureRef 0 [ref, msg, extra])
$ some fail
),
( 0,
([],) $
none
)
]
term'link'to'text :: SuperNormal Symbol
term'link'to'text =
unop0 0 $ \[link] -> TPrm TLTT [link]
value'load :: SuperNormal Symbol
value'load =
unop0 2 $ \[vlu, t, r] ->
TLetD t UN (TPrm LOAD [vlu])
. TMatch t
. MatchSum
$ mapFromList
[ (0, ([BX], TAbs r $ left r)),
(1, ([BX], TAbs r $ right r))
]
value'create :: SuperNormal Symbol
value'create = unop0 0 $ \[x] -> TPrm VALU [x]
check'sandbox :: SuperNormal Symbol
check'sandbox =
Lambda [BX, BX]
. TAbss [refs, val]
. TLetD b UN (TPrm SDBX [refs, val])
$ boolift b
where
(refs, val, b) = fresh3
stm'atomic :: SuperNormal Symbol
stm'atomic =
Lambda [BX]
. TAbs act
. TLetD unit BX (TCon Ty.unitRef 0 [])
. TName lz (Right act) [unit]
$ TPrm ATOM [lz]
where
(act, unit, lz) = fresh3
type ForeignOp = FOp -> ([Mem], ANormal Symbol)
standard'handle :: ForeignOp
standard'handle instr =
([BX],)
. TAbss [h0]
. unenum 3 h0 Ty.stdHandleRef h
$ TFOp instr [h]
where
(h0, h) = fresh2
any'construct :: SuperNormal Symbol
any'construct =
unop0 0 $ \[v] ->
TCon Ty.anyRef 0 [v]
any'extract :: SuperNormal Symbol
any'extract =
unop0 1 $
\[v, v1] ->
TMatch v $
MatchData Ty.anyRef (mapSingleton 0 $ ([BX], TAbs v1 (TVar v1))) Nothing
seek'handle :: ForeignOp
seek'handle instr =
([BX, BX, BX],)
. TAbss [arg1, arg2, arg3]
. unenum 3 arg2 Ty.seekModeRef seek
. unbox arg3 Ty.intRef nat
. TLetD result UN (TFOp instr [arg1, seek, nat])
$ outIoFailUnit stack1 stack2 stack3 unit fail result
where
(arg1, arg2, arg3, seek, nat, stack1, stack2, stack3, unit, fail, result) = fresh11
no'buf, line'buf, block'buf, sblock'buf :: Enum e => e
no'buf = toEnum $ fromIntegral Ty.bufferModeNoBufferingId
line'buf = toEnum $ fromIntegral Ty.bufferModeLineBufferingId
block'buf = toEnum $ fromIntegral Ty.bufferModeBlockBufferingId
sblock'buf = toEnum $ fromIntegral Ty.bufferModeSizedBlockBufferingId
infixr 0 -->
(-->) :: a -> b -> (a, b)
x --> y = (x, y)
set'buffering :: ForeignOp
set'buffering instr =
([BX, BX],)
. TAbss [handle, bmode]
. TMatch bmode
. MatchDataCover Ty.bufferModeRef
$ mapFromList
[ no'buf --> [] --> k1 no'buf,
line'buf --> [] --> k1 line'buf,
block'buf --> [] --> k1 block'buf,
sblock'buf --> [BX]
--> TAbs n . TMatch n . MatchDataCover Ty.bufferModeRef
$ mapFromList
[ 0 --> [UN]
--> TAbs w
. TLetD tag UN (TLit (N sblock'buf))
$ k2 [tag, w]
]
]
where
k1 num =
TLetD tag UN (TLit (N num)) $
k2 [tag]
k2 args =
TLetD r UN (TFOp instr (handle : args)) $
outIoFailUnit s1 s2 s3 u f r
(handle, bmode, tag, n, w, s1, s2, s3, u, f, r) = fresh11
get'buffering'output :: forall v. Var v => v -> v -> v -> v -> v -> v -> ANormal v
get'buffering'output eitherResult stack1 stack2 resultTag failVar successVar =
TMatch eitherResult . MatchSum $
mapFromList
[ ( 0,
([BX, BX],)
. TAbss [stack1, stack2]
. TLetD failVar BX (TCon Ty.failureRef 0 [stack1, stack2])
$ left failVar
),
( 1,
([UN],)
. TAbs resultTag
. TMatch resultTag
. MatchSum
$ mapFromList
[ no'buf --> []
--> TLetD successVar BX (TCon Ty.bufferModeRef no'buf [])
$ right successVar,