@@ -8,6 +8,9 @@ module Unison.Runtime.Foreign.Function
8
8
, foreignCall
9
9
, readsAtError
10
10
, foreignConventionError
11
+ , pseudoConstructors
12
+ , functionReplacements
13
+ , functionUnreplacements
11
14
) where
12
15
13
16
import Control.Concurrent (ThreadId )
@@ -35,6 +38,8 @@ import Data.ByteString.Lazy qualified as L
35
38
import Data.Default (def )
36
39
import Data.Digest.Murmur64 (asWord64 , hash64 )
37
40
import Data.IP (IP )
41
+ import Data.Map.Strict qualified as Map
42
+ import Data.Map.Strict.Internal qualified as Map
38
43
import Data.PEM (PEM , pemContent , pemParseLBS )
39
44
import Data.Sequence qualified as Sq
40
45
import Data.Tagged (Tagged (.. ))
@@ -148,7 +153,8 @@ import Unison.Runtime.Crypto.Rsa qualified as Rsa
148
153
import Unison.Runtime.Exception
149
154
import Unison.Runtime.Foreign hiding (Failure )
150
155
import Unison.Runtime.Foreign qualified as F
151
- import Unison.Runtime.Foreign.Function.Type (ForeignFunc (.. ))
156
+ import Unison.Runtime.Foreign.Function.Type
157
+ (ForeignFunc (.. ), foreignFuncBuiltinName )
152
158
import Unison.Runtime.MCode
153
159
import Unison.Runtime.Stack
154
160
import Unison.Runtime.TypeTags qualified as TT
@@ -858,6 +864,24 @@ foreignCallHelper = \case
858
864
Char_Class_is -> mkForeign $ \ (cl, c) -> evaluate $ TPat. charPatternPred cl c
859
865
Text_patterns_char -> mkForeign $ \ c ->
860
866
let v = TPat. cpattern (TPat. Char c) in pure v
867
+ Map_tip -> mkForeign $ \ () -> pure Map. empty
868
+ Map_bin -> mkForeign $ \ (sz :: Word64 , k :: Val , v :: Val , l , r ) ->
869
+ pure (Map. Bin (fromIntegral sz) k v l r)
870
+ Map_insert -> mkForeign $ \ (k :: Val , v :: Val , m :: Map Val Val ) ->
871
+ evaluate $ Map. insert k v m
872
+ Map_lookup -> mkForeign $ \ (k :: Val , v :: Map Val Val ) ->
873
+ evaluate $ Map. lookup k v
874
+ Map_fromList -> mkForeign $ \ (l :: [(Val , Val )]) ->
875
+ evaluate $ Map. fromList l
876
+ Map_eq -> mkForeign $ \ (l :: Map Val Val , r :: Map Val Val ) ->
877
+ pure $ l == r
878
+ List_range -> mkForeign $ \ (m :: Word64 , n :: Word64 ) ->
879
+ let sz | m < n = fromIntegral $ n - m
880
+ | otherwise = 0
881
+ mk i = NatVal $ m + fromIntegral i
882
+ force s = foldl (\ u x -> x `seq` u) s s
883
+ in evaluate . force $ Sq. fromFunction sz mk
884
+ List_sort -> mkForeign $ \ (l :: Seq Val ) -> pure $ Sq. unstableSort l
861
885
where
862
886
chop = reverse . dropWhile isPathSeparator . reverse
863
887
@@ -1928,3 +1952,53 @@ instance {-# overlappable #-} (BuiltinForeign b) => ForeignConvention b where
1928
1952
encodeVal = encodeBuiltin
1929
1953
readAtIndex = readBuiltinAt
1930
1954
writeBack = writeBuiltin
1955
+
1956
+ pseudoConstructors :: Map Reference (Map TT. CTag ForeignFunc )
1957
+ pseudoConstructors =
1958
+ Map. singleton Ty. mapRef $
1959
+ Map. fromList
1960
+ [ (fromIntegral Ty. mapTip, Map_tip )
1961
+ , (fromIntegral Ty. mapBin, Map_bin )
1962
+ ]
1963
+
1964
+ functionReplacementList :: [(Data.Text. Text , ForeignFunc )]
1965
+ functionReplacementList =
1966
+ [ ( " 03hqp8knrcgdc733mitcunjlug4cpi9headkggu8h9d87nfgneo6e"
1967
+ , Map_insert
1968
+ )
1969
+ , ( " 03g44bb2bp3g5eld8eh07g6e8iq7oiqiplapeb6jerbs7ee3icq9s"
1970
+ , Map_lookup
1971
+ )
1972
+ , ( " 005mc1fq7ojq72c238qlm2rspjgqo2furjodf28icruv316odu6du"
1973
+ , Map_fromList
1974
+ )
1975
+ , ( " 03c559iihi2vj0qps6cln48nv31ajup2srhas4pd05b9k46ds8jvk"
1976
+ , Map_eq
1977
+ )
1978
+ , ( " 01f446li3b0j5gcnj7fa99jfqir43shs0jqu779oo0npb7v8d3v22"
1979
+ , List_range
1980
+ )
1981
+ , ( " 00jh7o3l67okqqalho1sqgl4ei9n2sdhrpqobgkf7j390v4e938km"
1982
+ , List_sort
1983
+ )
1984
+ ]
1985
+
1986
+ functionReplacements :: Map Reference Reference
1987
+ functionReplacements =
1988
+ Map. fromList $ fmap process functionReplacementList
1989
+
1990
+ functionUnreplacements :: Map Reference Reference
1991
+ functionUnreplacements =
1992
+ Map. fromList . fmap (swap . process) $ functionReplacementList
1993
+ where
1994
+ swap (x, y) = (y, x)
1995
+
1996
+ -- Note: using index 0 right now. Generalize if ever replacing
1997
+ -- part of a mutually recursive group.
1998
+ process :: (Data.Text. Text , ForeignFunc ) -> (Reference , Reference )
1999
+ process (str, ff) = case derivedBase32Hex str 0 of
2000
+ Nothing -> error $ " Could not create reference for " ++ sname
2001
+ Just r -> (r, Builtin name)
2002
+ where
2003
+ name = foreignFuncBuiltinName ff
2004
+ sname = Data.Text. unpack name
0 commit comments