1
1
mirror of https://github.com/anoma/juvix.git synced 2024-11-13 07:23:12 +03:00

Do not filter unreachable symbols when compiling for REPL (#2172)

Say we have a module that import/open the Prelude:

Test.juvix
```
module Test;
import Stdlib.Prelude open;
```

When the module is compiled, we have a step in the compiler pipeline
which filters out unreachable symbols. For this module all symbols are
filtered because the module contains no definitions.

So if the module is loaded in the REPL, no symbols will be available to
process through the evaluator. The REPL is a place to explore the
symbols in the module so (like with Haskell's GHCi) it would be useful
if all symbols were available in the REPL session. That's what this PR
implements.

* Closes https://github.com/anoma/juvix/issues/2159

---------

Co-authored-by: Jan Mas Rovira <janmasrovira@gmail.com>
This commit is contained in:
Paul Cadman 2023-06-05 16:52:52 +01:00 committed by GitHub
parent 68b4b38f98
commit 108ccf7dcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 18 deletions

View File

@ -122,7 +122,7 @@ pSomeFile = mkPrepath
loadFile :: Prepath File -> Repl ()
loadFile f = do
entryPoint <- getReplEntryPoint f
entryPoint <- getReplEntryPointFromPrepath f
loadEntryPoint entryPoint
loadDefaultPrelude :: Repl ()
@ -140,11 +140,17 @@ loadDefaultPrelude = whenJustM defaultPreludeEntryPoint $ \e -> do
$ entrySetup
loadEntryPoint e
getReplEntryPoint :: Prepath File -> Repl EntryPoint
getReplEntryPoint inputFile = do
getReplEntryPoint :: (Roots -> a -> GlobalOptions -> IO EntryPoint) -> a -> Repl EntryPoint
getReplEntryPoint f inputFile = do
roots <- Reader.asks (^. replRoots)
gopts <- State.gets (^. replStateGlobalOptions)
liftIO (entryPointFromGlobalOptionsPre roots inputFile gopts)
liftIO (set entryPointSymbolPruningMode KeepAll <$> f roots inputFile gopts)
getReplEntryPointFromPrepath :: Prepath File -> Repl EntryPoint
getReplEntryPointFromPrepath = getReplEntryPoint entryPointFromGlobalOptionsPre
getReplEntryPointFromPath :: Path Abs File -> Repl EntryPoint
getReplEntryPointFromPath = getReplEntryPoint entryPointFromGlobalOptions
displayVersion :: String -> Repl ()
displayVersion _ = liftIO (putStrLn versionTag)
@ -169,7 +175,7 @@ replCommand opts input = catchAll $ do
eval :: Core.Node -> Repl Core.Node
eval n = do
ep <- getReplEntryPoint (mkPrepath (toFilePath replPath))
ep <- getReplEntryPointFromPrepath (mkPrepath (toFilePath replPath))
let shouldDisambiguate :: Bool
shouldDisambiguate = not (opts ^. replNoDisambiguate)
(artif', n') <-
@ -472,7 +478,6 @@ runCommand opts = do
-- | If the package contains the stdlib as a dependency, loads the Prelude
defaultPreludeEntryPoint :: Repl (Maybe EntryPoint)
defaultPreludeEntryPoint = do
opts <- State.gets (^. replStateGlobalOptions)
roots <- State.gets (^. replStateRoots)
let buildDir = roots ^. rootsBuildDir
root = roots ^. rootsRootDir
@ -481,7 +486,7 @@ defaultPreludeEntryPoint = do
case mstdlibPath of
Just stdlibPath ->
Just . set entryPointResolverRoot stdlibPath
<$> liftIO (entryPointFromGlobalOptions roots (stdlibPath <//> preludePath) opts)
<$> getReplEntryPointFromPath (stdlibPath <//> preludePath)
Nothing -> return Nothing
replMakeAbsolute :: SomeBase b -> Repl (Path Abs b)

View File

@ -5,10 +5,14 @@ import Juvix.Compiler.Internal.Language
import Juvix.Compiler.Internal.Translation.FromAbstract.Data.Context
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.ArityChecking qualified as Arity
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context qualified as Typed
import Juvix.Compiler.Pipeline.EntryPoint
import Juvix.Prelude
filterUnreachable :: Typed.InternalTypedResult -> Typed.InternalTypedResult
filterUnreachable r = r {Typed._resultModules = modules'}
filterUnreachable :: Members '[Reader EntryPoint] r => Typed.InternalTypedResult -> Sem r Typed.InternalTypedResult
filterUnreachable r = do
asks (^. entryPointSymbolPruningMode) >>= \case
KeepAll -> return r
FilterUnreachable -> return (set Typed.resultModules modules' r)
where
depInfo = r ^. (Typed.resultInternalArityResult . Arity.resultInternalResult . resultDepInfo)
modules = r ^. Typed.resultModules

View File

@ -81,13 +81,12 @@ upToInternalReachability ::
(Members '[HighlightBuilder, Reader EntryPoint, Files, NameIdGen, Error JuvixError, Builtins, PathResolver] r) =>
Sem r Internal.InternalTypedResult
upToInternalReachability =
Internal.filterUnreachable <$> upToInternalTyped
upToInternalTyped >>= Internal.filterUnreachable
upToCore ::
Members '[HighlightBuilder, Reader EntryPoint, Files, NameIdGen, Error JuvixError, Builtins, PathResolver] r =>
Sem r Core.CoreResult
upToCore =
upToInternalReachability >>= Core.fromInternal
upToCore = upToInternalReachability >>= Core.fromInternal
upToAsm ::
(Members '[HighlightBuilder, Reader EntryPoint, Files, NameIdGen, Error JuvixError, Builtins, PathResolver] r) =>

View File

@ -10,6 +10,12 @@ import Juvix.Compiler.Pipeline.Root
import Juvix.Extra.Paths
import Juvix.Prelude
-- | An option specifiying how symbols should be pruned in the Internal to Core translation
data SymbolPruningMode
= FilterUnreachable
| KeepAll
deriving stock (Eq, Show)
-- | The head of _entryModulePaths is assumed to be the Main module
data EntryPoint = EntryPoint
{ _entryPointRoot :: Path Abs Dir,
@ -30,7 +36,8 @@ data EntryPoint = EntryPoint
_entryPointOptimizationLevel :: Int,
_entryPointInliningDepth :: Int,
_entryPointGenericOptions :: GenericOptions,
_entryPointModulePaths :: [Path Abs File]
_entryPointModulePaths :: [Path Abs File],
_entryPointSymbolPruningMode :: SymbolPruningMode
}
deriving stock (Eq, Show)
@ -73,7 +80,8 @@ defaultEntryPointNoFile roots =
_entryPointUnrollLimit = defaultUnrollLimit,
_entryPointOptimizationLevel = defaultOptimizationLevel,
_entryPointInliningDepth = defaultInliningDepth,
_entryPointModulePaths = []
_entryPointModulePaths = [],
_entryPointSymbolPruningMode = FilterUnreachable
}
defaultUnrollLimit :: Int

View File

@ -469,3 +469,19 @@ tests:
stdout:
contains: "(::) :: nil"
exit-status: 0
- name: repl-no-filter-unreachable
command:
shell:
- bash
script: |
temp=$(mktemp -d)
trap 'rm -rf -- "$temp"' EXIT
cd $temp
echo "module Test;import Stdlib.Prelude open" > Test.juvix
touch juvix.yaml
juvix repl Test.juvix
stdin: "suc 99"
stdout:
contains: "100"
exit-status: 0

View File

@ -46,10 +46,11 @@ tests:
- name: cli-cmd-doctor-verbose-system
command:
- juvix
- doctor
- --verbose
- --offline
shell:
- bash
script: |
unset JUVIX_LLVM_DIST_PATH
juvix doctor --verbose --offline
exit-status: 0
stdout:
matches: