6)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  Safe-Infered Safe-Infered*parse a file (as a string) as Haskell src pretty print haskell src doesn't handle operators with '#' at the end. i.e. unsafeCoerce# CmergeModules : generate a full Haskell src file, give a .hs config C file, and a stub to take default syntax and decls from. Mostly we  just ensure they don'*t do anything bad, and that the names are  correct for the module. Transformations: :. Take src location pragmas from the conf file (1st file)  . Use the template's (2nd argument) module name 5 . Only use export list from template (2nd arg)  . Merge top-level decls @ . need to force the type of the plugin to match the stub, ( overwriting any type they supply. !replace Module name with String. Parsing option pragmas. @This is not a type checker. If the user supplies bogus options,  they'2ll get slightly mystical error messages. Also, we want to $ handle -package options, and other static flags. This is more than  GHC. GHC user' s guide :  B OPTIONS pragmas are only looked for at the top of your source = files, up to the first (non-literate,non-empty) line not A containing OPTIONS. Multiple OPTIONS pragmas are recognised. (based on getOptionsFromSource(), in main/DriverUtil.hs  module name  haskell src abstract syntax  input src normal options, global options  Safe-Infered       Safe-Infered=path to *build* dir, used by eval() for testing the examples what is ghc called? path to standard ghc libraries %name of the system package.conf file "This code is from runtime_loader: ) The extension used by system modules. #>The prefix used by system modules. This, in conjunction with  systemModuleExtension., will result in a module filename that looks  like "HSconcurrent.o" $'_' on a.out, and Darwin %DDefine tmpDir to where tmp files should be created on your platform  !"#$%  !"#$%  !"#$%  !"#$% Safe-Infered 'apply f" to the loaded objects Env, apply f to the package.conf  FM locks up the MVar so you can't recursively call a function 6 inside a with any -Env function. Nice and threadsafe /1insert a loaded module name into the environment 0?remove a module name from the environment. Returns True if the  module was actually removed. 1,insert a list of module names all in one go 2 is a module/package already loaded? 4"Set the dependencies of a Module. 5<Get module dependencies. Nothing if none have been recored. 6(Unrecord a module from the environment. 7BInsert a single package.conf (containing multiple configs) means: G create a new FM. insert packages into FM. add FM to end of list of FM  stored in the environment. 8]add a new FM for the package.conf to the list of existing ones; if a package occurs multiple ` times, pick the one with the higher version number as the default (e.g., important for base in  GHC 6.12) 9/generate a PkgEnv from the system package.conf 8 The path to the default package.conf was determined by  configure E This imposes a constraint that you must build your plugins with the D same ghc you use to build hs-plugins. This is reasonable, we feel. &'()*+,-./0123456789:;<=>?@&'()*+,-./0123456789:;<=>?@&'()*+,-./0123456>?@78;<9:=&'()*+,-./0123456789:;<=>?@ Safe-InferedA%return the Z-Encoding of the string. 6Stolen from GHC. Use -package ghc as soon as possible Cuseful DwriteFile for Handles E mkstemps. AWe use the Haskell version now... it is faster than calling into  mkstemps(3). 3create a new temp file, returning name and handle. # bit like the mktemp shell utility G*Get a new temp file, unique from those in /tmp, and from those , modules already loaded. Very nice for merge/ eval uses. "Will run for a long time if we can't create a temp file, luckily - mkstemps gives us a pretty big search space L /,  . : join two path components M /,  . : join two path components N /,  . : join two path components O /,  . : join two path components P6dirname : return the directory portion of a file path  if null, return . Q1basename : return the filename portion of a path S&work out the mod name from a filepath T&Changes the extension of a file path. UThe U function is the opposite of V. E It joins a file name and an extension to form a complete file path. The general rule is: $ filename `joinFileExt` ext == path  where ( (filename,ext) = splitFileExt path V>Split the path into file name and extension. If the file doesn't have extension, ; the function will return empty string. The extension doesn't include a leading period.  Examples: * splitFileExt "foo.ext" == ("foo", "ext") ' splitFileExt "foo" == ("foo", "") ' splitFileExt "." == (".", "") ' splitFileExt ".." == ("..", "") , splitFileExt "foo.bar."== ("foo.bar.", "") W-return the object file, given the .conf file  i.e. homedons foo.rc -> homedonsfoo.o 3we depend on the suffix we are given having a lead  Yis file1 newer than file2? =needs some fixing to work with 6.0.x series. (is this true?) EfileExist still seems to throw exceptions on some platforms: ia64 in  particular. .invarient : we already assume the first file, a , exists ABCDEFGHIJKLMNOPQRST The path information to modify. .The new extension (without a leading period). / Specify an empty string to remove an existing  extension from path. 3A string containing the modified path information. UVWXYZ[\ABCDEFGHIJKLMNOPQRSTUVWXYZ[\BDGHIJKEFWXRSTUV\PQLONMYZ[ACABCDEFGHIJKLMNOPQRSTUVWXYZ[\ Safe-Infered]Convience synonym ^ A list of String arguments _=Merging may be avoided if the source files are older than an  existing merged result. The  MergeCode type indicates whether 8 merging was performed, or whether it was unneccessary. `0An equivalent status for the preprocessor phase a!failure, and any errors returned bthe merge was successful cThe MakeCode1 type is used when compilation is successful, to  distinguish two cases: : * The source file needed recompiling, and this was done F * The source file was already up to date, recompilation was skipped drecompilation was not required erecompilation was performed fThe  MakeStatus4 type represents success or failure of compilation. A Compilation can fail for the usual reasons: syntax errors, type  errors and the like. The  MakeFailure constructor returns any error $ messages produced by the compiler.  MakeSuccess returns a MakeCode 2 value, and the path to the object file produced. gcompilation failed hcompilation was successful i?One-shot unconditional compilation of a single Haskell module.  make behaves like 'ghc -c'. Extra arguments to  may be passed  in the args8 parameter, they will be appended to the argument list.  make; always recompiles its target, whether or not it is out of  date. A side-effect of calling i is to have GHC produce a .hi file F containing a list of package and objects that the source depends on.  Subsequent calls to load& will use this interface file to load E module and library dependencies prior to loading the object itself. jj9 recursively compiles any dependencies it can find using  GHC's --make8 flag. Dependencies will be recompiled only if they are  visible to 6 -- this may require passing appropriate include path  flags in the args parameter. j takes the top-level file as  the first argument. kThis is a variety of i that first calls q to B combine the plugin source with a syntax stub. The result is then C compiled. This is provided for EDSL authors who wish to add extra  syntax to a user'+s source. It is important to note that the E module and types from the second file argument are used to override G any of those that appear in the first argument. For example, consider  the following source files:   module A where  a :: Integer  a = 1 and   module B where  a :: Int Calling  makeWith A B []& will merge the module name and types 7 from module B into module A, generating a third file:  {-# LINE 1 "A.hs" #-}  module MxYz123 where  {-# LINE 3 "B.hs" #-}  a :: Int  {-# LINE 4 "A.hs" #-}  a = 1 l hasChanged returns True if the module or any of its F dependencies have older object files than source files. Defaults to  True if some files couldn't be located. nn is like j, but rather than relying on   ghc --make, we explicitly check a module's dependencies using our F internal map of module dependencies. Performance is thus better, and  the result is more accurate. pLower-level than i". Compile a .hs file to a .o file > If the plugin needs to import an api (which should be almost E everyone) then the ghc flags to find the api need to be provided as  arguments q2Merge to source files into a temporary file. If we' ve tried to F merge these two stub files before, then reuse the module name (helps  recompilation checking) FThe merging operation is extremely useful for providing extra default A syntax. An EDSL user then need not worry about declaring module D names, or having required imports. In this way, the stub file can ; also be used to provide syntax declarations that would be 0 inconvenient to require of the plugin author. q< will include any import and export declarations written in < the stub, as well as any module name, so that plugin author's need C not worry about this compulsory syntax. Additionally, if a plugin A requires some non-standard library, which must be provided as a  -package; flag to GHC, they may specify this using the non-standard   GLOBALOPTIONS3 pragma. Options specified in the source this way F will be added to the command line. This is useful for users who wish B to use GHC flags that cannot be specified using the conventional  OPTIONS: pragma. The merging operation uses the parser hs-plugins  was configured with, either    or the HSX parser, to  parse Haskell source files. rr behaves like q!, but we can specify the file in  which to place output. ss behaves like q , but lets you specify a target  directory. t6makeClean : assuming we some element of [f.hs,f.hi,f.o] , remove the @ .hi and .o components. Silently ignore any missing components. /Does  not remove .hs files/. To do that use u. This would be ' useful for merged files, for example. ]^_`abcdefghijk a src file a syntax stub file any required args path to an object file lmnoppath to .hs source path to object file any extra cmd line flags qrstu]^_`abcdefghijklmnopqrstufhgcedijklmno`ba_^]qrstup]^_`bacedfhgijklmnopqrstu Safe-Infered vThe  LoadStatus2 type encodes the return status of functions that 1 perform dynamic loading in a type isomorphic to  . Failure C returns a list of error strings, success returns a reference to a G loaded module, and the Haskell value corresponding to the symbol that  was indexed. zz9 is the basic interface to the dynamic loader. A call to  z- imports a single object file into the caller's address space, E returning the value associated with the symbol requested. Libraries C and modules that the requested module depends upon are loaded and  linked in turn. FThe first argument is the path to the object file to load, the second D argument is a list of directories to search for dependent modules. < The third argument is a list of paths to user-defined, but  unregistered,  package.conf files. The  argument is the 0 symbol name of the value you with to retrieve. @The value returned must be given an explicit type signature, or G provided with appropriate type constraints such that Haskell compiler - can determine the expected type returned by z, as the return ! type is notionally polymorphic.  Example: 0 do mv <- load "Plugin.o" ["api"] [] "resource"  case mv of % LoadFailure msg -> print msg $ LoadSuccess _ v -> return v {Like load, but doesn'1t want a package.conf arg (they are rarely used) ~:Like pdynload, but you can specify extra arguments to the  typechecker. 'unload a module (not its dependencies) = we have the dependencies, so cascaded unloading is possible once you unload it, you can't z it again, you have to   it. Cause we don't unload all the dependencies %unload a module and its dependencies = we have the dependencies, so cascaded unloading is possible Cthis will be nice for panTHeon, needs thinking about the interface ! reload a single object file. don'"t care about depends, assume they 2 are loaded. (should use state to store all this)  assumes you've already done a z should factor the code DCall the initLinker function first, before calling any of the other ) functions in this module - otherwise you'll get unresolved symbols. ILoad a function from a module (which must be loaded and resolved first). @Loads a function from a package module, given the package name,  module name and symbol name. 4Load a generic .o file, good for loading C objects.  You should know what you' re doing.. + Returns a fairly meaningless iface value. )Resolve (link) the modules loaded by the  function.  from ghci/ ObjLinker.c Load a .so type object file. vwxyz object file any include paths list of package.conf paths symbol to find {|}object to load include paths package confs  API type symbol ~object to load include paths for loading any extra package.conf files *extra arguments to ghc, when typechecking expected type symbol to load The module the value is in Symbol name of value The value you want (Package name, including version number.  Module name Symbol to lookup in the module  vwxyz{|}~vxwz{|}~ yvxwyz{|}~  Safe-Infered8 ]^_`abcdefghijklmnopqrstuvwxyz{|}~  Safe-Infered;  Safe-Infered= provides a typesafe (to a limit) form of runtime evaluation " for Haskell -- a limited form of runtime metaprogramming. The   argument to * is a Haskell source fragment to evaluate  at rutime. imps5 are a list of module names to use in the context of  the compiled value. The value returned by  is constrained to be  --  meaning we can perform a limited runtime typecheck, using the  |9 function. One consequence of this is that the code must = evaluate to a monomorphic value (which will be wrapped in a  ). +If the evaluated code typechecks under the  constraints,  'Just v' is returned.  indicates typechecking failed. F Typechecking may fail at two places: when compiling the argument, or % when typechecking the splice point.  resembles a  metaprogramming run operator for closed source fragments. =To evaluate polymorphic values you need to wrap them in data  structures using rank-N types.  Examples: 2 do i <- eval "1 + 6 :: Int" [] :: IO (Maybe Int) 3 when (isJust i) $ putStrLn (show (fromJust i))  is a variety of  with all the internal hooks D available. You are able to set any extra arguments to the compiler A (for example, optimisation flags) or dynamic loader, as well as " having any errors returned in an  type. >Sometimes when constructing string fragments to evaluate, the F programmer is able to provide some other constraint on the evaluated F string, such that the evaluated expression will be typesafe, without  requiring a , constraint. In such cases, the monomorphic  restriction is annoying.  removes any splice-point A typecheck, with an accompanying obligation on the programmer to E ensure that the fragment evaluated will be typesafe at the point it  is spliced. EAn example of how to do this would be to wrap the fragment in a call  to =. The augmented fragment would then be checked when compiled  to return a /, and the programmer can rely on this, without 1 requiring a splice-point typecheck, and thus no   restriction. ?Note that if you get the proof wrong, your program will likely  segfault.  Example: < do s <- unsafeEval "map toUpper \"haskell\"" ["Data.Char"] , when (isJust s) $ putStrLn (fromJust s)  is a form of  with all internal hooks A exposed. This is useful for application wishing to return error D messages to users, to specify particular libraries to link against  and so on. % is a helper function for converting s G of names and values into Haskell code. It relies on the assumption of F names and values into Haskell code. It relies on the assumption that  the passed values'/ Show instances produce valid Haskell literals ' (this is true for all Prelude types). Return a compiled value'"s type, by using Dynamic to get a & representation of the inferred type. code to compile  any imports extra make flags (package.confs) for load #include paths load is to search in +either errors, or maybe a well typed value code to compile  any imports  make flags (package.confs) for load #include paths load is to search in A Safe-InferedA !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklm%nopqrstuvwxyz{|}~  plugins-1.5.2.3System.Plugins.ParserSystem.Plugins.ProcessSystem.Plugins.LoadTypesSystem.Plugins.ConstsSystem.Plugins.EnvSystem.Plugins.UtilsSystem.Plugins.MakeSystem.Plugins.LoadSystem.Eval.UtilsSystem.Eval.HaskellLanguageHaskellSystem.PluginsDataMap System.Evalhaskell-src-1.0.1.5Language.Haskell.SyntaxHsModuleexecpopenparsepretty mergeModulesreplaceModName parsePragmasObjTypeSharedVanillaModulepathmnamekindifacekey PackageConfErrorsTypeSymbolKeyPackageObjecttopghcghcLibraryPath sysPkgConf sysPkgSuffixobjSufhiSufhsSufdllSuf sysPkgPrefixprefixUnderscoretmpDirenv withModEnv withDepEnv withPkgEnvs withMerged modifyModEnv modifyDepEnv modifyPkgEnv modifyMerged addModulermModule addModulesisLoadedloaded addModuleDeps getModuleDeps rmModuleDeps addPkgConfuniongrabDefaultPkgConfreadPackageConf addStaticPkg isStaticPkg lookupPkgisMerged lookupMergedaddMerge EncodedStringArgpanichWritemkTempmkTempInmkUnique hMkUnique mkUniqueIn hMkUniqueInfindFile<.><+><>dirnamebasename dropSuffixmkModid changeFileExt joinFileExt splitFileExt replaceSuffix outFilePathnewerencodedecode isSublistOfArgs MergeCode MergeStatus MergeFailure MergeSuccessMakeCodeNotReqReComp MakeStatus MakeFailure MakeSuccessmakemakeAllmakeWith hasChanged hasChanged' recompileAll recompileAll'buildmergemergeTo mergeToDir makeClean makeCleaner LoadStatus LoadFailure LoadSuccess initLinkerloadload_dynloadpdynload pdynload_unload unloadAllreload loadFunction loadFunction_loadPackageFunction loadModule loadRawObject resolveObjs loadShared loadPackage unloadPackageloadPackageWith getImportsImportsymbolescapegetPaths mkUniqueWithcleanupevaleval_ unsafeEval unsafeEval_ mkHsValuestypeOf$fSynEqHsImportDecl $fSynEqHsDecl $fEqModule $fOrdModulebaseGHC.Base. Data.EitherEither loadObjectfail>>=>>fmapreturn Control.MonadguardliftMMonadFunctor MonadPlus Data.MaybeNothingmfilterapliftM5liftM4liftM3liftM2unlesswhen replicateM_ replicateMfoldM_foldM zipWithM_zipWithM mapAndUnzipMjoinvoidforever<=<>=>msumforM_forMfilterMmapM_mapM sequence_sequence=<<mplusmzeromapMaybe catMaybes listToMaybe maybeToList fromMaybefromJust isNothingisJustmaybeJustMaybeStringData.Typeable.InternalTypeable Data.DynamicDynamicGHC.Showshow