[英]How can I parse GHC core?
I am trying to parse ghc core code obtained from running ghc -c -ddump-simpl myfile.hs
. 我试图解析从运行
ghc -c -ddump-simpl myfile.hs
获得的ghc核心代码。
I know extcore
and core
libraries are my options. 我知道
extcore
和core
库是我的选择。
I am looking for a simple example depicting the use of these libraries. 我正在寻找一个描述这些库使用的简单示例。
[EDIT] Parsing result should be a data structure from which it should be easy to trace different paths a function can take. [编辑]解析结果应该是一个数据结构,从中可以很容易地跟踪函数可以采用的不同路径。
Consider a simple not
function 考虑一个简单的
not
功能
not True = False
not False = True
GHC will turn this into case expressions (consider output from ghc -c -ddump-simple
only). GHC会将其转换为case表达式(仅考虑
ghc -c -ddump-simple
输出)。 I am looking to parse this output of GHC core. 我想解析GHC核心的这个输出。
I think the easiest way is to forego these external Core libraries and just use GHC as a library directly. 我认为最简单的方法是放弃这些外部核心库,直接使用GHC作为库。 Based on this example from the Haskell wiki , we can make a simple function that turns a module into Core:
基于Haskell wiki中的这个示例 ,我们可以创建一个将模块转换为Core的简单函数:
import GHC
import GHC.Paths (libdir)
import HscTypes (mg_binds)
import CoreSyn
import DynFlags
import Control.Monad ((<=<))
compileToCore :: String -> IO [CoreBind]
compileToCore modName = runGhc (Just libdir) $ do
setSessionDynFlags =<< getSessionDynFlags
target <- guessTarget (modName ++ ".hs") Nothing
setTargets [target]
load LoadAllTargets
ds <- desugarModule <=< typecheckModule <=< parseModule <=< getModSummary $ mkModuleName modName
return $ mg_binds . coreModule $ ds
Here's a silly example usage that processes its output to count the number of cases: 这是一个愚蠢的示例用法,用于处理其输出以计算案例数:
-- Silly example function that analyzes Core
countCases :: [CoreBind] -> Int
countCases = sum . map countBind
where
countBind (NonRec _ e) = countExpr e
countBind (Rec bs) = sum . map (countExpr . snd) $ bs
countExpr (Case e _ _ alts) = countExpr e + sum (map countAlt alts)
countExpr (App f e) = countExpr f + countExpr e
countExpr (Lam _ e) = countExpr e
countExpr (Let b e) = countBind b + countExpr e
countExpr (Cast e _) = countExpr e
countExpr (Tick _ e) = countExpr e
countExpr _ = 0
countAlt (_, _, rhs) = 1 + countExpr rhs
Let's run it on your example: 让我们在你的例子中运行它:
main :: IO ()
main = do
core <- compileToCore "MyNot"
print $ countCases core
This outputs 2, as expected. 按预期输出2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.