我该如何解析GHC核心?

时间:2016-02-17 06:24:22

标签: haskell ghc

我正在尝试解析从运行not获得的ghc核心代码。

我知道extcorecore库是我的选择。

我正在寻找一个描述这些库使用的简单示例。

[编辑]解析结果应该是一个数据结构,从中可以很容易地跟踪函数可以采用的不同路径。

考虑一个简单的not True = False not False = True 函数

ghc -c -ddump-simple

GHC会将此转换为案例表达式(仅考虑found_relative_to_earth = float(found_planet_mass / earth_mass) results_text_Earth = 'The planet you found weighs {m1:0.5f} times the weight of the Earth\n'.format(m1=found_relative_to_earth) print(results_text_Earth) 的输出)。我想解析GHC核心的这个输出。

1 个答案:

答案 0 :(得分:2)

我认为最简单的方法是放弃这些外部核心库,直接使用GHC作为库。基于this example from the Haskell wiki,我们可以创建一个将模块转换为Core的简单函数:

#   |@CLASS|page2chck|page2chck|Title                          
----+------+---------+---------+---------------------------------
0   |null  |[441]    |[441]    |BlahBlah               

这是一个愚蠢的示例用法,用于处理其输出以计算案例数:

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

让我们按照你的例子运行它:

-- 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

按预期输出2。