Personal tools

GHC/As a library (up to 6.8)

From HaskellWiki

< GHC(Difference between revisions)
Jump to: navigation, search
(update the GHCi section for 6.6)
(update the "relevant" section for 6.6)
Line 44: Line 44:
 
== Relevant information ==
 
== Relevant information ==
   
'''Danger Will Robinson!! As of 15 October 2006, the GHC API has changed in ways that are not completely compatible with the documentation below!'''
+
'''As of GHC 6.6.'''
 
Initialize GHC
 
<pre>GHC.init :: String -> IO ()</pre>
 
This should be called once only. Initializes with TopDir path (the String passed in)
 
   
 
First create a session:
 
First create a session:
<pre>GHC.newSession :: DynFlags.GhcMode -> Session</pre>
+
<pre>GHC.newSession :: DynFlags.GhcMode -> Maybe FilePath -> IO Session</pre>
  +
The path should be the GHC installation directory, e.g., /usr/local/lib/ghc-6.6
   
 
Load Module
 
Load Module
Line 57: Line 57:
 
Enter Expressions/Run Statements
 
Enter Expressions/Run Statements
 
<pre>GHC.runStmt :: Session -> String -> IO RunResult
 
<pre>GHC.runStmt :: Session -> String -> IO RunResult
date GHC.RunResult
+
data GHC.RunResult
 
= RunOk [Name]
 
= RunOk [Name]
 
| RunFailed
 
| RunFailed
| RunException
+
| RunException GHC.IOBase.Exception -- that's Control.Exception.Exception
 
</pre>
 
</pre>
 
Example:
 
Example:
 
<pre>runStmt session "let n = 2 + 2"</pre>
 
<pre>runStmt session "let n = 2 + 2"</pre>
The RunResult of this is RunOk [n] where n is bound to 4. So if we subsequently enter <pre>runStmt session n</pre> the RunResult is not updated but 4 will be printed
+
The RunResult of this is RunOk [n] where n is bound to 4. So if we subsequently enter <pre>runStmt session "n"</pre> the RunResult is not updated but 4 will be printed
   
 
CompileExpr, DynCompileExpr
 
CompileExpr, DynCompileExpr
Line 73: Line 73:
 
<pre>GHC.getBindings :: Session -> IO [TyThing]</pre>
 
<pre>GHC.getBindings :: Session -> IO [TyThing]</pre>
   
Error messages can be routed through a callback mechanism.
+
Error messages can be routed through a callback mechanism using
<pre>setSessionDynFlags :: </pre>
+
<pre>setSessionDynFlags :: Session -> DynFlags -> IO [PackageId]</pre>
  +
where <code>DynFlags</code> is a record with many fields, one of which is
  +
<pre>
  +
log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message
  +
-> IO ()}
  +
</pre>
  +
and you can set it to your action, like
  +
<pre>
  +
f <- getSessionDynFlags session
  +
setSessionDynFlags session f{log_action = my_action}
  +
</pre>
   
 
== Interactive mode example ==
 
== Interactive mode example ==

Revision as of 05:32, 6 January 2007

Using GHC as a library

Contents

In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC.

This page is a place for everyone to add

  • Notes about how to get it working
  • Comments about the API
  • Suggestions for improvement

and so on.

1 Getting started

You'll need to get a version of GHC that supports the GHC API. Either download ghc from CVS or use darcs: darcs get --partial http://darcs.haskell.org/ghc. There are also nightly snapshot distributions available.

To use the GHC API you say simply

  import GHC

Doing this imports the module GHC from the package ghc, which comes with GHC 6.5 and subsequent. The module GHC exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the source code (which is somewhat documented) here http://darcs.haskell.org/ghc/compiler/main/GHC.hs

Here's an example main program that does it Media:Main.hs (good for GHC 6.6). You need to manually change the value of
myGhcRoot
to point to your GHC directory.

To compile Media:Main.hs, you have to turn on the flag "-package ghc", e.g.

  ghc -package ghc Main.hs

2 Using the GHC library from inside GHCi

This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.

Prelude> :m + GHC Module Packages PackageConfig
Prelude GHC> session <- newSession Interactive (Just "/usr/local/lib/ghc-6.6")
Prelude GHC> (\(f,_) -> setSessionDynFlags session f) =<< initPackages =<< getSessionDynFlags session
Prelude GHC> setContext session [] [mkModule (stringToPackageId "base") (mkModuleName "Prelude")]
Prelude GHC> runStmt session "let add1 x = x + 1"
Prelude GHC> runStmt session "add1 2"
3
Prelude GHC> :q
Leaving GHCi.

3 Relevant information

As of GHC 6.6.

First create a session:

GHC.newSession :: DynFlags.GhcMode -> Maybe FilePath -> IO Session

The path should be the GHC installation directory, e.g., /usr/local/lib/ghc-6.6

Load Module

HscTypes.TargetId = TargetModule ModuleName | TargetFile FilePath (Maybe Phase)

The Phase determines which phase to start from (preprocessing)

Enter Expressions/Run Statements

GHC.runStmt :: Session -> String -> IO RunResult
data GHC.RunResult
= RunOk [Name]
| RunFailed
| RunException GHC.IOBase.Exception  -- that's Control.Exception.Exception

Example:

runStmt session "let n = 2 + 2"
The RunResult of this is RunOk [n] where n is bound to 4. So if we subsequently enter
runStmt session "n"
the RunResult is not updated but 4 will be printed

CompileExpr, DynCompileExpr

Get module dependency graph

GHC.getModuleGraph :: Session -> IO ModuleGraph

Get bindings

GHC.getBindings :: Session -> IO [TyThing]

Error messages can be routed through a callback mechanism using

setSessionDynFlags :: Session -> DynFlags -> IO [PackageId]

where DynFlags is a record with many fields, one of which is

log_action :: Severity -> SrcLoc.SrcSpan -> Outputable.PprStyle -> ErrUtils.Message
           -> IO ()}

and you can set it to your action, like

  f <- getSessionDynFlags session
  setSessionDynFlags session f{log_action = my_action}

4 Interactive mode example

The file Media:Interactive.hs (also requires Media:MyPrelude.hs) serves as an example for using GHC as a library in interactive mode. It also shows how to replace some of the standard prelude functions with modified versions. See the comments in the code for further information.