Make stdin and stdout unbuffered; add 'interpret' helper function

This commit is contained in:
darkf 2013-11-06 21:56:14 -08:00
parent 52d72a32b1
commit 0725c9735b
1 changed files with 13 additions and 5 deletions

View File

@ -10,7 +10,8 @@ import qualified Network.Socket as SO
import Data.List (intercalate)
import Control.Monad.Trans (lift)
import Control.Monad.Trans.State (StateT, runStateT, evalStateT, get, put)
import System.IO (Handle, hPutStr, hGetLine, hFlush, hClose, hIsEOF, openBinaryFile, hSetBinaryMode, IOMode(..), stdout, stdin)
import System.IO (Handle, hPutStr, hGetLine, hClose, hIsEOF, hSetBuffering,
hSetBinaryMode, openBinaryFile, IOMode(..), BufferMode(NoBuffering), stdout, stdin)
import System.Directory (doesFileExist)
import System.FilePath (FilePath, splitExtension, takeBaseName)
import AST
@ -104,13 +105,13 @@ l !=$ r = BoolV (l /= r)
_fputbytes (TupleV [StreamV h, StrV str]) = do
(handles,_) <- get
let handle = handles !! h
io <- lift $ hPutStr handle str >> hFlush handle
io <- lift $ hPutStr handle str
return UnitV
_fputstr (TupleV [StreamV h, StrV str]) = do
(handles,_) <- get
let handle = handles !! h
io <- lift $ hPutStr handle str >> hFlush handle
io <- lift $ hPutStr handle str
return UnitV
_fgetline (StreamV h) = do
@ -411,12 +412,19 @@ apply (Builtin (BIF fn)) arg = fn arg
-- some helper programs for evaluation
-- sets up stdin/stdout for binary mode
-- sets up stdin/stdout for binary mode and makes them unbuffered
initIO :: IO ()
initIO = do
hSetBinaryMode stdin True
hSetBinaryMode stdout True
hSetBuffering stdin NoBuffering
hSetBuffering stdout NoBuffering
-- Takes an interpreter state and evaluates it with the empty initial state.
interpret :: InterpState a -> IO a
interpret state = evalStateT state initialState
evalProgram :: [AST] -> InterpState Value
evalProgram nodes = foldr1 (>>) $ map eval nodes
@ -442,4 +450,4 @@ evalFile path = do
else evalString contents
evalFileV :: FilePath -> IO Value
evalFileV path = evalStateT (evalFile path) initialState
evalFileV path = interpret $ evalFile path