Skip to content

Commit

Permalink
Adding 'it' and 'itN' for execution count N variables
Browse files Browse the repository at this point in the history
  • Loading branch information
gibiansky committed Nov 11, 2013
1 parent e02e5c2 commit ab5b30e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 14 deletions.
57 changes: 54 additions & 3 deletions Haskell-Notebook.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -224,20 +224,71 @@
"cell_type": "code",
"collapsed": false,
"input": [
"doubleIt \"hello\""
"1+1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 1,
"text": [
"2\n"
]
},
{
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"it * 2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<span style='color: red; font-style: italic;'>Couldn't match expected type `Int'<br/> with actual type `String'<br/></span>"
"<span style='color: red; font-style: italic;'>No instance for (GHC.Num.Num ()) arising from a use of `GHC.Num.*'<br/>Possible fix: add an instance declaration for (GHC.Num.Num ())<br/></span>"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 7
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"Out[1] * 2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<span style='color: red; font-style: italic;'>Not in scope: data constructor `Out'<br/></span>"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
Expand Down
33 changes: 23 additions & 10 deletions IHaskell/Eval/Evaluate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,24 @@ makeWrapperStmts = (fileName, initStmts, postStmts)
randStr = "1345964344725219474" :: String
fileVariable = "file_var_" ++ randStr
oldVariable = fileVariable ++ "_old"
itVariable = "it_var_" ++ randStr
fileName = ".ihaskell_capture"

postStmts :: [String]
postStmts = [
"hFlush stdout",
printf "hDuplicateTo %s stdout" oldVariable,
printf "hClose %s" fileVariable]

initStmts :: [String]
initStmts = [
printf "let %s = it" itVariable,
printf "%s <- openFile \"%s\" WriteMode" fileVariable fileName,
printf "%s <- hDuplicate stdout" oldVariable,
printf "hDuplicateTo %s stdout" fileVariable]
printf "hDuplicateTo %s stdout" fileVariable,
printf "let it = %s" itVariable]

postStmts :: [String]
postStmts = [
printf "let %s = it" itVariable,
"hFlush stdout",
printf "hDuplicateTo %s stdout" oldVariable,
printf "hClose %s" fileVariable,
printf "let it = %s" itVariable]

write :: GhcMonad m => String -> m ()
write x = when debug $ liftIO $ hPutStrLn stderr x
Expand Down Expand Up @@ -101,15 +106,21 @@ interpret action = runGhc (Just libdir) $ do
imports <- mapM parseImportDecl globalImports
setContext $ map IIDecl imports

-- Give a value for `it`. This is required due to the way we handle `it`
-- in the wrapper statements - if it doesn't exist, the first statement
-- will fail.
runStmt "()" RunToCompletion

-- Run the rest of the interpreter
action

-- | Evaluate some IPython input code.
evaluate :: String -- ^ Haskell code or other interpreter commands.
evaluate :: Int -- ^ The execution counter of this evaluation.
-> String -- ^ Haskell code or other interpreter commands.
-> Interpreter [DisplayData] -- ^ All of the output.
evaluate code
evaluate execCount code
| strip code == "" = return []
| otherwise = joinDisplays <$> runUntilFailure (parseCommands $ strip code)
| otherwise = joinDisplays <$> runUntilFailure (parseCommands (strip code) ++ [storeItCommand execCount])
where
runUntilFailure :: [Command] -> Interpreter [DisplayData]
runUntilFailure [] = return []
Expand All @@ -121,6 +132,8 @@ evaluate code
return $ result ++ restRes
Failure -> return result

storeItCommand execCount = Statement $ printf "let it%d = it" execCount

joinDisplays :: [DisplayData] -> [DisplayData]
joinDisplays displays =
let isPlain (Display mime _) = (mime == PlainText)
Expand Down
2 changes: 1 addition & 1 deletion Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ replyTo interface ExecuteRequest{ getCode = code } replyHeader state = do
send $ PublishStatus busyHeader Busy

-- Get display data outputs of evaluating the code.
outputs <- evaluate $ Chars.unpack code
outputs <- evaluate execCount $ Chars.unpack code

-- Find all the plain text outputs.
-- Send plain text output via an output message, because we are just
Expand Down

0 comments on commit ab5b30e

Please sign in to comment.