elm-repl 0.1 → 0.1.0.1
raw patch · 3 files changed
+52/−35 lines, 3 filesdep ~Elm
Dependency ranges changed: Elm
Files
- Evaluator.hs +42/−23
- Repl.hs +8/−10
- elm-repl.cabal +2/−2
Evaluator.hs view
@@ -6,6 +6,7 @@ import qualified Language.Elm as Elm import qualified Environment as Env +import System.IO import System.IO.Error (isDoesNotExistError) import System.Directory (removeFile) import System.Exit (ExitCode(..))@@ -14,11 +15,12 @@ import Control.Exception import Control.Monad (unless) -runRepl :: Env.Repl -> IO Bool-runRepl environment =- do writeFile tempElm (Env.toElm environment)- result <- run "elm" elmArgs $ \types -> do- reformatJS tempJS+runRepl :: String -> Env.Repl -> IO Env.Repl+runRepl "" env = return env+runRepl input oldEnv =+ do writeFile tempElm $ Env.toElm newEnv+ success <- run "elm" elmArgs $ \types -> do+ reformatJS input tempJS run "node" nodeArgs $ \value' -> let value = BSC.init value' tipe = scrapeOutputType types@@ -26,10 +28,13 @@ BSC.isInfixOf "\n" tipe || BSC.length value + BSC.length tipe > 80 message = BS.concat [ if isTooLong then value' else value, tipe ]- in unless (BSC.null value') $ BSC.putStrLn message+ in do unless (BSC.null value') $ BSC.hPutStrLn stdout message+ return True removeIfExists tempElm- return result+ return $ if success then newEnv else oldEnv where+ newEnv = Env.insert input oldEnv+ tempElm = "repl-temp-000.elm" tempJS = "build" </> replaceExtension tempElm "js" @@ -37,32 +42,46 @@ elmArgs = ["--make", "--only-js", "--print-types", tempElm] run name args nextComputation =- let failure message = BSC.putStrLn message >> return False- missingExe = unlines [ "Error: '" ++ name ++ "' command not found."- , " Do you have it installed?"- , " Can it be run from anywhere? I.e. is it on your PATH?" ]- in- do (_, stdout, _, handle') <- createProcess (proc name args) { std_out = CreatePipe }+ do (_, stdout, stderr, handle') <-+ createProcess (proc name args) { std_out = CreatePipe+ , std_err = CreatePipe } exitCode <- waitForProcess handle'- case (exitCode, stdout) of- (ExitFailure 127, _) -> failure $ BSC.pack missingExe- (_, Nothing) -> failure "Unknown error!"- (ExitFailure _, Just out) -> failure =<< BSC.hGetContents out- (ExitSuccess , Just out) ->- do nextComputation =<< BS.hGetContents out- return True+ case (exitCode, stdout, stderr) of+ (ExitSuccess, Just out, Just _) ->+ nextComputation =<< BS.hGetContents out+ (ExitFailure 127, Just _, Just _) -> failure missingExe+ (ExitFailure _, Just out, Just err) -> do e <- BSC.hGetContents err+ o <- BSC.hGetContents out+ failure (BS.concat [o,e])+ (_, _, _) -> failure "Unknown error!"+ where+ failure message = BSC.hPutStrLn stderr message >> return False+ missingExe = BSC.pack $ unlines $+ [ "Error: '" ++ name ++ "' command not found."+ , " Do you have it installed?"+ , " Can it be run from anywhere? I.e. is it on your PATH?" ] -reformatJS :: String -> IO ()-reformatJS tempJS =++reformatJS :: String -> String -> IO ()+reformatJS input tempJS = do rts <- BS.readFile =<< Elm.runtime src <- BS.readFile tempJS BS.length src `seq` BS.writeFile tempJS (BS.concat [rts,src,out]) where out = BS.concat- [ "var context = { inputs:[] };\n"+ [ "process.on('uncaughtException', function(err) {\n"+ , " var input = '", BSC.pack input, "';\n"+ , " var msg = (input.slice(0,7) === 'import ') ? ", badImport, " : ('Runtime error: ' + err);\n"+ , " process.stderr.write(msg);\n"+ , " process.exit(1);\n"+ , "});\n"+ , "var context = { inputs:[] };\n" , "var repl = Elm.Repl.make(context);\n" , "if ('", Env.output, "' in repl)\n" , " console.log(context.Native.Show.values.show(repl.", Env.output, "));" ]++ badImport = "('Error: unable to import \\\"' + input.slice(7).replace(/ /g,'') + '\\\".\\nIt may rely on a browser API that is unavailable on the command line.')"+ scrapeOutputType :: BS.ByteString -> BS.ByteString scrapeOutputType types
Repl.hs view
@@ -13,17 +13,15 @@ loop :: Env.Repl -> InputT IO () loop environment@(Env.Repl _ _ _ wasCtrlC) = do str' <- handleInterrupt (return Nothing) getInput- let env = environment {Env.ctrlc = False} case str' of- Nothing -> if wasCtrlC then lift $ exitWith (ExitFailure 130)- else do - lift $ putStrLn "(Ctrl-C again to exit)"- loop $ environment {Env.ctrlc = True}- Just "" -> loop env- Just str -> do- let env' = Env.insert str env- success <- liftIO $ Eval.runRepl env'- loop (if success then env' else env)+ Just input ->+ loop =<< liftIO (Eval.runRepl input $ environment {Env.ctrlc = False})++ Nothing+ | wasCtrlC -> lift $ exitWith (ExitFailure 130)+ | otherwise -> do + lift $ putStrLn "(Ctrl-C again to exit)"+ loop $ environment {Env.ctrlc = True} getInput :: InputT IO (Maybe String) getInput = get "> " ""
elm-repl.cabal view
@@ -1,5 +1,5 @@ Name: elm-repl-Version: 0.1+Version: 0.1.0.1 Synopsis: a REPL for Elm Description: A read-eval-print-loop (REPL) for evaluating Elm expressions, definitions, ADTs, and module imports. This tool is meant to@@ -34,7 +34,7 @@ bytestring, containers >= 0.3, directory,- Elm >= 0.10,+ Elm >= 0.10.0.2, filepath, haskeline, transformers >= 0.2,