link,
unload,
PersistentLinkerState{-abstractly!-}, emptyPLS,
- lookupClosure
+ linkExpr
) where
stuff = [ (trees,itbls) | Trees trees itbls <- ul_trees ]
(ibinds, new_itbl_env, new_closure_env) <-
- linkIModules closure_env' itbl_env' stuff
+ linkIModules itbl_env' closure_env' stuff
let new_pls = PersistentLinkerState {
closure_env = new_closure_env,
unload :: PersistentLinkerState -> IO PersistentLinkerState
unload pls = return pls{ closure_env = emptyFM, itbl_env = emptyFM }
-lookupClosure :: RdrName -> PersistentLinkerState -> Maybe HValue
-lookupClosure nm PersistentLinkerState{ closure_env = cenv } =
- case lookupFM cenv nm of
- Nothing -> Nothing
- Just hv -> Just hv
+linkExpr :: PersistentLinkerState -> UnlinkedIExpr -> IO HValue
+linkExpr PersistentLinkerState{ itbl_env = ie, closure_env = ce } expr
+ = iExprToHValue ie ce expr
#endif
\end{code}
\section[CompManager]{The Compilation Manager}
\begin{code}
-module CompManager ( cmInit, cmLoadModule,
+module CompManager ( cmInit, cmLoadModule,
cmGetExpr, cmRunExpr,
- CmState, emptyCmState, -- abstract
- cmLookupSymbol --tmp
+ CmState, emptyCmState -- abstract
)
where
#include "HsVersions.h"
-import List ( nub )
-import Maybe ( catMaybes, fromMaybe )
-import Maybes ( maybeToBool )
-import Outputable
-import UniqFM ( emptyUFM, lookupUFM, addToUFM, delListFromUFM,
- UniqFM, listToUFM )
-import Unique ( Uniquable )
-import Digraph ( SCC(..), stronglyConnComp )
-
import CmLink
import CmTypes
import HscTypes
+import HscMain ( hscExpr )
import Interpreter ( HValue )
import Module ( ModuleName, moduleName,
isModuleInThisPackage, moduleEnvElts,
import PrelNames ( mainName )
import HscMain ( initPersistentCompilerState )
import Finder ( findModule, emptyHomeDirCache )
+import UniqFM ( emptyUFM, lookupUFM, addToUFM, delListFromUFM,
+ UniqFM, listToUFM )
+import Unique ( Uniquable )
+import Digraph ( SCC(..), stronglyConnComp )
import DriverUtil ( BarfKind(..), splitFilename3 )
+import CmdLineOpts ( DynFlags )
import Util
+import Outputable
import Panic ( panic )
+-- lang
import Exception ( throwDyn )
-import IO
+
+-- std
import Time ( ClockTime )
import Directory ( getModificationTime, doesFileExist )
+import IO
+import List ( nub )
+import Maybe ( catMaybes, fromMaybe, isJust )
+import PrelGHC ( unsafeCoerce# )
\end{code}
-
\begin{code}
cmInit :: PackageConfigInfo -> GhciMode -> IO CmState
cmInit raw_package_info gmode
= emptyCmState raw_package_info gmode
cmGetExpr :: CmState
+ -> DynFlags
-> ModuleName
-> String
- -> IO (CmState, Either [SDoc] HValue)
-cmGetExpr cmstate modhdl expr
- = return (panic "cmGetExpr:unimp")
+ -> IO (CmState, Maybe HValue)
+cmGetExpr cmstate dflags modname expr
+ = do (new_pcs, maybe_unlinked_iexpr) <-
+ hscExpr dflags hst hit pcs (mkModuleInThisPackage modname) expr
+ case maybe_unlinked_iexpr of
+ Nothing -> return (cmstate{ pcs=new_pcs }, Nothing)
+ Just uiexpr -> do
+ hValue <- linkExpr pls uiexpr
+ return (cmstate{ pcs=new_pcs }, Just hValue)
+
+ -- ToDo: check that the module we passed in is sane/exists?
+ where
+ CmState{ pcs=pcs, pcms=pcms, pls=pls } = cmstate
+ PersistentCMState{ hst=hst, hit=hit } = pcms
+-- The HValue should represent a value of type IO () (Perhaps IO a?)
cmRunExpr :: HValue -> IO ()
cmRunExpr hval
- = return (panic "cmRunExpr:unimp")
-
+ = do unsafeCoerce# hval :: IO ()
+ -- putStrLn "done."
-- Persistent state just for CM, excluding link & compile subsystems
data PersistentCMState
-- Does this ModDetails export Main.main?
exports_main :: ModDetails -> Bool
exports_main md
- = maybeToBool (lookupNameEnv (md_types md) mainName)
+ = isJust (lookupNameEnv (md_types md) mainName)
-- Add the given (LM-form) Linkables to the UI, overwriting previous
return (Just time))
`catch`
(\err -> return Nothing)
-
-cmLookupSymbol :: RdrName -> CmState -> Maybe HValue
-cmLookupSymbol nm CmState{ pls = pls } = lookupClosure nm pls
\end{code}
-----------------------------------------------------------------------------
--- $Id: InteractiveUI.hs,v 1.3 2000/11/16 16:54:36 simonmar Exp $
+-- $Id: InteractiveUI.hs,v 1.4 2000/11/17 16:53:27 simonmar Exp $
--
-- GHC Interactive User Interface
--
import CompManager
import CmStaticInfo
+import DriverFlags
import DriverUtil
import DriverState
import Linker
import Module
-import RdrName -- tmp
-import OccName -- tmp
import Panic
import Util
import IO
import Char
-import PrelGHC ( unsafeCoerce# )
-
-----------------------------------------------------------------------------
ghciWelcomeMsg = "\
#ifndef NO_READLINE
Readline.initialize
#endif
- _ <- (unGHCi uiLoop) GHCiState{ current_module = mkModuleName "Prelude",
+ _ <- (unGHCi uiLoop) GHCiState{ current_module = mkModuleName "Main",
target = Nothing,
cmstate = st }
return ()
runCommand l
uiLoop
+-- Top level exception handler, just prints out the exception and carries on.
runCommand c =
- myCatchDyn (doCommand c)
+ ghciHandle ( \other_exception ->io (putStrLn (show other_exception) )) $
+ ghciHandleDyn
(\dyn -> case dyn of
PhaseFailed phase code ->
io ( putStrLn ("Phase " ++ phase ++ " failed (code "
++ show code ++ ")"))
Interrupted -> io (putStrLn "Interrupted.")
_ -> io (putStrLn (show (dyn :: BarfKind)))
- )
+ ) $
+ doCommand c
doCommand (':' : command) = specialCommand command
doCommand expr = do
st <- getGHCiState
- io (hPutStrLn stdout ("Run expression: " ++ expr))
+ dflags <- io (readIORef v_DynFlags)
+ (st, maybe_hvalue) <-
+ io (cmGetExpr (cmstate st) dflags (current_module st) expr)
+ case maybe_hvalue of
+ Nothing -> return ()
+ Just hv -> io (cmRunExpr hv)
+{-
let (mod,'.':str) = break (=='.') expr
case cmLookupSymbol (mkOrig varName (mkModuleName mod) (_PK_ str)) (cmstate st) of
Nothing -> io (putStrLn "nothing.")
- Just e -> io (do unsafeCoerce# e :: IO ()
- putStrLn "done.")
+ Just e -> io (
return ()
+-}
specialCommand str = do
let (cmd,rest) = break isSpace str
-----------------------------------------------------------------------------
-- Commands
--- ToDo: don't forget to catch errors
-
help :: String -> GHCi ()
help _ = io (putStr helpText)
loadModule :: String -> GHCi ()
loadModule path = do
state <- getGHCiState
- (new_cmstate, mod) <- io (cmLoadModule (cmstate state) ({-ToDo!!-}mkModuleName path))
- setGHCiState state{cmstate=new_cmstate, target=Just path}
+ (new_cmstate, mod) <- io (cmLoadModule (cmstate state)
+ ({-ToDo!!-}mkModuleName path))
+ let new_state = GHCiState {
+ cmstate = new_cmstate,
+ current_module = case mod of
+ Nothing -> current_module state
+ Just m -> m,
+ target = Just path
+ }
+ setGHCiState new_state
reloadModule :: String -> GHCi ()
reloadModule "" = do
setGHCiState state{cmstate=new_cmstate}
reloadModule _ = noArgs ":reload"
+-- set options in the interpreter. Syntax is exactly the same as the
+-- ghc command line, except that certain options aren't available (-C,
+-- -E etc.)
+--
+-- This is pretty fragile: most options won't work as expected. ToDo:
+-- figure out which ones & disallow them.
setOptions :: String -> GHCi ()
-setOptions = panic "setOptions"
+setOptions str =
+ io (do leftovers <- processArgs static_flags (words str) []
+ dyn_flags <- readIORef v_InitDynFlags
+ writeIORef v_DynFlags dyn_flags
+ leftovers <- processArgs dynamic_flags leftovers []
+ dyn_flags <- readIORef v_DynFlags
+ writeIORef v_InitDynFlags dyn_flags
+ if (not (null leftovers))
+ then throwDyn (OtherError ("unrecognised flags: " ++
+ unwords leftovers))
+ else return ()
+ )
typeOfExpr :: String -> GHCi ()
typeOfExpr = panic "typeOfExpr"
io m = GHCi $ \s -> m >>= \a -> return (s,a)
-myCatch (GHCi m) h = GHCi $ \s ->
+ghciHandle h (GHCi m) = GHCi $ \s ->
Exception.catch (m s) (\e -> unGHCi (h e) s)
-myCatchDyn (GHCi m) h = GHCi $ \s ->
+ghciHandleDyn h (GHCi m) = GHCi $ \s ->
Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
-----------------------------------------------------------------------------
let path = d ++ '/':obj
b <- doesFileExist path
if b then return path else findFile ds obj
-
-
\begin{code}
module StgInterp (
- ClosureEnv, ItblEnv, filterRdrNameEnv,
- linkIModules,
- stgToInterpSyn,
+
+ ClosureEnv, ItblEnv,
+ filterRdrNameEnv, -- :: [ModuleName] -> FiniteMap RdrName a
+ -- -> FiniteMap RdrName a
+
+ linkIModules, -- :: ItblEnv -> ClosureEnv
+ -- -> [([UnlinkedIBind], ItblEnv)]
+ -- -> IO ([LinkedIBind], ItblEnv, ClosureEnv)
+
+ iExprToHValue, -- :: ItblEnv -> ClosureEnv
+ -- -> UnlinkedIExpr -> HValue
+
+ stgBindsToInterpSyn,-- :: [StgBinding]
+ -- -> [TyCon] -> [Class]
+ -- -> IO ([UnlinkedIBind], ItblEnv)
+
+ stgExprToInterpSyn, -- :: StgExpr
+ -- -> IO UnlinkedIExpr
+
+ interp -- :: LinkedIExpr -> HValue
) where
{- -----------------------------------------------------------------------------
import FiniteMap
import Panic ( panic )
import OccName ( occNameString )
+import ErrUtils ( showPass )
+import CmdLineOpts ( DynFlags )
import Foreign
import CTypes
+import IO
-- ---------------------------------------------------------------------------
-- Environments needed by the linker
= filterFM (\n _ -> rdrNameModule n `notElem` mods) env
-- ---------------------------------------------------------------------------
--- Run our STG program through the interpreter
+-- Turn an UnlinkedIExpr into a value we can run, for the interpreter
-- ---------------------------------------------------------------------------
-#if 0
--- To be nuked at some point soon.
-runStgI :: [TyCon] -> [Class] -> [StgBinding] -> IO Int
-
--- the bindings need to have a binding for stgMain, and the
--- body of it had better represent something of type Int# -> Int#
-runStgI tycons classes stgbinds
- = do
- let unlinked_binds = concatMap (translateBind emptyUniqSet) stgbinds
-
-{-
- let dbg_txt
- = "-------------------- Unlinked Binds --------------------\n"
- ++ showSDoc (vcat (map (\bind -> pprIBind bind $$ char ' ')
- unlinked_binds))
-
- hPutStr stderr dbg_txt
--}
- (linked_binds, ie, ce) <-
- linkIModules emptyFM emptyFM [(tycons,unlinked_binds)]
-
- let dbg_txt
- = "-------------------- Linked Binds --------------------\n"
- ++ showSDoc (vcat (map (\bind -> pprIBind bind $$ char ' ')
- linked_binds))
-
- hPutStr stderr dbg_txt
-
- let stgMain
- = case [rhs | IBind v rhs <- linked_binds, showSDoc (ppr v) == "stgMain"] of
- (b:_) -> b
- [] -> error "\n\nCan't find `stgMain'. Giving up.\n\n"
-
- let result
- = I# (evalI (AppII stgMain (LitI 0#))
- emptyUFM{-initial de-}
- )
- return result
-#endif
+iExprToHValue :: ItblEnv -> ClosureEnv -> UnlinkedIExpr -> IO HValue
+iExprToHValue ie ce expr = return (interp (linkIExpr ie ce expr))
-- ---------------------------------------------------------------------------
-- Convert STG to an unlinked interpretable
-- ---------------------------------------------------------------------------
-- visible from outside
-stgToInterpSyn :: [StgBinding]
- -> [TyCon] -> [Class]
- -> IO ([UnlinkedIBind], ItblEnv)
-stgToInterpSyn binds local_tycons local_classes
- = do let ibinds = concatMap (translateBind emptyUniqSet) binds
+stgBindsToInterpSyn :: DynFlags
+ -> [StgBinding]
+ -> [TyCon] -> [Class]
+ -> IO ([UnlinkedIBind], ItblEnv)
+stgBindsToInterpSyn dflags binds local_tycons local_classes
+ = do showPass dflags "StgToInterp"
+ let ibinds = concatMap (translateBind emptyUniqSet) binds
let tycs = local_tycons ++ map classTyCon local_classes
itblenv <- mkITbls tycs
return (ibinds, itblenv)
+stgExprToInterpSyn :: DynFlags
+ -> StgExpr
+ -> IO UnlinkedIExpr
+stgExprToInterpSyn dflags expr
+ = do showPass dflags "StgToInterp"
+ return (stg2expr emptyUniqSet expr)
translateBind :: UniqSet Id -> StgBinding -> [UnlinkedIBind]
translateBind ie (StgNonRec v e) = [IBind v (rhs2expr ie e)]
ArrayRep -> RepP
ByteArrayRep -> RepP
+ FloatRep -> RepF
+ DoubleRep -> RepD
+
other -> pprPanic "primRep2Rep" (ppr other)
repOfStgExpr :: StgExpr -> Rep
-- Addr#. So, copy the string into C land and introduce a
-- memory leak at the same time.
let n = I# l in
- case unsafePerformIO (do a <- mallocBytes (n+1);
- strncpy a ba (fromIntegral n);
- pokeByteOff a n '\0'
- case a of { Ptr a -> return a })
+ -- CAREFUL! Chars are 32 bits in ghc 4.09+
+ case unsafePerformIO (do a@(Ptr addr) <- mallocBytes (n+1)
+ strncpy a ba (fromIntegral n)
+ writeCharOffAddr addr n '\0'
+ return addr)
of A# a -> LitI (addr2Int# a)
_ -> error "StgInterp.lit2expr: unhandled string constant type"
(translateBind ie binds)
(stg2expr (addListToUniqSet ie (map fst bs)) body)
- other
+ -- treat let-no-escape just like let.
+ StgLetNoEscape _ _ binds body
+ -> stg2expr ie (StgLet binds body)
+
+ other
-> pprPanic "stg2expr" (ppr stgexpr)
where
doPrimAlt (lit,rhs)
-- any var that isn't in scope is turned into a Native
mkVar ie rep var
- | var `elementOfUniqSet` ie = case rep of { RepI -> VarI; RepP -> VarP } $ var
+ | var `elementOfUniqSet` ie =
+ (case rep of
+ RepI -> VarI
+ RepF -> VarF
+ RepD -> VarD
+ RepP -> VarP) var
| otherwise = Native (toRdrName var)
mkRec RepI = RecI
-- Link interpretables into something we can run
-- ---------------------------------------------------------------------------
-linkIModules :: ClosureEnv -- incoming global closure env; returned updated
- -> ItblEnv -- incoming global itbl env; returned updated
+linkIModules :: ItblEnv -- incoming global itbl env; returned updated
+ -> ClosureEnv -- incoming global closure env; returned updated
-> [([UnlinkedIBind], ItblEnv)]
-> IO ([LinkedIBind], ItblEnv, ClosureEnv)
-linkIModules gce gie mods = do
+linkIModules gie gce mods = do
let (bindss, ies) = unzip mods
binds = concat bindss
top_level_binders = map (toRdrName.binder) binds
linkIBind ie ce (IBind bndr expr) = IBind bndr (linkIExpr ie ce expr)
+linkIExpr :: ItblEnv -> ClosureEnv -> UnlinkedIExpr -> LinkedIExpr
linkIExpr ie ce expr = case expr of
CaseAlgP bndr expr alts dflt ->
-- Evaluator for things of boxed (pointer) representation
-- ---------------------------------------------------------------------------
+interp :: LinkedIExpr -> HValue
+interp iexpr = unsafeCoerce# (evalP iexpr emptyUFM)
+
evalP :: LinkedIExpr -> UniqFM boxed -> boxed
{-
-- Evaluate something which has an unboxed Int rep
evalI :: LinkedIExpr -> UniqFM boxed -> Int#
+{-
evalI expr de
-- | trace ("evalI: " ++ showExprTag expr) False
| trace ("evalI:\n" ++ showSDoc (pprIExpr expr) ++ "\n") False
= error "evalI: ?!?!"
+-}
evalI (LitI i#) de = i#
-- Evaluate something which has an unboxed Int rep
evalF :: LinkedIExpr -> UniqFM boxed -> Float#
+{-
evalF expr de
-- | trace ("evalF: " ++ showExprTag expr) False
| trace ("evalF:\n" ++ showSDoc (pprIExpr expr) ++ "\n") False
= error "evalF: ?!?!"
+-}
evalF (LitF f#) de = f#
-- Evaluate something which has an unboxed Int rep
evalD :: LinkedIExpr -> UniqFM boxed -> Double#
+{-
evalD expr de
-- | trace ("evalD: " ++ showExprTag expr) False
| trace ("evalD:\n" ++ showSDoc (pprIExpr expr) ++ "\n") False
= error "evalD: ?!?!"
+-}
evalD (LitD d#) de = d#
\section[GHC_Main]{Main driver for Glasgow Haskell compiler}
\begin{code}
-module HscMain ( HscResult(..), hscMain,
+module HscMain ( HscResult(..), hscMain, hscExpr,
initPersistentCompilerState ) where
#include "HsVersions.h"
import IO ( hPutStrLn, stderr )
import HsSyn
-import StringBuffer ( hGetStringBuffer )
+import StringBuffer ( hGetStringBuffer,
+ stringToStringBuffer, freeStringBuffer )
import Parser
+import RdrHsSyn ( RdrNameHsExpr )
import Lex ( PState(..), ParseResult(..) )
import SrcLoc ( mkSrcLoc )
-import Rename ( renameModule, checkOldIface, closeIfaceDecls )
+import Rename
import Rules ( emptyRuleBase )
import PrelInfo ( wiredInThingEnv, wiredInThings )
import PrelNames ( knownKeyNames )
import MkIface ( completeIface, mkModDetailsFromIface, mkModDetails,
writeIface, pprIface )
-import TcModule ( TcResults(..), typecheckModule )
+import TcModule
import InstEnv ( emptyInstEnv )
-import Desugar ( deSugar )
-import SimplCore ( core2core )
+import Desugar
+import SimplCore
import OccurAnal ( occurAnalyseBinds )
import CoreUtils ( coreBindsSize )
import CoreTidy ( tidyCorePgm )
-import CoreToStg ( topCoreBindsToStg )
+import CoreToStg ( topCoreBindsToStg, coreToStgExpr )
import StgSyn ( collectFinalStgBinders )
import SimplStg ( stg2stg )
import CodeGen ( codeGen )
import Bag ( emptyBag )
import Outputable
-import Interpreter ( UnlinkedIBind, ItblEnv, stgToInterpSyn )
+import Interpreter
import CmStaticInfo ( GhciMode(..) )
import HscStats ( ppSourceStats )
import HscTypes ( ModDetails, ModIface(..), PersistentCompilerState(..),
hscMain ghci_mode dflags source_unchanged location maybe_old_iface hst hit pcs
= do {
- putStrLn ("CHECKING OLD IFACE for hs = " ++ show (ml_hs_file location)
- ++ ", hspp = " ++ show (ml_hspp_file location));
+ showPass dflags ("Checking old interface for hs = "
+ ++ show (ml_hs_file location)
+ ++ ", hspp = " ++ show (ml_hspp_file location));
(pcs_ch, errs_found, (recomp_reqd, maybe_checked_iface))
- <- checkOldIface dflags hit hst pcs (unJust (ml_hi_file location) "hscMain")
- source_unchanged maybe_old_iface;
+ <- checkOldIface dflags hit hst pcs
+ (unJust (ml_hi_file location) "hscMain")
+ source_unchanged maybe_old_iface;
if errs_found then
return (HscFail pcs_ch)
-------------------
-- RENAME
-------------------
+ ; showPass dflags "Rename"
; (pcs_rn, maybe_rn_result)
<- renameModule dflags hit hst pcs_ch this_mod rdr_module
; case maybe_rn_result of {
-------------------
-- TYPECHECK
-------------------
+ ; showPass dflags "Typecheck"
; maybe_tc_result <- typecheckModule dflags pcs_rn hst new_iface
print_unqualified rn_hs_decls
; case maybe_tc_result of {
hit pit -- these last two for mapping ModNames to Modules
| toInterp
= do (ibinds,itbl_env)
- <- stgToInterpSyn (map fst stg_binds) local_tycons local_classes
+ <- stgBindsToInterpSyn dflags (map fst stg_binds)
+ local_tycons local_classes
return (Nothing, Nothing, Just (ibinds,itbl_env))
| otherwise
dsThenSimplThenTidy dflags pcs hst this_mod print_unqual is_exported tc_result
= do -------------------------- Desugaring ----------------
+ showPass dflags "DeSugar"
-- _scc_ "DeSugar"
(desugared, rules, h_code, c_code, fe_binders)
<- deSugar dflags pcs hst this_mod print_unqual tc_result
<- core2core dflags pcs hst is_exported desugared rules
-- Do the final tidy-up
+ showPass dflags "TidyCore"
(tidy_binds, tidy_orphan_rules)
<- tidyCorePgm dflags this_mod simplified orphan_rules
myCoreToStg dflags this_mod tidy_binds
= do
- c2s_uniqs <- mkSplitUniqSupply 'c'
st_uniqs <- mkSplitUniqSupply 'g'
let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds
-- simplifier, which for reasons I don't understand, persists
-- thoroughout code generation
- showPass dflags "Core2Stg"
-- _scc_ "Core2Stg"
- let stg_binds = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds
+ stg_binds <- topCoreBindsToStg dflags occ_anal_tidy_binds
showPass dflags "Stg2Stg"
-- _scc_ "Stg2Stg"
%* *
%************************************************************************
+\begin{code}
hscExpr
:: DynFlags
-> HomeSymbolTable
-> PersistentCompilerState -- IN: persistent compiler state
-> Module -- Context for compiling
-> String -- The expression
- -> IO HscResult
+ -> IO ( PersistentCompilerState, Maybe UnlinkedIExpr )
-hscExpr dflags hst hit pcs this_module expr
+hscExpr dflags hst hit pcs0 this_module expr
= do { -- Parse it
- maybe_parsed <- myParseExpr dflags expr
- ; case maybe_parsed of {
- Nothing -> return (HscFail pcs_ch);
+ maybe_parsed <- hscParseExpr dflags expr;
+ case maybe_parsed of
+ Nothing -> return (pcs0, Nothing)
Just parsed_expr -> do {
-- Rename it
- (new_pcs, maybe_renamed_expr) <- renameExpr dflags hit hst pcs this_module parsed_expr ;
- ; case maybe_renamed_expr of {
- Nothing -> FAIL
- Just (print_unqual, rn_expr) ->
+ (pcs1, maybe_renamed_expr) <-
+ renameExpr dflags hit hst pcs0 this_module parsed_expr;
+ case maybe_renamed_expr of
+ Nothing -> return (pcs1, Nothing)
+ Just (print_unqual, rn_expr) -> do {
-- Typecheck it
- maybe_tc_expr <- typecheckExpr dflags pcs hst print_unqual rn_expr
- ; case maybe_tc_expr of
- Nothing -> FAIL
- Just tc_expr ->
+ maybe_tc_expr <- typecheckExpr dflags pcs1 hst print_unqual rn_expr;
+ case maybe_tc_expr of
+ Nothing -> return (pcs1, Nothing)
+ Just tc_expr -> do {
-- Desugar it
- ; ds_expr <- deSugarExpr dflags pcs hst this_module print_unqual tc_expr
+ ds_expr <- deSugarExpr dflags pcs1 hst this_module
+ print_unqual tc_expr;
-- Simplify it
- ; simpl_expr <- simplifyExpr dflags pcs hst ds_expr
+ simpl_expr <- simplifyExpr dflags pcs1 hst ds_expr;
- ; return I'M NOT SURE
- }
+ -- Convert to STG
+ stg_expr <- coreToStgExpr dflags simpl_expr;
-
+ -- ToDo: need to do StgVarInfo? or SRTs?
+
+ -- Convert to InterpSyn
+ unlinked_iexpr <- stgExprToInterpSyn dflags stg_expr;
+
+ return (pcs1, Just unlinked_iexpr);
+ }}}}
+
+hscParseExpr :: DynFlags -> String -> IO (Maybe RdrNameHsExpr)
+hscParseExpr dflags str
+ = do -------------------------- Parser ----------------
+ showPass dflags "Parser"
+ -- _scc_ "Parser"
+ buf <- stringToStringBuffer ("__expr " ++ str)
+
+ -- glaexts is True for now (because of the daft __expr at the front
+ -- of the string...)
+ let glaexts = 1#
+ --let glaexts | dopt Opt_GlasgowExts dflags = 1#
+ -- | otherwise = 0#
+
+ case parse buf PState{ bol = 0#, atbol = 1#,
+ context = [], glasgow_exts = glaexts,
+ loc = mkSrcLoc SLIT("<no file>") 0 } of {
+
+ PFailed err -> do { freeStringBuffer buf
+ ; hPutStrLn stderr (showSDoc err)
+ ; return Nothing };
+
+ POk _ (PExpr rdr_expr) -> do {
+
+ -- ToDo:
+ -- freeStringBuffer buf;
+
+ dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser" (ppr rdr_expr);
+
+ return (Just rdr_expr)
+ }}
+\end{code}
%************************************************************************
%* *
-----------------------------------------------------------------------------
--- $Id: Interpreter.hs,v 1.4 2000/11/16 15:57:05 simonmar Exp $
+-- $Id: Interpreter.hs,v 1.5 2000/11/17 16:53:27 simonmar Exp $
--
-- Interpreter subsystem wrapper
--
linkIModules,
stgToInterpSyn,
HValue,
- UnlinkedIBind,
+ UnlinkedIBind, UnlinkedIExpr,
loadObjs, resolveObjs,
#endif
) where
type HValue = ()
data UnlinkedIBind = UnlinkedIBind
+data UnlinkedIBind = UnlinkedIExpr
instance Outputable UnlinkedIBind where
ppr x = text "Can't output UnlinkedIBind"
{-# OPTIONS -W -fno-warn-incomplete-patterns #-}
-----------------------------------------------------------------------------
--- $Id: Main.hs,v 1.24 2000/11/16 15:57:06 simonmar Exp $
+-- $Id: Main.hs,v 1.25 2000/11/17 16:53:27 simonmar Exp $
--
-- GHC Driver program
--
-- reading the package configuration file is too slow
-- -H, -K, -Rghc-timing
-- hi-diffs
+-- -ddump-all doesn't do anything
-----------------------------------------------------------------------------
-- Differences vs. old driver:
; renameSource dflags hit hst pcs this_module $
initRnMS rdr_env emptyLocalFixityEnv SourceMode $
- (rnExpr expr `thenRn` \ (e,_) -> returnRn (Just (print_unqual, e)))
+ ( rnExpr expr `thenRn` \ (e,_) ->
+
+ doptRn Opt_D_dump_rn `thenRn` \ dump_rn ->
+ ioToRnM (dumpIfSet dump_rn "Renamer:" (ppr e)) `thenRn_`
+
+ returnRn (Just (print_unqual, e)))
}
| otherwise
return (processed_binds, orphan_rules)
-simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
+simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
-> PersistentCompilerState
-> HomeSymbolTable
-> CoreExpr
-> IO CoreExpr
simplifyExpr dflags pcs hst expr
= do {
+ ; showPass dflags "Simplify"
+
; us <- mkSplitUniqSupply 's'
; let (expr', counts) = initSmpl dflags sw_chkr us emptyVarSet black_list_all
Convert a @CoreSyntax@ program to a @StgSyntax@ program.
\begin{code}
-module CoreToStg ( topCoreBindsToStg ) where
+module CoreToStg ( topCoreBindsToStg, coreToStgExpr ) where
#include "HsVersions.h"
import UniqSupply -- all of it, really
import BasicTypes ( TopLevelFlag(..), isNotTopLevel )
import UniqSet ( emptyUniqSet )
+import ErrUtils ( showPass )
+import CmdLineOpts ( DynFlags )
import Maybes
import Outputable
\end{code}
\end{code}
\begin{code}
-topCoreBindsToStg :: UniqSupply -- name supply
- -> [CoreBind] -- input
- -> [StgBinding] -- output
-
-topCoreBindsToStg us core_binds
- = initUs_ us (coreBindsToStg emptyVarEnv core_binds)
+topCoreBindsToStg :: DynFlags -> [CoreBind] -> IO [StgBinding]
+topCoreBindsToStg dflags core_binds
+ = do showPass dflags "Core2Stg"
+ us <- mkSplitUniqSupply 'c'
+ return (initUs_ us (coreBindsToStg emptyVarEnv core_binds))
where
coreBindsToStg :: StgEnv -> [CoreBind] -> UniqSM [StgBinding]
returnUs new_bs
\end{code}
+%************************************************************************
+%* *
+\subsection[coreToStgExpr]{Converting an expression (for the interpreter)}
+%* *
+%************************************************************************
+
+\begin{code}
+coreToStgExpr :: DynFlags -> CoreExpr -> IO StgExpr
+coreToStgExpr dflags core_expr
+ = do showPass dflags "Core2Stg"
+ us <- mkSplitUniqSupply 'c'
+ return (initUs_ us (coreExprToStg emptyVarEnv core_expr))
+\end{code}
%************************************************************************
%* *
(
StringBuffer,
- -- creation
- hGetStringBuffer, -- :: FilePath -> IO StringBuffer
+ -- creation/destruction
+ hGetStringBuffer, -- :: FilePath -> IO StringBuffer
+ stringToStringBuffer, -- :: String -> IO StringBuffer
+ freeStringBuffer, -- :: StringBuffer -> IO ()
-- Lookup
currentChar, -- :: StringBuffer -> Char
\end{code}
-----------------------------------------------------------------------------
+-- Turn a String into a StringBuffer
+
+\begin{code}
+stringToStringBuffer :: String -> IO StringBuffer
+stringToStringBuffer str =
+ do let sz@(I# sz#) = length str + 1
+ (Ptr a@(A# a#)) <- mallocBytes sz
+ fill_in str a
+ writeCharOffAddr a (sz-1) '\0' -- sentinel
+ return (StringBuffer a# sz# 0# 0#)
+ where
+ fill_in [] _ = return ()
+ fill_in (c:cs) a = do
+ writeCharOffAddr a 0 c
+ fill_in cs (a `plusAddr` 1)
+
+freeStringBuffer :: StringBuffer -> IO ()
+freeStringBuffer (StringBuffer a# _ _ _) = Foreign.free (Ptr (A# a#))
+\end{code}
+
+-----------------------------------------------------------------------------
This very disturbing bit of code is used for expanding the tabs in a
file before we start parsing it. Expanding the tabs early makes the
lexer a lot simpler: we only have to record the beginning of the line