packages feed

purescript 0.5.1 → 0.5.2

raw patch · 16 files changed

+245/−300 lines, 16 filesdep ~haskelinePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: haskeline

API changes (from Hackage documentation)

- Language.PureScript.CodeGen.Monad: Gen :: State [String] a -> Gen a
- Language.PureScript.CodeGen.Monad: fresh :: Gen String
- Language.PureScript.CodeGen.Monad: instance Applicative Gen
- Language.PureScript.CodeGen.Monad: instance Functor Gen
- Language.PureScript.CodeGen.Monad: instance Monad Gen
- Language.PureScript.CodeGen.Monad: instance MonadState [String] Gen
- Language.PureScript.CodeGen.Monad: newtype Gen a
- Language.PureScript.CodeGen.Monad: runGen :: [String] -> Gen a -> a
- Language.PureScript.CodeGen.Monad: unGen :: Gen a -> State [String] a
- Language.PureScript.Scope: unusedNames :: [Ident] -> [Ident]
- Language.PureScript.Scope: usedNamesBinder :: Binder -> [Ident]
- Language.PureScript.Scope: usedNamesCaseAlternative :: CaseAlternative -> [Ident]
- Language.PureScript.Scope: usedNamesDecl :: Declaration -> [Ident]
- Language.PureScript.Scope: usedNamesDoNotationElement :: DoNotationElement -> [Ident]
- Language.PureScript.Scope: usedNamesValue :: Value -> [Ident]
+ Language.PureScript.Supply: SupplyT :: StateT Integer m a -> SupplyT m a
+ Language.PureScript.Supply: evalSupply :: Integer -> Supply a -> a
+ Language.PureScript.Supply: evalSupplyT :: Functor m => Integer -> SupplyT m a -> m a
+ Language.PureScript.Supply: fresh :: Monad m => SupplyT m Integer
+ Language.PureScript.Supply: freshName :: (Functor m, Monad m) => SupplyT m String
+ Language.PureScript.Supply: instance (Monad m, Functor m) => Applicative (SupplyT m)
+ Language.PureScript.Supply: instance Functor m => Functor (SupplyT m)
+ Language.PureScript.Supply: instance Monad m => Monad (SupplyT m)
+ Language.PureScript.Supply: instance MonadError e m => MonadError e (SupplyT m)
+ Language.PureScript.Supply: instance MonadTrans SupplyT
+ Language.PureScript.Supply: newtype SupplyT m a
+ Language.PureScript.Supply: runSupply :: Integer -> Supply a -> (a, Integer)
+ Language.PureScript.Supply: runSupplyT :: Integer -> SupplyT m a -> m (a, Integer)
+ Language.PureScript.Supply: type Supply = SupplyT Identity
+ Language.PureScript.Supply: unSupplyT :: SupplyT m a -> StateT Integer m a
- Language.PureScript: make :: (Functor m, Monad m, MonadMake m) => FilePath -> Options -> [(FilePath, Module)] -> m Environment
+ Language.PureScript: make :: (Functor m, Applicative m, Monad m, MonadMake m) => FilePath -> Options -> [(FilePath, Module)] -> m Environment
- Language.PureScript.CodeGen.JS: declToJs :: Options -> ModuleName -> Declaration -> Environment -> Maybe [JS]
+ Language.PureScript.CodeGen.JS: declToJs :: (Functor m, Applicative m, Monad m) => Options -> ModuleName -> Declaration -> Environment -> SupplyT m (Maybe [JS])
- Language.PureScript.CodeGen.JS: moduleToJs :: ModuleType -> Options -> Module -> Environment -> [JS]
+ Language.PureScript.CodeGen.JS: moduleToJs :: (Functor m, Applicative m, Monad m) => ModuleType -> Options -> Module -> Environment -> SupplyT m [JS]
- Language.PureScript.Environment: Environment :: Map (ModuleName, Ident) (Type, NameKind) -> Map (Qualified ProperName) (Kind, TypeKind) -> Map (Qualified ProperName) (ProperName, Type) -> Map (Qualified ProperName) ([String], Type) -> [TypeClassDictionaryInScope] -> Map (Qualified ProperName) ([String], [(Ident, Type)], [(Qualified ProperName, [Type])]) -> Environment
+ Language.PureScript.Environment: Environment :: Map (ModuleName, Ident) (Type, NameKind) -> Map (Qualified ProperName) (Kind, TypeKind) -> Map (Qualified ProperName) (ProperName, Type) -> Map (Qualified ProperName) ([String], Type) -> Map (Qualified Ident, Maybe ModuleName) TypeClassDictionaryInScope -> Map (Qualified ProperName) ([String], [(Ident, Type)], [(Qualified ProperName, [Type])]) -> Environment
- Language.PureScript.Environment: typeClassDictionaries :: Environment -> [TypeClassDictionaryInScope]
+ Language.PureScript.Environment: typeClassDictionaries :: Environment -> Map (Qualified Ident, Maybe ModuleName) TypeClassDictionaryInScope
- Language.PureScript.Sugar: desugar :: [Module] -> Either ErrorStack [Module]
+ Language.PureScript.Sugar: desugar :: [Module] -> SupplyT (Either ErrorStack) [Module]
- Language.PureScript.Sugar.CaseDeclarations: desugarCases :: [Declaration] -> Either ErrorStack [Declaration]
+ Language.PureScript.Sugar.CaseDeclarations: desugarCases :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
- Language.PureScript.Sugar.CaseDeclarations: desugarCasesModule :: [Module] -> Either ErrorStack [Module]
+ Language.PureScript.Sugar.CaseDeclarations: desugarCasesModule :: [Module] -> SupplyT (Either ErrorStack) [Module]
- Language.PureScript.Sugar.DoNotation: desugarDoModule :: Module -> Either ErrorStack Module
+ Language.PureScript.Sugar.DoNotation: desugarDoModule :: Module -> SupplyT (Either ErrorStack) Module
- Language.PureScript.Sugar.TypeClasses: desugarTypeClasses :: [Module] -> Either ErrorStack [Module]
+ Language.PureScript.Sugar.TypeClasses: desugarTypeClasses :: [Module] -> SupplyT (Either ErrorStack) [Module]

Files

