44-- license that can be found in the LICENSE file or at
55-- https://developers.google.com/open-source/licenses/bsd
66
7+ {-# LANGUAGE GADTs #-}
8+
79module Dex.Foreign.Context (
8- Context (.. ),
10+ Context (.. ), AtomEx ( .. ),
911 setError ,
1012 dexCreateContext , dexDestroyContext ,
1113 dexInsert , dexLookup ,
12- dexEval , dexEvalExpr ,
14+ dexEval ,
1315 ) where
1416
1517import Foreign.Ptr
1618import Foreign.StablePtr
1719import Foreign.C.String
1820
21+ import Control.Monad.IO.Class
1922import Data.String
2023import Data.Int
2124import Data.Functor
@@ -26,18 +29,18 @@ import Resources
2629import Syntax hiding (sizeOf )
2730import Type
2831import TopLevel
29- import Env hiding ( Tag )
32+ import Name
3033import PPrint
3134import Err
35+ import Parser
36+ import Builder
3237
3338import Dex.Foreign.Util
3439
35- import SaferNames.Bridge
36- import qualified SaferNames.Syntax as S
37- import qualified SaferNames.Parser as S
38-
3940
4041data Context = Context EvalConfig TopStateEx
42+ data AtomEx where
43+ AtomEx :: Atom n -> AtomEx
4144
4245foreign import ccall " _internal_dexSetError" internalSetErrorPtr :: CString -> Int64 -> IO ()
4346setError :: String -> IO ()
@@ -46,70 +49,45 @@ setError msg = withCStringLen msg $ \(ptr, len) ->
4649
4750dexCreateContext :: IO (Ptr Context )
4851dexCreateContext = do
49- let evalConfig = EvalConfig LLVM Nothing Nothing
50- maybePreludeEnv <- evalPrelude evalConfig preludeSource
51- case maybePreludeEnv of
52- Success preludeEnv -> toStablePtr $ Context evalConfig preludeEnv
53- Failure err -> nullPtr <$ setError (" Failed to initialize standard library: " ++ pprint err)
54- where
55- evalPrelude :: EvalConfig -> String -> IO (Except TopStateEx )
56- evalPrelude opts sourceText = do
57- (results, env) <- runInterblockM opts initTopState $
58- map snd <$> evalSourceText sourceText
59- return $ env `unlessError` results
60- where
61- unlessError :: TopStateEx -> [Result ] -> Except TopStateEx
62- result `unlessError` [] = Success result
63- _ `unlessError` ((Result _ (Failure err)): _) = Failure err
64- result `unlessError` (_: t ) = result `unlessError` t
52+ let evalConfig = EvalConfig LLVM Nothing Nothing Nothing
53+ cachedEnv <- loadCache
54+ runTopperM evalConfig cachedEnv (evalSourceBlockRepl preludeImportBlock) >>= \ case
55+ (Result [] (Success () ), preludeEnv) -> toStablePtr $ Context evalConfig preludeEnv
56+ (Result _ (Failure err), _ ) -> nullPtr <$
57+ setError (" Failed to initialize standard library: " ++ pprint err)
6558
6659dexDestroyContext :: Ptr Context -> IO ()
6760dexDestroyContext = freeStablePtr . castPtrToStablePtr . castPtr
6861
6962dexEval :: Ptr Context -> CString -> IO (Ptr Context )
7063dexEval ctxPtr sourcePtr = do
71- Context evalConfig env <- fromStablePtr ctxPtr
64+ Context evalConfig initEnv <- fromStablePtr ctxPtr
7265 source <- peekCString sourcePtr
73- (results, finalEnv) <- runInterblockM evalConfig env $ evalSourceText source
66+ (results, finalEnv) <- runTopperM evalConfig initEnv $ evalSourceText source
7467 let anyError = asum $ fmap (\ case (_, Result _ (Failure err)) -> Just err; _ -> Nothing ) results
7568 case anyError of
7669 Nothing -> toStablePtr $ Context evalConfig finalEnv
7770 Just err -> setError (pprint err) $> nullPtr
7871
79- dexInsert :: Ptr Context -> CString -> Ptr Atom -> IO (Ptr Context )
72+ dexInsert :: Ptr Context -> CString -> Ptr AtomEx -> IO (Ptr Context )
8073dexInsert ctxPtr namePtr atomPtr = do
81- Context evalConfig (TopStateEx env) <- fromStablePtr ctxPtr
82- name <- fromString <$> peekCString namePtr
83- atom <- fromStablePtr atomPtr
84- let freshName = genFresh (Name GenName (fromString name) 0 ) (topBindings $ topStateD env)
85- let newBinding = AtomBinderInfo (getType atom) (LetBound PlainLet (Atom atom))
86- let evaluated = EvaluatedModule (freshName @> newBinding) mempty
87- (SourceMap (M. singleton name (SrcAtomName freshName)))
88- let envNew = extendTopStateD env evaluated
89- toStablePtr $ Context evalConfig $ envNew
74+ Context evalConfig initEnv <- fromStablePtr ctxPtr
75+ sourceName <- peekCString namePtr
76+ AtomEx atom <- fromStablePtr atomPtr
77+ (_, finalEnv) <- runTopperM evalConfig initEnv do
78+ -- TODO: Check if atom is compatible with context! Use module name?
79+ name <- emitTopLet (fromString sourceName) PlainLet $ Atom $ unsafeCoerceE atom
80+ emitSourceMap $ SourceMap $ M. singleton sourceName [ModuleVar Main $ Just $ UAtomVar name]
81+ toStablePtr $ Context evalConfig finalEnv
9082
91- dexEvalExpr :: Ptr Context -> CString -> IO (Ptr Atom )
92- dexEvalExpr ctxPtr sourcePtr = do
93- Context evalConfig env <- fromStablePtr ctxPtr
94- source <- peekCString sourcePtr
95- case S. parseExpr source of
96- Success expr -> do
97- let (v, m) = S. exprAsModule expr
98- let block = S. SourceBlock 0 0 LogNothing source (S. RunModule m) Nothing
99- (Result [] maybeErr, newState) <- runInterblockM evalConfig env $ evalSourceBlock block
100- case maybeErr of
101- Success () -> do
102- let Success (AtomBinderInfo _ (LetBound _ (Atom atom))) =
103- lookupSourceName newState v
104- toStablePtr atom
105- Failure err -> setError (pprint err) $> nullPtr
106- Failure err -> setError (pprint err) $> nullPtr
107-
108- dexLookup :: Ptr Context -> CString -> IO (Ptr Atom )
83+ dexLookup :: Ptr Context -> CString -> IO (Ptr AtomEx )
10984dexLookup ctxPtr namePtr = do
110- Context _ env <- fromStablePtr ctxPtr
85+ Context evalConfig env <- fromStablePtr ctxPtr
11186 name <- peekCString namePtr
112- case lookupSourceName env (fromString name) of
113- Success (AtomBinderInfo _ (LetBound _ (Atom atom))) -> toStablePtr atom
114- Failure _ -> setError " Unbound name" $> nullPtr
115- Success _ -> setError " Looking up an expression" $> nullPtr
87+ fst <$> runTopperM evalConfig env do
88+ lookupSourceMap name >>= \ case
89+ Just (UAtomVar v) -> lookupAtomName v >>= \ case
90+ LetBound (DeclBinding _ _ (Atom atom)) -> liftIO $ toStablePtr $ AtomEx atom
91+ _ -> liftIO $ setError " Looking up an unevaluated atom?" $> nullPtr
92+ Just _ -> liftIO $ setError " Only Atom names can be looked up" $> nullPtr
93+ Nothing -> liftIO $ setError " Unbound name" $> nullPtr
0 commit comments