Я пытаюсь извлечь STG-представление источника Haskell как String
через Outputable
, но похоже, что coreToStgArgs
запаниковал следующим дампом:
user@machine ~/Desktop/hue $ runhaskell test.hs
[foo :: forall a. Num a => a -> a
[GblId, Arity=2, Caf=NoCafRefs, Str=DmdType] =
\r srt:SRT:[] [$dNum a1] + $dNum a1 a1;,
bar :: Int -> Int
[GblId,test.hs: test.hs: panic! (the 'impossible' happened)
(GHC version 7.10.3 for x86_64-unknown-linux):
coreToStgArgs I# 3
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Вот файл FooBar.hs
, который я хочу извлечь:
module FooBar where
foo a = a + a
bar :: Int -> Int
bar b = b + 3
Вот источник test.hs
, который я использовал:
import CoreToStg
import GHC
import GHC.Paths
import Outputable
import StgSyn
mkDynFlags :: IO DynFlags
mkDynFlags = runGhc (Just libdir) getSessionDynFlags
mkSTG :: FilePath -> FilePath -> IO [StgBinding]
mkSTG proj src = do
dflags <- mkDynFlags
ghc_core <- runGhc (Just libdir) $ do
setSessionDynFlags (dflags {importPaths = [proj]})
compileToCoreSimplified src
-- compileToCoreModule src
coreToStg dflags (cm_module ghc_core) (cm_binds ghc_core)
mkIOStr :: (Outputable a) => a -> IO String
mkIOStr obj = do
dflags <- mkDynFlags
let ppr_str = showPpr dflags obj
return ppr_str
main :: IO ()
main = do
let proj = "/home/user/Desktop/hue"
let src = proj ++ "/FooBar.hs"
res <- mkIOStr =<< mkSTG proj src
putStrLn res
Похоже, что кто-то за несколько лет до меня столкнулся с похожей проблемой:
https://ghc.haskell.org/trac/ghc/ticket/7159
Однако я понятия не имею, что произошло с тех пор. Я также не уверен, что это правильный способ извлечения STG из произвольного источника Haskell, поэтому, если есть лучшие альтернативы, которые работают, я хотел бы услышать о них.
РЕДАКТИРОВАТЬ: Перевод STG выглядит успешным для следующей программы, в которой bar b = b + 3
заменено на bar b = 3
:
module FooBar where
foo a = a + a
bar :: Int -> Int
bar b = 3
Фактически, на первый взгляд кажется, что все работает, если индуцированный Core Haskell не заставляет выполнять примитивные операции. Например, bar b = 3 + 9
не работает.
1 ответ
Большое спасибо melpomene за указание на то, что я пропустил в документации.
Вот модифицированный исходный код test.hs
, который работает:
import CorePrep
import CoreToStg
import GHC
import GHC.Paths
import GhcMonad
import HscTypes
import Outputable
import StgSyn
import System.IO
mkSTG :: FilePath -> FilePath -> IO [StgBinding]
mkSTG proj src = runGhc (Just libdir) $ do
env <- getSession
dflags <- getSessionDynFlags
setSessionDynFlags (dflags {importPaths = [proj]})
target <- guessTarget src Nothing
setTargets [target]
load LoadAllTargets
mod_graph <- getModuleGraph
let mod_sum = head mod_graph -- This is bad practice
pmod <- parseModule mod_sum
tmod <- typecheckModule pmod
dmod <- desugarModule tmod
let guts = coreModule dmod
let loc = ms_location mod_sum
let binds = mg_binds guts
let tcs = mg_tcs guts
prep <- liftIO $ corePrepPgm env loc binds tcs
liftIO $ coreToStg dflags (mg_module guts) prep
mkIOStr :: (Outputable a) => a -> IO String
mkIOStr obj = do
dflags <- runGhc (Just libdir) getSessionDynFlags
let ppr_str = showPpr dflags obj
return ppr_str
main :: IO ()
main = do
let proj = "/home/celery/Desktop/hue"
let src = proj ++ "/FooBar.hs"
res <- mkIOStr =<< mkSTG proj src
putStrLn res
Я не уверен, как лучше всего восстановить ModSummary
(и, следовательно, ModuleName
) из Target
, но я смутно помню, что это был первый элемент ModuleGraph
, который определяется как type ModuleGraph = [ModSummary]
.
Сигнатура типа для corePrepPgm
также различается между GHC 7 и 8:
https://downloads.haskell.org/~ghc/7.10.1/docs/html/libraries/ghc-7.10.1/CorePrep.html
https://downloads.haskell.org/~ghc/latest/docs/html/libraries/ghc-8.0.1/CorePrep.html
Предложения по улучшению приветствуются :)
РЕДАКТИРОВАТЬ : я нашел примеры встречных примеров - head
ModuleGraph
не всегда является целью. Мой текущий обходной путь - проверить, содержит ли какой-либо ModSummary
в ModuleGraph
местоположение, которое совпадает с местоположением исходного исходного файла.
[]
), которые иногда в основном вынуждают вас делать «плохие» вещи. Так что не расстраивайтесь по этому поводу!
Похожие вопросы
Новые вопросы
haskell
Haskell - это функциональный язык программирования, отличающийся строгой статической типизацией, отложенной оценкой, обширной поддержкой параллелизма и параллелизма и уникальными возможностями абстракции.
CorePrep.corePrepPgm
, прежде чем пытаться использоватьCoreToStg.coreToStg
. ».