psc-make/Main.hs view
@@ -45,7 +45,7 @@   collect :: [(FilePath, Either ParseError [P.Module])] -> Either ParseError [(FilePath, P.Module)]   collect = fmap concat . sequence . map (\(fp, e) -> fmap (map ((,) fp)) e) -newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Monad, MonadIO, MonadError String)+newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadError String)  runMake :: Make a -> IO (Either String a) runMake = runErrorT . unMake
purescript.cabal view
@@ -1,5 +1,5 @@ name: purescript-version: 0.5.1+version: 0.5.2 cabal-version: >=1.8 build-type: Custom license: MIT@@ -34,8 +34,8 @@                      Language.PureScript.Errors                      Language.PureScript.Kinds                      Language.PureScript.Names+                     Language.PureScript.Supply                      Language.PureScript.Types-                     Language.PureScript.Scope                      Language.PureScript.Traversals                      Language.PureScript.TypeClassDictionaries                      Language.PureScript.DeadCodeElimination@@ -53,7 +53,6 @@                      Language.PureScript.CodeGen.Externs                      Language.PureScript.CodeGen.JS                      Language.PureScript.CodeGen.JS.AST-                     Language.PureScript.CodeGen.Monad                      Language.PureScript.Optimizer                      Language.PureScript.Optimizer.Common                      Language.PureScript.Optimizer.MagicDo@@ -106,7 +105,7 @@  executable psci     build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,-                   mtl -any, parsec -any, haskeline -any, purescript -any,+                   mtl -any, parsec -any, haskeline >= 0.7.0.0, purescript -any,                    transformers -any, utf8-string -any, process -any,                    xdg-basedir -any, cmdtheline -any     main-is: Main.hs@@ -136,7 +135,7 @@  test-suite tests     build-depends: base >=4 && <5, containers -any, directory -any,-                   filepath -any, mtl -any, parsec -any, purescript -any, +                   filepath -any, mtl -any, parsec -any, purescript -any,                    transformers -any, utf8-string -any, process -any     type: exitcode-stdio-1.0     main-is: Main.hs
src/Language/PureScript.hs view
@@ -30,6 +30,7 @@ import Language.PureScript.Environment as P import Language.PureScript.Errors as P import Language.PureScript.DeadCodeElimination as P+import Language.PureScript.Supply as P  import qualified Language.PureScript.Constants as C @@ -40,7 +41,7 @@ import Control.Monad.Error import Control.Monad.State.Lazy import Control.Arrow ((&&&))-import Control.Applicative ((<$>))+import Control.Applicative import qualified Data.Map as M import qualified Data.Set as S import System.FilePath (pathSeparator)@@ -70,14 +71,14 @@ compile' :: Environment -> Options -> [Module] -> Either String (String, String, Environment) compile' env opts ms = do   (sorted, _) <- sortModules $ if optionsNoPrelude opts then ms else (map importPrelude ms)-  desugared <- stringifyErrorStack True $ desugar sorted+  (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ desugar sorted   (elaborated, env') <- runCheck' opts env $ forM desugared $ typeCheckModule mainModuleIdent   regrouped <- stringifyErrorStack True $ createBindingGroupsModule . collapseBindingGroupsModule $ elaborated   let entryPoints = moduleNameFromString `map` optionsModules opts   let elim = if null entryPoints then regrouped else eliminateDeadCode entryPoints regrouped   let codeGenModules = moduleNameFromString `map` optionsCodeGenModules opts   let modulesToCodeGen = if null codeGenModules then elim else filter (\(Module mn _ _) -> mn `elem` codeGenModules) elim-  let js = concatMap (\m -> moduleToJs Globals opts m env') modulesToCodeGen+  let js = evalSupply nextVar $ concat <$> mapM (\m -> moduleToJs Globals opts m env') modulesToCodeGen   let exts = intercalate "\n" . map (`moduleToPs` env') $ modulesToCodeGen   js' <- generateMain env' opts js   return (prettyPrintJS js', exts, env')@@ -165,7 +166,7 @@ -- If timestamps have not changed, the externs file can be used to provide the module's types without -- having to typecheck the module again. ---make :: (Functor m, Monad m, MonadMake m) => FilePath -> Options -> [(FilePath, Module)] -> m Environment+make :: (Functor m, Applicative m, Monad m, MonadMake m) => FilePath -> Options -> [(FilePath, Module)] -> m Environment make outputDir opts ms = do   let filePathMap = M.fromList (map (\(fp, Module mn _ _) -> (mn, fp)) ms) @@ -188,15 +189,15 @@    marked <- rebuildIfNecessary (reverseDependencies graph) toRebuild sorted -  desugared <- liftError $ stringifyErrorStack True $ zip (map fst marked) <$> desugar (map snd marked)+  (desugared, nextVar) <- liftError $ stringifyErrorStack True $ runSupplyT 0 $ zip (map fst marked) <$> desugar (map snd marked) -  go initEnvironment desugared+  evalSupplyT nextVar (go initEnvironment desugared)    where-  go :: (Functor m, Monad m, MonadMake m) => Environment -> [(Bool, Module)] -> m Environment+  go :: (Functor m, Applicative m, Monad m, MonadMake m) => Environment -> [(Bool, Module)] -> SupplyT m Environment   go env [] = return env   go env ((False, m) : ms') = do-    (_, env') <- liftError . runCheck' opts env $ typeCheckModule Nothing m+    (_, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m      go env' ms'   go env ((True, m@(Module moduleName' _ exps)) : ms') = do@@ -204,18 +205,18 @@         jsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "index.js"         externsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "externs.purs" -    progress $ "Compiling " ++ runModuleName moduleName'+    lift . progress $ "Compiling " ++ runModuleName moduleName' -    (Module _ elaborated _, env') <- liftError . runCheck' opts env $ typeCheckModule Nothing m+    (Module _ elaborated _, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m -    regrouped <- liftError . stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated+    regrouped <- lift . liftError . stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated      let mod' = Module moduleName' regrouped exps-        js = prettyPrintJS $ moduleToJs CommonJS opts mod' env'-        exts = moduleToPs mod' env'+    js <- prettyPrintJS <$> moduleToJs CommonJS opts mod' env'+    let exts = moduleToPs mod' env' -    writeTextFile jsFile js-    writeTextFile externsFile exts+    lift $ writeTextFile jsFile js+    lift $ writeTextFile externsFile exts      go env' ms' 
src/Language/PureScript/CodeGen/Externs.hs view
@@ -85,7 +85,7 @@      exportToPs (TypeInstanceRef ident) = do       let TypeClassDictionaryInScope { tcdClassName = className, tcdInstanceTypes = tys, tcdDependencies = deps} =-            fromMaybe (error $ "Type class instance has no dictionary in exportToPs") . find ((== Qualified (Just moduleName) ident) . tcdName) $ typeClassDictionaries env+            fromMaybe (error $ "Type class instance has no dictionary in exportToPs") . find ((== Qualified (Just moduleName) ident) . tcdName) $ M.elems $ typeClassDictionaries env       let constraintsText = case fromMaybe [] deps of                               [] -> ""                               cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map prettyPrintTypeAtom tys')) cs) ++ ") => "
src/Language/PureScript/CodeGen/JS.hs view
@@ -23,26 +23,25 @@     isIdent ) where -import Data.Maybe (fromJust, fromMaybe, mapMaybe)+import Data.Maybe (catMaybes, fromJust, fromMaybe) import Data.Function (on) import Data.List (nub, (\\)) -import Control.Arrow (second) import Control.Monad (replicateM, forM)+import Control.Applicative  import qualified Data.Map as M  import Language.PureScript.Names import Language.PureScript.Declarations-import Language.PureScript.CodeGen.Monad import Language.PureScript.Options import Language.PureScript.CodeGen.JS.AST as AST import Language.PureScript.Types import Language.PureScript.Optimizer import Language.PureScript.CodeGen.Common import Language.PureScript.Environment--import qualified Language.PureScript.Scope as S+import Language.PureScript.Supply+import Language.PureScript.Traversals (sndM)  -- | -- Different types of modules which are supported@@ -53,22 +52,23 @@ -- Generate code in the simplified Javascript intermediate representation for all declarations in a -- module. ---moduleToJs :: ModuleType -> Options -> Module -> Environment -> [JS]-moduleToJs mt opts (Module name decls (Just exps)) env = case mt of-  CommonJS -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) moduleExports]-  Globals | not isModuleEmpty ->-    [ JSVariableIntroduction (fromJust (optionsBrowserNamespace opts))-                             (Just (JSBinary Or (JSVar (fromJust (optionsBrowserNamespace opts))) (JSObjectLiteral [])) )-    , JSAssignment (JSAccessor (moduleNameToJs name) (JSVar (fromJust (optionsBrowserNamespace opts))))-                   (JSApp (JSFunction Nothing [] (JSBlock (moduleBody ++ [JSReturn moduleExports]))) [])-    ]-  _ -> []-  where-  isModuleEmpty = null jsDecls-  moduleBody = JSStringLiteral "use strict" : jsImports ++ jsDecls-  moduleExports = JSObjectLiteral $ concatMap exportToJs exps-  jsDecls = (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts name decl env) decls)-  jsImports = map (importToJs mt opts) . (\\ [name]) . nub $ concatMap imports decls+moduleToJs :: (Functor m, Applicative m, Monad m) => ModuleType -> Options -> Module -> Environment -> SupplyT m [JS]+moduleToJs mt opts (Module name decls (Just exps)) env = do+  let jsImports = map (importToJs mt opts) . (\\ [name]) . nub $ concatMap imports decls+  jsDecls <- mapM (\decl -> declToJs opts name decl env) decls+  let optimized = concat $ map (map $ optimize opts) $ catMaybes jsDecls+  let isModuleEmpty = null optimized+  let moduleBody = JSStringLiteral "use strict" : jsImports ++ optimized+  let moduleExports = JSObjectLiteral $ concatMap exportToJs exps+  return $ case mt of+    CommonJS -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) moduleExports]+    Globals | not isModuleEmpty ->+      [ JSVariableIntroduction (fromJust (optionsBrowserNamespace opts))+                               (Just (JSBinary Or (JSVar (fromJust (optionsBrowserNamespace opts))) (JSObjectLiteral [])) )+      , JSAssignment (JSAccessor (moduleNameToJs name) (JSVar (fromJust (optionsBrowserNamespace opts))))+                     (JSApp (JSFunction Nothing [] (JSBlock (moduleBody ++ [JSReturn moduleExports]))) [])+      ]+    _ -> [] moduleToJs _ _ _ _ = error "Exports should have been elaborated in name desugaring"  importToJs :: ModuleType -> Options -> ModuleName -> JS@@ -91,14 +91,17 @@ -- | -- Generate code in the simplified Javascript intermediate representation for a declaration ---declToJs :: Options -> ModuleName -> Declaration -> Environment -> Maybe [JS]-declToJs opts mp (ValueDeclaration ident _ _ _ val) e =-  Just [JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))]-declToJs opts mp (BindingGroupDeclaration vals) e =-  Just $ flip concatMap vals $ \(ident, _, val) ->-    [JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))]-declToJs _ mp (DataDeclaration _ _ ctors) _ =-  Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->+declToJs :: (Functor m, Applicative m, Monad m) => Options -> ModuleName -> Declaration -> Environment -> SupplyT m (Maybe [JS])+declToJs opts mp (ValueDeclaration ident _ _ _ val) e = do+  js <- valueToJs opts mp e val+  return $ Just [JSVariableIntroduction (identToJs ident) (Just js)]+declToJs opts mp (BindingGroupDeclaration vals) e = do+  jss <- flip mapM vals $ \(ident, _, val) -> do+    js <- valueToJs opts mp e val+    return $ JSVariableIntroduction (identToJs ident) (Just js)+  return $ Just jss+declToJs _ mp (DataDeclaration _ _ ctors) _ = do+  return $ Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->     [JSVariableIntroduction ctor (Just (go pn 0 tys []))]     where     go :: ProperName -> Integer -> [Type] -> [JS] -> JS@@ -107,10 +110,12 @@     go pn index (_ : tys') values =       JSFunction Nothing ["value" ++ show index]         (JSBlock [JSReturn (go pn (index + 1) tys' (JSVar ("value" ++ show index) : values))])-declToJs opts mp (DataBindingGroupDeclaration ds) e = Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds-declToJs _ _ (ExternDeclaration _ _ (Just js) _) _ = Just [js]+declToJs opts mp (DataBindingGroupDeclaration ds) e = do+  jss <- mapM (\decl -> declToJs opts mp decl e) ds+  return $ Just $ concat $ catMaybes jss+declToJs _ _ (ExternDeclaration _ _ (Just js) _) _ = return $ Just [js] declToJs opts mp (PositionedDeclaration _ d) e = declToJs opts mp d e-declToJs _ _ _ _ = Nothing+declToJs _ _ _ _ = return Nothing  -- | -- Generate key//value pairs for an object literal exporting values from a module.@@ -144,22 +149,35 @@ -- | -- Generate code in the simplified Javascript intermediate representation for a value or expression. ---valueToJs :: Options -> ModuleName -> Environment -> Value -> JS-valueToJs _ _ _ (NumericLiteral n) = JSNumericLiteral n-valueToJs _ _ _ (StringLiteral s) = JSStringLiteral s-valueToJs _ _ _ (BooleanLiteral b) = JSBooleanLiteral b-valueToJs opts m e (ArrayLiteral xs) = JSArrayLiteral (map (valueToJs opts m e) xs)-valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral (map (second (valueToJs opts m e)) ps)-valueToJs opts m e (ObjectUpdate o ps) = extendObj (valueToJs opts m e o) (map (second (valueToJs opts m e)) ps)-valueToJs _ m _ (Constructor name) = qualifiedToJS m (Ident . runProperName) name-valueToJs opts m e (Case values binders) = bindersToJs opts m e binders (map (valueToJs opts m e) values)-valueToJs opts m e (IfThenElse cond th el) = JSConditional (valueToJs opts m e cond) (valueToJs opts m e th) (valueToJs opts m e el)-valueToJs opts m e (Accessor prop val) = accessorString prop (valueToJs opts m e val)-valueToJs opts m e (App val arg) = JSApp (valueToJs opts m e val) [valueToJs opts m e arg]-valueToJs opts m e (Let ds val) = JSApp (JSFunction Nothing [] (JSBlock (concat (mapMaybe (flip (declToJs opts m) e) ds) ++ [JSReturn $ valueToJs opts m e val]))) []-valueToJs opts m e (Abs (Left arg) val) = JSFunction Nothing [identToJs arg] (JSBlock [JSReturn (valueToJs opts m (bindName m arg e) val)])-valueToJs opts m e (TypedValue _ (Abs (Left arg) val) ty) | optionsPerformRuntimeTypeChecks opts = let arg' = identToJs arg in JSFunction Nothing [arg'] (JSBlock $ runtimeTypeChecks arg' ty ++ [JSReturn (valueToJs opts m e val)])-valueToJs _ m _ (Var ident) = varToJs m ident+valueToJs :: (Functor m, Applicative m, Monad m) => Options -> ModuleName -> Environment -> Value -> SupplyT m JS+valueToJs _ _ _ (NumericLiteral n) = return $ JSNumericLiteral n+valueToJs _ _ _ (StringLiteral s) = return $ JSStringLiteral s+valueToJs _ _ _ (BooleanLiteral b) = return $ JSBooleanLiteral b+valueToJs opts m e (ArrayLiteral xs) = JSArrayLiteral <$> mapM (valueToJs opts m e) xs+valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral <$> mapM (sndM (valueToJs opts m e)) ps+valueToJs opts m e (ObjectUpdate o ps) = do+  obj <- valueToJs opts m e o+  sts <- mapM (sndM (valueToJs opts m e)) ps+  extendObj obj sts+valueToJs _ m _ (Constructor name) = return $ qualifiedToJS m (Ident . runProperName) name+valueToJs opts m e (Case values binders) = do+  vals <- mapM (valueToJs opts m e) values+  bindersToJs opts m e binders vals+valueToJs opts m e (IfThenElse cond th el) = JSConditional <$> valueToJs opts m e cond <*> valueToJs opts m e th <*> valueToJs opts m e el+valueToJs opts m e (Accessor prop val) = accessorString prop <$> valueToJs opts m e val+valueToJs opts m e (App val arg) = JSApp <$> valueToJs opts m e val <*> (return <$> valueToJs opts m e arg)+valueToJs opts m e (Let ds val) = do+  decls <- concat . catMaybes <$> mapM (flip (declToJs opts m) e) ds+  ret <- valueToJs opts m e val+  return $ JSApp (JSFunction Nothing [] (JSBlock (decls ++ [JSReturn ret]))) []+valueToJs opts m e (Abs (Left arg) val) = do+  ret <- valueToJs opts m (bindName m arg e) val+  return $ JSFunction Nothing [identToJs arg] (JSBlock [JSReturn ret])+valueToJs opts m e (TypedValue _ (Abs (Left arg) val) ty) | optionsPerformRuntimeTypeChecks opts = do+  let arg' = identToJs arg+  ret <- valueToJs opts m e val+  return $ JSFunction Nothing [arg'] (JSBlock $ runtimeTypeChecks arg' ty ++ [JSReturn ret])+valueToJs _ m _ (Var ident) = return $ varToJs m ident valueToJs opts m e (TypedValue _ val _) = valueToJs opts m e val valueToJs opts m e (PositionedValue _ val) = valueToJs opts m e val valueToJs _ _ _ (TypeClassDictionary _ _ _) = error "Type class dictionary was not replaced"@@ -168,20 +186,22 @@ -- | -- Shallow copy an object. ---extendObj :: JS -> [(String, JS)] -> JS-extendObj obj sts = JSApp (JSFunction Nothing [] block) []+extendObj :: (Functor m, Applicative m, Monad m) => JS -> [(String, JS)] -> SupplyT m JS+extendObj obj sts = do+  newObj <- freshName+  key <- freshName+  let+    jsKey = JSVar key+    jsNewObj = JSVar newObj+    block = JSBlock (objAssign:copy:extend ++ [JSReturn jsNewObj])+    objAssign = JSVariableIntroduction newObj (Just $ JSObjectLiteral [])+    copy = JSForIn key obj $ JSBlock [JSIfElse cond assign Nothing]+    cond = JSApp (JSAccessor "hasOwnProperty" obj) [jsKey]+    assign = JSBlock [JSAssignment (JSIndexer jsKey jsNewObj) (JSIndexer jsKey obj)]+    stToAssign (s, js) = JSAssignment (JSAccessor s jsNewObj) js+    extend = map stToAssign sts+  return $ JSApp (JSFunction Nothing [] block) []   where-  [newObj, key] = take 2 . map identToJs . S.unusedNames $ used-  used = usedNamesJS obj ++ concatMap (usedNamesJS . snd) sts-  jsKey = JSVar key-  jsNewObj = JSVar newObj-  block = JSBlock (objAssign:copy:extend ++ [JSReturn jsNewObj])-  objAssign = JSVariableIntroduction newObj (Just $ JSObjectLiteral [])-  copy = JSForIn key obj $ JSBlock [JSIfElse cond assign Nothing]-  cond = JSApp (JSAccessor "hasOwnProperty" obj) [jsKey]-  assign = JSBlock [JSAssignment (JSIndexer jsKey jsNewObj) (JSIndexer jsKey obj)]-  stToAssign (s, js) = JSAssignment (JSAccessor s jsNewObj) js-  extend = map stToAssign sts  -- | -- Temporarily extends the environment with a single local variable name@@ -198,7 +218,6 @@   where   noType = error "Temporary lambda variable type was read" - -- | -- Generate code in the simplified Javascript intermediate representation for runtime type checks. --@@ -251,42 +270,31 @@ -- Generate code in the simplified Javascript intermediate representation for pattern match binders -- and guards. ---bindersToJs :: Options -> ModuleName -> Environment -> [CaseAlternative] -> [JS] -> JS-bindersToJs opts m e binders vals = runGen (map identToJs (S.unusedNames usedNames)) $ do-  valNames <- replicateM (length vals) fresh-  jss <- forM binders $ \(CaseAlternative bs grd result) -> go valNames [JSReturn (valueToJs opts m (bindNames m (concatMap binderNames bs) e) result)] bs grd-  return $ JSApp (JSFunction Nothing valNames (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))-                 vals+bindersToJs :: (Functor m, Applicative m, Monad m) => Options -> ModuleName -> Environment -> [CaseAlternative] -> [JS] -> SupplyT m JS+bindersToJs opts m e binders vals = do+  valNames <- replicateM (length vals) freshName+  let assignments = zipWith JSVariableIntroduction valNames (map Just vals)+  jss <- forM binders $ \(CaseAlternative bs grd result) -> do+    ret <- valueToJs opts m (bindNames m (concatMap binderNames bs) e) result+    go valNames [JSReturn ret] bs grd+  return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))+                 []   where-    usedNames = concatMap usedNamesJS vals ++ concatMap S.usedNamesCaseAlternative binders--    go :: [String] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]+    go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder] -> Maybe Guard -> SupplyT m [JS]     go _ done [] Nothing = return done-    go _ done [] (Just cond) = return [JSIfElse (valueToJs opts m e cond) (JSBlock done) Nothing]+    go _ done [] (Just cond) = do+      cond' <- valueToJs opts m e cond+      return [JSIfElse cond' (JSBlock done) Nothing]     go (v:vs) done' (b:bs) grd = do       done'' <- go vs done' bs grd       binderToJs m e v done'' b     go _ _ _ _ = error "Invalid arguments to bindersToJs"  -- |--- Gather all used names appearing inside a value----usedNamesJS :: JS -> [Ident]-usedNamesJS val = nub $ everythingOnJS (++) namesJS val-  where-  namesJS (JSVar name) = [Ident name]-  namesJS (JSFunction (Just name) args _) = Ident name : map Ident args-  namesJS (JSFunction Nothing args _) = map Ident args-  namesJS (JSVariableIntroduction name _) = [Ident name]-  namesJS (JSFor name _ _ _) = [Ident name]-  namesJS (JSForIn name _ _) = [Ident name]-  namesJS _ = []---- | -- Generate code in the simplified Javascript intermediate representation for a pattern match -- binder. ---binderToJs :: ModuleName -> Environment -> String -> [JS] -> Binder -> Gen [JS]+binderToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Environment -> String -> [JS] -> Binder -> SupplyT m [JS] binderToJs _ _ _ done NullBinder = return done binderToJs _ _ varName done (StringBinder str) =   return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSStringLiteral str)) (JSBlock done) Nothing]@@ -308,19 +316,19 @@                      (JSBlock js)                      Nothing]   where-  go :: Integer -> [JS] -> [Binder] -> Gen [JS]+  go :: (Functor m, Applicative m, Monad m) => Integer -> [JS] -> [Binder] -> SupplyT m [JS]   go _ done' [] = return done'   go index done' (binder:bs') = do-    argVar <- fresh+    argVar <- freshName     done'' <- go (index + 1) done' bs'     js <- binderToJs m e argVar done'' binder     return (JSVariableIntroduction argVar (Just (JSIndexer (JSNumericLiteral (Left index)) (JSAccessor "values" (JSVar varName)))) : js) binderToJs m e varName done (ObjectBinder bs) = go done bs   where-  go :: [JS] -> [(String, Binder)] -> Gen [JS]+  go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder)] -> SupplyT m [JS]   go done' [] = return done'   go done' ((prop, binder):bs') = do-    propVar <- fresh+    propVar <- freshName     done'' <- go done' bs'     js <- binderToJs m e propVar done'' binder     return (JSVariableIntroduction propVar (Just (accessorString prop (JSVar varName))) : js)@@ -328,16 +336,16 @@   js <- go done 0 bs   return [JSIfElse (JSBinary EqualTo (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing]   where-  go :: [JS] -> Integer -> [Binder] -> Gen [JS]+  go :: (Functor m, Applicative m, Monad m) => [JS] -> Integer -> [Binder] -> SupplyT m [JS]   go done' _ [] = return done'   go done' index (binder:bs') = do-    elVar <- fresh+    elVar <- freshName     done'' <- go done' (index + 1) bs'     js <- binderToJs m e elVar done'' binder     return (JSVariableIntroduction elVar (Just (JSIndexer (JSNumericLiteral (Left index)) (JSVar varName))) : js) binderToJs m e varName done (ConsBinder headBinder tailBinder) = do-  headVar <- fresh-  tailVar <- fresh+  headVar <- freshName+  tailVar <- freshName   js1 <- binderToJs m e headVar done headBinder   js2 <- binderToJs m e tailVar js1 tailBinder   return [JSIfElse (JSBinary GreaterThan (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left 0))) (JSBlock
− src/Language/PureScript/CodeGen/Monad.hs
@@ -1,43 +0,0 @@------------------------------------------------------------------------------------ Module      :  Language.PureScript.CodeGen.Monad--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT------ Maintainer  :  Phil Freeman <paf31@cantab.net>--- Stability   :  experimental--- Portability :------ |--- Code generation monad------ This monad provides a supply of fresh names which can be used to create variables.-----------------------------------------------------------------------------------{-# LANGUAGE GeneralizedNewtypeDeriving #-}--module Language.PureScript.CodeGen.Monad where--import Control.Monad.State-import Control.Applicative---- |--- Code generation monad data type----newtype Gen a = Gen { unGen :: State [String] a } deriving (Functor, Applicative, Monad, MonadState [String])---- |--- Run a computation in the code generation monad----runGen :: [String] -> Gen a -> a-runGen names = flip evalState names . unGen---- |--- Generate a fresh name----fresh :: Gen String-fresh = do-  (s:ss) <- get-  put ss-  return s
src/Language/PureScript/Environment.hs view
@@ -49,7 +49,7 @@   -- |   -- Available type class dictionaries   ---  , typeClassDictionaries :: [TypeClassDictionaryInScope]+  , typeClassDictionaries :: M.Map (Qualified Ident, Maybe ModuleName) TypeClassDictionaryInScope   -- |   -- Type classes   --@@ -60,7 +60,7 @@ -- The initial environment with no values and only the default javascript types defined -- initEnvironment :: Environment-initEnvironment = Environment M.empty primTypes M.empty M.empty [] M.empty+initEnvironment = Environment M.empty primTypes M.empty M.empty M.empty M.empty  -- | -- The type of a foreign import
src/Language/PureScript/Optimizer/Inliner.hs view
@@ -53,7 +53,11 @@ unThunk = everywhereOnJS convert   where   convert :: JS -> JS-  convert (JSBlock [JSReturn (JSApp (JSFunction Nothing [] (JSBlock body)) [])]) = JSBlock body+  convert (JSBlock []) = JSBlock []+  convert (JSBlock jss) =+    case (last jss) of+      JSReturn (JSApp (JSFunction Nothing [] (JSBlock body)) []) -> JSBlock $ init jss ++ body+      _ -> JSBlock jss   convert js = js  evaluateIifes :: JS -> JS
− src/Language/PureScript/Scope.hs
@@ -1,84 +0,0 @@------------------------------------------------------------------------------------ Module      :  Language.PureScript.Scope--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT------ Maintainer  :  Phil Freeman <paf31@cantab.net>--- Stability   :  experimental--- Portability :------ |--- Utility functions for working with names in scope-----------------------------------------------------------------------------------module Language.PureScript.Scope (-    usedNamesDecl,-    usedNamesValue,-    usedNamesBinder,-    usedNamesCaseAlternative,-    usedNamesDoNotationElement,-    unusedNames-) where--import Data.List ((\\), nub)--import Language.PureScript.Declarations-import Language.PureScript.Names--usedNames :: (Declaration -> [Ident], Value -> [Ident], Binder -> [Ident], CaseAlternative -> [Ident], DoNotationElement -> [Ident])-usedNames = everythingOnValues (++) f g h (const []) (const [])-  where-  f :: Declaration -> [Ident]-  f (ValueDeclaration name _ _ _ _) = [name]-  f _ = []--  g :: Value -> [Ident]-  g (Abs (Left arg) _) = [arg]-  g (Var (Qualified Nothing name)) = [name]-  g _ = []--  h :: Binder -> [Ident]-  h (VarBinder name) = [name]-  h _ = []---- |--- Gather all used names appearing inside a declaration----usedNamesDecl :: Declaration -> [Ident]-usedNamesDecl = let (f, _, _, _, _) = usedNames in nub . f---- |--- Gather all used names appearing inside a value----usedNamesValue :: Value -> [Ident]-usedNamesValue = let (_, f, _, _, _) = usedNames in nub . f---- |--- Gather all used names appearing inside a binder----usedNamesBinder :: Binder -> [Ident]-usedNamesBinder = let (_, _, f, _, _) = usedNames in nub . f---- |--- Gather all used names appearing inside a case alternative----usedNamesCaseAlternative :: CaseAlternative -> [Ident]-usedNamesCaseAlternative = let (_, _, _, f, _) = usedNames in nub . f---- |--- Gather all used names appearing inside a do notation element----usedNamesDoNotationElement :: DoNotationElement -> [Ident]-usedNamesDoNotationElement = let (_, _, _, _, f) = usedNames in nub . f---- |--- Generate a set of names which are unused inside a value, of the form @_{n}@ for an integer @n@----unusedNames :: [Ident] -> [Ident]-unusedNames allNames =-  let-    varNames = map (Ident . ('_' :) . show) ([1..] :: [Int])-  in-    varNames \\ allNames
src/Language/PureScript/Sugar.hs view
@@ -16,9 +16,12 @@ module Language.PureScript.Sugar (desugar, module S) where  import Control.Monad+import Control.Category ((>>>))+import Control.Monad.Trans.Class  import Language.PureScript.Declarations import Language.PureScript.Errors+import Language.PureScript.Supply  import Language.PureScript.Sugar.Operators as S import Language.PureScript.Sugar.DoNotation as S@@ -28,8 +31,6 @@ import Language.PureScript.Sugar.TypeClasses as S import Language.PureScript.Sugar.Names as S -import Control.Category ((>>>))- -- | -- The desugaring pipeline proceeds as follows: --@@ -47,12 +48,12 @@ -- --  * Qualify any unqualified names and types ---desugar :: [Module] -> Either ErrorStack [Module]+desugar :: [Module] -> SupplyT (Either ErrorStack) [Module] desugar = map removeSignedLiterals           >>> mapM desugarDoModule           >=> desugarCasesModule-          >=> desugarTypeDeclarationsModule-          >=> desugarImports-          >=> rebracket+          >=> lift . (desugarTypeDeclarationsModule+                      >=> desugarImports+                      >=> rebracket)           >=> desugarTypeClasses-          >=> createBindingGroupsModule+          >=> lift . createBindingGroupsModule
src/Language/PureScript/Sugar/CaseDeclarations.hs view
@@ -23,43 +23,41 @@ import Data.List (groupBy)  import Control.Applicative-import Control.Monad ((<=<), forM, join, unless)+import Control.Monad ((<=<), forM, join, unless, replicateM) import Control.Monad.Error.Class  import Language.PureScript.Names import Language.PureScript.Declarations-import Language.PureScript.Scope import Language.PureScript.Environment import Language.PureScript.Errors+import Language.PureScript.Supply  -- | -- Replace all top-level binders in a module with case expressions. ---desugarCasesModule :: [Module] -> Either ErrorStack [Module]+desugarCasesModule :: [Module] -> SupplyT (Either ErrorStack) [Module] desugarCasesModule ms = forM ms $ \(Module name ds exps) ->   rethrow (strMsg ("Error in module " ++ show name) <>) $-    Module name <$> (desugarCases . desugarAbs $ ds) <*> pure exps+    Module name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps -desugarAbs :: [Declaration] -> [Declaration]-desugarAbs = map f+desugarAbs :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]+desugarAbs = mapM f   where-  (f, _, _) = everywhereOnValues id replace id+  (f, _, _) = everywhereOnValuesM return replace return -  replace (Abs (Right binder) val) =-    let-      used = usedNamesBinder binder ++ usedNamesValue val-      ident = head $ unusedNames used-    in-      Abs (Left ident) $ Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing val]-  replace other = other+  replace :: Value -> SupplyT (Either ErrorStack) Value+  replace (Abs (Right binder) val) = do+    ident <- Ident <$> freshName+    return $ Abs (Left ident) $ Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing val]+  replace other = return other  -- | -- Replace all top-level binders with case expressions. ---desugarCases :: [Declaration] -> Either ErrorStack [Declaration]+desugarCases :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration] desugarCases = desugarRest <=< fmap join . mapM toDecls . groupBy inSameGroup   where-    desugarRest :: [Declaration] -> Either ErrorStack [Declaration]+    desugarRest :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]     desugarRest (TypeInstanceDeclaration name constraints className tys ds : rest) =       (:) <$> (TypeInstanceDeclaration name constraints className tys <$> desugarCases ds) <*> desugarRest rest     desugarRest (ValueDeclaration name nameKind bs g val : rest) =@@ -80,7 +78,7 @@ inSameGroup d1 (PositionedDeclaration _ d2) = inSameGroup d1 d2 inSameGroup _ _ = False -toDecls :: [Declaration] -> Either ErrorStack [Declaration]+toDecls :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration] toDecls [ValueDeclaration ident nameKind bs Nothing val] | all isVarBinder bs = do   let args = map (\(VarBinder arg) -> arg) bs       body = foldr (Abs . Left) val args@@ -89,7 +87,8 @@   let tuples = map toTuple ds   unless (all ((== length bs) . length . fst) tuples) $       throwError $ mkErrorStack ("Argument list lengths differ in declaration " ++ show ident) Nothing-  return [makeCaseDeclaration ident tuples]+  caseDecl <- makeCaseDeclaration ident tuples+  return [caseDecl] toDecls (PositionedDeclaration pos d : ds) = do   (d' : ds') <- rethrowWithPosition pos $ toDecls (d : ds)   return (PositionedDeclaration pos d' : ds')@@ -104,15 +103,13 @@ toTuple (PositionedDeclaration _ d) = toTuple d toTuple _ = error "Not a value declaration" -makeCaseDeclaration :: Ident -> [([Binder], (Maybe Guard, Value))] -> Declaration-makeCaseDeclaration ident alternatives =+makeCaseDeclaration :: Ident -> [([Binder], (Maybe Guard, Value))] -> SupplyT (Either ErrorStack) Declaration+makeCaseDeclaration ident alternatives = do+  let argPattern = length . fst . head $ alternatives+  args <- map Ident <$> replicateM argPattern freshName   let-    argPattern = length . fst . head $ alternatives-    args = take argPattern $ unusedNames used-    used = concatMap (\(bs, (grd, val)) -> concatMap usedNamesBinder bs ++ maybe [] usedNamesValue grd ++ usedNamesValue val) alternatives     vars = map (Var . Qualified Nothing) args     binders = [ CaseAlternative bs g val | (bs, (g, val)) <- alternatives ]     value = foldr (Abs . Left) (Case vars binders) args-  in-    ValueDeclaration ident Value [] Nothing value+  return $ ValueDeclaration ident Value [] Nothing value 
src/Language/PureScript/Sugar/DoNotation.hs view
@@ -19,25 +19,27 @@ ) where  import Language.PureScript.Names-import Language.PureScript.Scope import Language.PureScript.Declarations import Language.PureScript.Errors+import Language.PureScript.Supply  import qualified Language.PureScript.Constants as C  import Control.Applicative+import Control.Monad.Trans.Class  -- | -- Replace all @DoNotationBind@ and @DoNotationValue@ constructors with applications of the Prelude.(>>=) function, -- and all @DoNotationLet@ constructors with let expressions. ---desugarDoModule :: Module -> Either ErrorStack Module+desugarDoModule :: Module -> SupplyT (Either ErrorStack) Module desugarDoModule (Module mn ds exts) = Module mn <$> mapM desugarDo ds <*> pure exts -desugarDo :: Declaration -> Either ErrorStack Declaration-desugarDo =+desugarDo :: Declaration -> SupplyT (Either ErrorStack) Declaration+desugarDo (PositionedDeclaration pos d) = (PositionedDeclaration pos) <$> (rethrowWithPosition pos $ desugarDo d)+desugarDo d =   let (f, _, _) = everywhereOnValuesM return replace return-  in f+  in f d   where   prelude :: ModuleName   prelude = ModuleName [ProperName C.prelude]@@ -45,28 +47,28 @@   bind :: Value   bind = Var (Qualified (Just prelude) (Op (C.>>=))) -  replace :: Value -> Either ErrorStack Value+  replace :: Value -> SupplyT (Either ErrorStack) Value   replace (Do els) = go els+  replace (PositionedValue pos v) = PositionedValue pos <$> rethrowWithPosition pos (replace v)   replace other = return other -  go :: [DoNotationElement] -> Either ErrorStack Value+  go :: [DoNotationElement] -> SupplyT (Either ErrorStack) Value   go [] = error "The impossible happened in desugarDo"   go [DoNotationValue val] = return val   go (DoNotationValue val : rest) = do     rest' <- go rest     return $ App (App bind val) (Abs (Left (Ident "_")) rest')-  go [DoNotationBind _ _] = Left $ mkErrorStack "Bind statement cannot be the last statement in a do block" Nothing+  go [DoNotationBind _ _] = lift $ Left $ mkErrorStack "Bind statement cannot be the last statement in a do block" Nothing   go (DoNotationBind NullBinder val : rest) = go (DoNotationValue val : rest)   go (DoNotationBind (VarBinder ident) val : rest) = do     rest' <- go rest     return $ App (App bind val) (Abs (Left ident) rest')   go (DoNotationBind binder val : rest) = do     rest' <- go rest-    let used = concatMap usedNamesDoNotationElement rest-        ident = head $ unusedNames used+    ident <- Ident <$> freshName     return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing rest']))-  go [DoNotationLet _] = Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing+  go [DoNotationLet _] = lift $ Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing   go (DoNotationLet ds : rest) = do     rest' <- go rest     return $ Let ds rest'-  go (PositionedDoNotationElement pos el : rest) = PositionedValue pos <$> go (el : rest)+  go (PositionedDoNotationElement pos el : rest) = rethrowWithPosition pos $ PositionedValue pos <$> go (el : rest)
src/Language/PureScript/Sugar/TypeClasses.hs view
@@ -24,6 +24,7 @@ import Language.PureScript.Sugar.CaseDeclarations import Language.PureScript.Environment import Language.PureScript.Errors+import Language.PureScript.Supply import Language.PureScript.Pretty.Types (prettyPrintTypeAtom)  import qualified Language.PureScript.Constants as C@@ -40,13 +41,13 @@  type MemberMap = M.Map (ModuleName, ProperName) Declaration -type Desugar = StateT MemberMap (Either ErrorStack)+type Desugar = StateT MemberMap (SupplyT (Either ErrorStack))  -- | -- Add type synonym declarations for type class dictionary types, and value declarations for type class -- instance dictionary expressions. ---desugarTypeClasses :: [Module] -> Either ErrorStack [Module]+desugarTypeClasses :: [Module] -> SupplyT (Either ErrorStack) [Module] desugarTypeClasses = flip evalStateT M.empty . mapM desugarModule  desugarModule :: Module -> Desugar Module@@ -160,7 +161,7 @@   m <- get    -- Lookup the type arguments and member types for the type class-  (TypeClassDeclaration _ args implies tyDecls) <- lift $+  (TypeClassDeclaration _ args implies tyDecls) <- lift . lift $     maybe (Left $ mkErrorStack ("Type class " ++ show className ++ " is undefined") Nothing) Right $       M.lookup (qualify mn className) m @@ -203,7 +204,7 @@    memberToNameAndValue :: [(Ident, Type)] -> Declaration -> Desugar (Ident, Value)   memberToNameAndValue tys' d@(ValueDeclaration ident _ _ _ _) = do-    _ <- lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'+    _ <- lift . lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'     let memberValue = typeInstanceDictionaryEntryValue d     return (ident, memberValue)   memberToNameAndValue tys' (PositionedDeclaration pos d) = rethrowWithPosition pos $ do
+ src/Language/PureScript/Supply.hs view
@@ -0,0 +1,56 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.Supply+-- Copyright   :  (c) Phil Freeman 2014+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Fresh variable supply+--+-----------------------------------------------------------------------------++{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}++module Language.PureScript.Supply where++import Data.Functor.Identity++import Control.Applicative+import Control.Monad.State+import Control.Monad.Error.Class++newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a } deriving (Functor, Applicative, Monad, MonadTrans)++runSupplyT :: Integer -> SupplyT m a -> m (a, Integer)+runSupplyT n = flip runStateT n . unSupplyT++evalSupplyT :: (Functor m) => Integer -> SupplyT m a -> m a+evalSupplyT n = fmap fst . runSupplyT n++type Supply = SupplyT Identity++runSupply :: Integer -> Supply a -> (a, Integer)+runSupply n = runIdentity . runSupplyT n++evalSupply :: Integer -> Supply a -> a+evalSupply n = runIdentity . evalSupplyT n++fresh :: (Monad m) => SupplyT m Integer+fresh = SupplyT $ do+  n <- get+  put (n + 1)+  return n++freshName :: (Functor m, Monad m) => SupplyT m String+freshName = ('_' :) . show <$> fresh++instance (MonadError e m) => MonadError e (SupplyT m) where+  throwError = SupplyT . throwError+  catchError e f = SupplyT $ catchError (unSupplyT e) (unSupplyT . f)
src/Language/PureScript/TypeChecker.hs view
@@ -84,7 +84,8 @@  addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check () addTypeClassDictionaries entries =-  modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = entries ++ (typeClassDictionaries . checkEnv $ st) } }+  let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ }  <- entries ]+  in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }  checkTypeClassInstance :: ModuleName -> Type -> Check () checkTypeClassInstance _ (TypeVar _) = return ()@@ -182,8 +183,8 @@   guardWith (strMsg ("Fixity declaration with no binding: " ++ name)) $ M.member (moduleName, Op name) $ names env   return $ d : ds typeCheckAll mainModuleName currentModule (d@(ImportDeclaration moduleName _ _) : rest) = do-  env <- getEnv-  let instances = filter (\tcd -> let Qualified (Just mn) _ = tcdName tcd in moduleName == mn) (typeClassDictionaries env)+  tcds <- getTypeClassDictionaries+  let instances = filter (\tcd -> let Qualified (Just mn) _ = tcdName tcd in moduleName == mn) tcds   addTypeClassDictionaries [ tcd { tcdName = Qualified (Just currentModule) ident, tcdType = TCDAlias (canonicalizeDictionary tcd) }                            | tcd <- instances                            , let (Qualified _ ident) = tcdName tcd
src/Language/PureScript/TypeChecker/Monad.hs view
@@ -21,6 +21,7 @@ import Language.PureScript.Types import Language.PureScript.Kinds import Language.PureScript.Names+import Language.PureScript.Declarations (canonicalizeDictionary) import Language.PureScript.Environment import Language.PureScript.TypeClassDictionaries import Language.PureScript.Options@@ -63,7 +64,8 @@ withTypeClassDictionaries :: (MonadState CheckState m) => [TypeClassDictionaryInScope] -> m a -> m a withTypeClassDictionaries entries action = do   orig <- get-  modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = entries ++ (typeClassDictionaries . checkEnv $ st) } }+  let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ }  <- entries ]+  modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }   a <- action   modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = typeClassDictionaries . checkEnv $ orig } }   return a@@ -72,7 +74,7 @@ -- Get the currently available list of type class dictionaries -- getTypeClassDictionaries :: (Functor m, MonadState CheckState m) => m [TypeClassDictionaryInScope]-getTypeClassDictionaries = typeClassDictionaries . checkEnv <$> get+getTypeClassDictionaries = M.elems . typeClassDictionaries . checkEnv <$> get  -- | -- Temporarily bind a collection of names to local variables