h$YTs      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~            None:plugins?@#$%&'()*+,-./0123>?@4569:;78<=None&Aplugins)parse a file (as a string) as Haskell srcBpluginspretty print haskell srcdoesn't handle operators with # at the end. i.e. unsafeCoerce#CpluginsmergeModules : generate a full Haskell src file, give a .hs config 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 . 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.Dplugins replace Module name with String.EpluginsParsing option pragmas.This is not a type checker. If the user supplies bogus options, they'll 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 :  OPTIONS pragmas are only looked for at the top of your source files, up to the first (non-literate,non-empty) line not containing OPTIONS. Multiple OPTIONS pragmas are recognised.6based on getOptionsFromSource(), in main/DriverUtil.hsAplugins module nameplugins haskell srcpluginsabstract syntaxEplugins input srcpluginsnormal options, global optionsABCDEACBED Safe-Inferred[HIHINoneCJplugins$return the Z-Encoding of the string.5Stolen from GHC. Use -package ghc as soon as possibleLpluginsusefulMpluginswriteFile for HandlesNpluginscreate a new temp file, returning name and handle. bit like the mktemp shell utilityPpluginsGet 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 spaceUplugins /,  . : join two path componentsVplugins /,  . : join two path componentsWplugins /,  . : join two path componentsXpluginsdirname : return the directory portion of a file path if null, return "."Yplugins0basename : return the filename portion of a path[plugins%work out the mod name from a filepath\plugins%Changes the extension of a file path.]pluginsThe ] function is the opposite of ^. 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^pluginsSplit 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.", "")_plugins3return the object file, given the .conf file i.e. homedons foo.rc -> homedonsfoo.o3we depend on the suffix we are given having a lead apluginsis file1 newer than file2? print msg LoadSuccess _ v -> return vpluginsLike load, but doesn't want a package.conf arg (they are rarely used)pluginsA work-around for Dynamics. The keys used to compare two TypeReps are somehow not equal for the same type in hs-plugin's loaded objects. Solution: implement our own dynamics...The problem with dynload is that it requires the plugin to export a value that is a Dynamic (in our case a (TypeRep,a) pair). If this is not the case, we core dump. Use pdynload if you don't trust the user to supply you with a Dynamicplugins!The super-replacement for dynloadUse GHC at runtime so we get staged type inference, providing full power dynamics, *on module interfaces only*. This is quite suitable for plugins, of course :)8TODO where does the .hc file go in the call to build() ?pluginsLike pdynload, but you can specify extra arguments to the typechecker.pluginsunload a module (not its dependencies) we have the dependencies, so cascaded unloading is possibleonce you unload it, you can't  it again, you have to 0 it. Cause we don't unload all the dependenciespluginsunload a module and its dependencies we have the dependencies, so cascaded unloading is possiblepluginsthis will be nice for panTHeon, needs thinking about the interface reload a single object file. don't care about depends, assume they are loaded. (should use state to store all this)assumes you've already done a should factor the codepluginsCall the initLinker function first, before calling any of the other functions in this module - otherwise you'll get unresolved symbols.pluginsLoad a function from a module (which must be loaded and resolved first).pluginsLoads a function from a package module, given the package name, module name and symbol name.pluginsload a single object. no dependencies. You should know what you're doing.pluginsLoad a generic .o file, good for loading C objects. You should know what you're doing.. Returns a fairly meaningless iface value.plugins)Resolve (link) the modules loaded by the  function.pluginsfrom ghci/ObjLinker.cLoad a .so type object file.pluginsLoad a -package that we might need, implicitly loading the cbits too The argument is the name of package (e.g. "concurrent")How to find a package is determined by the package.conf info we store in the environment. It is just a matter of looking it up.$Not printing names of dependent pkgspluginsUnload a -package, that has already been loaded. Unload the cbits too. The argument is the name of the package.May need to check if it exists.Note that we currently need to unload everything. grumble grumble.We need to add the version number to the package name with 6.4 and over. "yi-0.1" for example. This is a bug really.pluginsload a package using the given package.conf to help TODO should report if it doesn't actually load the package, instead of mapM_ doing nothing like above.pluginsNice interface to .hi parserplugins object filepluginsany include pathspluginslist of package.conf pathspluginssymbol to findplugins object filepluginsany include pathspluginssymbol to findpluginsobject to loadplugins include pathsplugins package confspluginsAPI typepluginssymbolpluginsobject to loadpluginsinclude paths for loadingpluginsany extra package.conf filesplugins)extra arguments to ghc, when typecheckingplugins expected typepluginssymbol to loadpluginsThe module the value is inpluginsSymbol name of valuepluginsThe value you wantplugins'Package name, including version number.plugins Module namepluginsSymbol to lookup in the module NoneD8efghijklmnopqrstuvwxyz{|} NoneE=> NoneS3plugins provides a typesafe (to a limit) form of runtime evaluation for Haskell -- a limited form of runtime metaprogramming. The  argument to 6 is a Haskell source fragment to evaluate at rutime. imps 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  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. 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: do i <- eval "1 + 6 :: Int" [] :: IO (Maybe Int) when (isJust i) $ putStrLn (show (fromJust i))plugins is a variety of  with all the internal hooks available. You are able to set any extra arguments to the compiler (for example, optimisation flags) or dynamic loader, as well as having any errors returned in an  type.pluginsSometimes when constructing string fragments to evaluate, the programmer is able to provide some other constraint on the evaluated 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 typecheck, with an accompanying obligation on the programmer to ensure that the fragment evaluated will be typesafe at the point it is spliced.An 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 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)plugins is a form of  with all internal hooks exposed. This is useful for application wishing to return error messages to users, to specify particular libraries to link against and so on.plugins% is a helper function for converting s of names and values into Haskell code. It relies on the assumption of 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).pluginsReturn a compiled value's type, by using Dynamic to get a representation of the inferred type.pluginscode to compileplugins any importspluginsextra make flagsplugins(package.confs) for loadplugins"include paths load is to search inplugins*either errors, or maybe a well typed valuepluginscode to compileplugins any importsplugins make flagsplugins(package.confs) for loadplugins"include paths load is to search inNoneS !"#$%&&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw-xyz{|}~            &plugins-1.6.2.1-6pBEu0slLAOHrMboKaAhERSystem.Plugins.UtilsSystem.Plugins.ParserSystem.Plugins.ConstsSystem.Plugins.LoadTypesSystem.Plugins.EnvSystem.Plugins.ProcessSystem.Plugins.MakeSystem.Plugins.LoadSystem.Eval.UtilsSystem.Eval.HaskellLanguageHaskellSystem.PluginsDataMap System.EvalbaseGHC.Base<>(haskell-src-1.0.4-FDgYFnQ2pxqDO4ZrP3QDl0Language.Haskell.SyntaxHsModuletopghcghcLibraryPath sysPkgConf sysPkgSuffixobjSufhiSufhsSufdllSuf sysPkgPrefixprefixUnderscoretmpDirObjTypeVanillaSharedModulepathmnamekindifacekey PackageConfErrorsTypeSymbolKeyObjectPackage $fEqModule $fOrdModule $fEqObjTypeenv withModEnv withDepEnv withPkgEnvs withMerged modifyModEnv modifyDepEnv modifyPkgEnv modifyMerged addModulermModule addModulesisLoadedloaded addModuleDeps getModuleDeps rmModuleDeps addPkgConfdefaultPkgConfuniongrabDefaultPkgConfreadPackageConf addStaticPkg isStaticPkg rmStaticPkg lookupPkgpkgManglingPrefixisMerged lookupMergedaddMergeparsepretty mergeModulesreplaceModName parsePragmas$fSynEqHsImportDecl $fSynEqHsDeclexecpopen EncodedStringArgpanichWritemkTempmkTempInmkUnique hMkUnique mkUniqueIn hMkUniqueInfindFile<.><+>dirnamebasename dropSuffixmkModid changeFileExt joinFileExt splitFileExt replaceSuffix outFilePathnewerencodedecode isSublistOfArgs MergeCode MergeStatus MergeSuccess MergeFailureMakeCodeReCompNotReq MakeStatus MakeSuccess MakeFailuremakemakeAllmakeWith hasChanged hasChanged' recompileAll recompileAll'buildmergemergeTo mergeToDir makeClean makeCleaner$fEqMakeStatus$fShowMakeStatus$fEqMergeStatus$fShowMergeStatus $fEqMakeCode$fShowMakeCode LoadStatus LoadSuccess LoadFailureloadload_dynloadpdynload pdynload_unload unloadAllreload initLinker loadFunction loadFunction_loadPackageFunction loadModule loadRawObject resolveObjs loadShared loadPackage unloadPackageloadPackageWith getImportsImportsymbolescapegetPaths mkUniqueWithcleanupevaleval_ unsafeEval unsafeEval_ mkHsValuestypeOf. Data.EitherEither loadObject Control.MonadguardjoinMonadreturn>>=>>Functorfmap<$Control.Monad.Fail MonadFailfailData.TraversablemapMsequence GHC.MaybeMaybeNothingJust MonadPlusmplusmzero=<<whenliftMliftM2ap Data.Functorvoid Data.MaybemaybeisJust isNothing fromMaybe maybeToList listToMaybe catMaybesmapMaybe Data.Foldable sequence_filterMfoldMunlessmfilter<$!> replicateM_ replicateMfoldM_ zipWithM_zipWithM mapAndUnzipMforever<=<>=>forMmsumforM_mapM_fromJustliftM5liftM4liftM3StringData.Typeable.InternalTypeable Data.DynamicDynamicGHC.Showshow