Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
c53f70d8
Commit
c53f70d8
authored
Mar 21, 2015
by
Andrew Gibiansky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Formatting ipython-kernel
parent
7ba7c4d1
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
836 additions
and
890 deletions
+836
-890
Calc.hs
ipython-kernel/examples/Calc.hs
+123
-120
EasyKernel.hs
ipython-kernel/src/IHaskell/IPython/EasyKernel.hs
+136
-165
Kernel.hs
ipython-kernel/src/IHaskell/IPython/Kernel.hs
+8
-11
Parser.hs
ipython-kernel/src/IHaskell/IPython/Message/Parser.hs
+46
-49
UUID.hs
ipython-kernel/src/IHaskell/IPython/Message/UUID.hs
+14
-17
Writer.hs
ipython-kernel/src/IHaskell/IPython/Message/Writer.hs
+92
-107
Stdin.hs
ipython-kernel/src/IHaskell/IPython/Stdin.hs
+50
-60
Types.hs
ipython-kernel/src/IHaskell/IPython/Types.hs
+293
-291
ZeroMQ.hs
ipython-kernel/src/IHaskell/IPython/ZeroMQ.hs
+65
-66
verify_formatting.py
verify_formatting.py
+9
-4
No files found.
ipython-kernel/examples/Calc.hs
View file @
c53f70d8
{-# LANGUAGE FlexibleContexts, FlexibleInstances, OverloadedStrings, MultiWayIf #-}
module
Main
where
import
Control.Applicative
...
...
@@ -20,7 +21,8 @@ import IHaskell.IPython.EasyKernel (installProfile, easyKernel, KernelConfig(..)
import
System.Environment
(
getArgs
)
import
System.FilePath
((
</>
))
import
Text.Parsec
(
Parsec
,
ParseError
,
alphaNum
,
char
,
letter
,
oneOf
,
optionMaybe
,
runParser
,
(
<?>
))
import
Text.Parsec
(
Parsec
,
ParseError
,
alphaNum
,
char
,
letter
,
oneOf
,
optionMaybe
,
runParser
,
(
<?>
))
import
qualified
Text.Parsec.Token
as
P
import
qualified
Paths_ipython_kernel
as
Paths
...
...
@@ -28,21 +30,16 @@ import qualified Paths_ipython_kernel as Paths
---------------------------------------------------------
-- Hutton's Razor, plus time delays, plus a global state
---------------------------------------------------------
-- | This language is Hutton's Razor with two added operations that
-- are needed to demonstrate the kernel features: a global state,
-- accessed and modified using Count, and a sleep operation.
--
-- | This language is Hutton's Razor with two added operations that are needed to demonstrate the
-- kernel features: a global state, accessed and modified using Count, and a sleep operation.
data
Razor
=
I
Integer
|
Plus
Razor
Razor
|
SleepThen
Double
Razor
|
Count
deriving
(
Read
,
Show
,
Eq
)
---------
-- Parser
---------
-- ------- Parser -------
razorDef
::
Monad
m
=>
P
.
GenLanguageDef
String
a
m
razorDef
=
P
.
LanguageDef
{
P
.
commentStart
=
"(*"
...
...
@@ -83,7 +80,8 @@ literal :: Parsec String a Razor
literal
=
I
<$>
integer
sleepThen
::
Parsec
String
a
Razor
sleepThen
=
do
keyword
"sleep"
sleepThen
=
do
keyword
"sleep"
delay
<-
float
<?>
"seconds"
keyword
"then"
body
<-
expr
...
...
@@ -94,8 +92,11 @@ count :: Parsec String a Razor
count
=
keyword
"count"
>>
return
Count
expr
::
Parsec
String
a
Razor
expr
=
do
one
<-
parens
expr
<|>
literal
<|>
sleepThen
<|>
count
rest
<-
optionMaybe
(
do
op
<-
operator
expr
=
do
one
<-
parens
expr
<|>
literal
<|>
sleepThen
<|>
count
rest
<-
optionMaybe
(
do
op
<-
operator
guard
(
op
==
"+"
)
expr
)
case
rest
of
...
...
@@ -105,12 +106,7 @@ expr = do one <- parens expr <|> literal <|> sleepThen <|> count
parse
::
String
->
Either
ParseError
Razor
parse
=
runParser
expr
()
"(input)"
----------------------
-- Language operations
----------------------
-- | Completion
-- -------------------- Language operations -------------------- | Completion
langCompletion
::
T
.
Text
->
T
.
Text
->
Int
->
Maybe
([
T
.
Text
],
T
.
Text
,
T
.
Text
)
langCompletion
_code
line
col
=
let
(
before
,
_
)
=
T
.
splitAt
col
line
...
...
@@ -123,20 +119,18 @@ langCompletion _code line col =
lastMaybe
(
_
:
xs
)
=
lastMaybe
xs
matchesFor
::
String
->
[
String
]
matchesFor
input
=
filter
(
isPrefixOf
input
)
available
available
=
[
"sleep"
,
"then"
,
"end"
,
"count"
]
++
map
show
[(
-
1000
::
Int
)
..
1000
]
available
=
[
"sleep"
,
"then"
,
"end"
,
"count"
]
++
map
show
[(
-
1000
::
Int
)
..
1000
]
-- | Documentation lookup
langInfo
::
T
.
Text
->
Maybe
(
T
.
Text
,
T
.
Text
,
T
.
Text
)
langInfo
obj
=
if
|
any
(
T
.
isPrefixOf
obj
)
[
"sleep"
,
"then"
,
"end"
]
->
Just
(
obj
,
sleepDocs
,
sleepType
)
|
T
.
isPrefixOf
obj
"count"
->
Just
(
obj
,
countDocs
,
countType
)
if
|
any
(
T
.
isPrefixOf
obj
)
[
"sleep"
,
"then"
,
"end"
]
->
Just
(
obj
,
sleepDocs
,
sleepType
)
|
T
.
isPrefixOf
obj
"count"
->
Just
(
obj
,
countDocs
,
countType
)
|
obj
==
"+"
->
Just
(
obj
,
plusDocs
,
plusType
)
|
T
.
all
isDigit
obj
->
Just
(
obj
,
intDocs
obj
,
intType
)
|
[
x
,
y
]
<-
T
.
splitOn
"."
obj
,
T
.
all
isDigit
x
,
T
.
all
isDigit
y
->
Just
(
obj
,
floatDocs
obj
,
floatType
)
|
[
x
,
y
]
<-
T
.
splitOn
"."
obj
,
T
.
all
isDigit
x
,
T
.
all
isDigit
y
->
Just
(
obj
,
floatDocs
obj
,
floatType
)
|
otherwise
->
Nothing
where
sleepDocs
=
"sleep DURATION then VALUE end: sleep DURATION seconds, then eval VALUE"
...
...
@@ -155,11 +149,11 @@ data IntermediateEvalRes = Got Razor Integer
|
Waiting
Double
deriving
Show
-- | Cons for lists of trace elements - in this case, "sleeping"
--
messages should replace old ones to
create a countdown effect.
-- | Cons for lists of trace elements - in this case, "sleeping"
messages should replace old ones to
-- create a countdown effect.
consRes
::
IntermediateEvalRes
->
[
IntermediateEvalRes
]
->
[
IntermediateEvalRes
]
consRes
r
@
(
Waiting
_
)
(
Waiting
_
:
s
)
=
r
:
s
consRes
r
s
=
r
:
s
consRes
r
@
(
Waiting
_
)
(
Waiting
_
:
s
)
=
r
:
s
consRes
r
s
=
r
:
s
-- | Execute an expression.
execRazor
::
MVar
Integer
-- ^ The global counter state
...
...
@@ -168,9 +162,10 @@ execRazor :: MVar Integer -- ^ The global counter state
->
([
IntermediateEvalRes
]
->
IO
()
)
-- ^ Callback for intermediate results
->
StateT
([
IntermediateEvalRes
],
T
.
Text
)
IO
Integer
execRazor
_
x
@
(
I
i
)
_
_
=
modify
(
second
(
<>
(
T
.
pack
(
show
x
)
)))
>>
return
i
modify
(
second
(
<>
T
.
pack
(
show
x
)))
>>
return
i
execRazor
val
tm
@
(
Plus
x
y
)
clear
send
=
do
modify
(
second
(
<>
(
T
.
pack
(
show
tm
))))
do
modify
(
second
(
<>
T
.
pack
(
show
tm
)))
x'
<-
execRazor
val
x
clear
send
modify
(
first
$
consRes
(
Got
x
x'
))
sendState
...
...
@@ -181,33 +176,39 @@ execRazor val tm@(Plus x y) clear send =
modify
(
first
$
consRes
(
Got
tm
res
))
sendState
return
res
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
execRazor
val
(
SleepThen
delay
body
)
clear
send
|
delay
<=
0.0
=
execRazor
val
body
clear
send
|
delay
>
0.1
=
do
modify
(
first
$
consRes
(
Waiting
delay
))
|
delay
>
0.1
=
do
modify
(
first
$
consRes
(
Waiting
delay
))
sendState
liftIO
$
threadDelay
100000
execRazor
val
(
SleepThen
(
delay
-
0.1
)
body
)
clear
send
|
otherwise
=
do
modify
(
first
$
consRes
(
Waiting
0
))
|
otherwise
=
do
modify
(
first
$
consRes
(
Waiting
0
))
sendState
liftIO
$
threadDelay
(
floor
(
delay
*
1000000
))
execRazor
val
body
clear
send
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
execRazor
val
Count
clear
send
=
do
i
<-
liftIO
$
takeMVar
val
modify
(
first
$
consRes
(
Got
Count
i
))
sendState
liftIO
$
putMVar
val
(
i
+
1
)
liftIO
$
putMVar
val
(
i
+
1
)
return
i
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
where
sendState
=
liftIO
clear
>>
fst
<$>
get
>>=
liftIO
.
send
-- | Generate a language configuration for some initial state
mkConfig
::
MVar
Integer
-- ^ The internal state of the execution
->
KernelConfig
IO
[
IntermediateEvalRes
]
(
Either
ParseError
Integer
)
mkConfig
var
=
KernelConfig
{
languageName
=
"expanded_huttons_razor"
,
languageVersion
=
[
0
,
1
,
0
]
,
languageVersion
=
[
0
,
1
,
0
]
,
profileSource
=
Just
.
(
</>
"calc_profile.tar"
)
<$>
Paths
.
getDataDir
,
displayResult
=
displayRes
,
displayOutput
=
displayOut
...
...
@@ -235,7 +236,8 @@ mkConfig var = KernelConfig
return
(
Right
res
,
Ok
,
T
.
unpack
pager
)
main
::
IO
()
main
=
do
args
<-
getArgs
main
=
do
args
<-
getArgs
val
<-
newMVar
1
case
args
of
[
"kernel"
,
profileFile
]
->
...
...
@@ -246,4 +248,5 @@ main = do args <- getArgs
_
->
do
putStrLn
"Usage:"
putStrLn
"simple-calc-example setup -- set up the profile"
putStrLn
"simple-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
putStrLn
"simple-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
ipython-kernel/src/IHaskell/IPython/EasyKernel.hs
View file @
c53f70d8
This diff is collapsed.
Click to expand it.
ipython-kernel/src/IHaskell/IPython/Kernel.hs
View file @
c53f70d8
-- | This module exports all the types and functions necessary to create an
-- IPython language kernel that supports the @ipython console@ and @ipython
-- notebook@ frontends.
module
IHaskell.IPython.Kernel
(
module
X
,
)
where
-- | This module exports all the types and functions necessary to create an IPython language kernel
-- that supports the @ipython console@ and @ipython notebook@ frontends.
module
IHaskell.IPython.Kernel
(
module
X
)
where
import
IHaskell.IPython.Types
as
X
import
IHaskell.IPython.Message.Writer
as
X
...
...
ipython-kernel/src/IHaskell/IPython/Message/Parser.hs
View file @
c53f70d8
{-# LANGUAGE OverloadedStrings #-}
-- | Description : Parsing messages received from IPython
--
-- This module is responsible for converting from low-level ByteStrings
--
obtained from the 0MQ sockets into Messages. The only exposed function is
--
`parseMessage`, which should only be used in
the low-level 0MQ interface.
-- This module is responsible for converting from low-level ByteStrings
obtained from the 0MQ
--
sockets into Messages. The only exposed function is `parseMessage`, which should only be used in
-- the low-level 0MQ interface.
module
IHaskell.IPython.Message.Parser
(
parseMessage
)
where
import
Data.Aeson
((
.:
),
decode
,
Result
(
..
),
Object
)
...
...
@@ -17,9 +18,7 @@ import IHaskell.IPython.Types
type
LByteString
=
Lazy
.
ByteString
----- External interface -----
-- | Parse a message from its ByteString components into a Message.
-- --- External interface ----- | Parse a message from its ByteString components into a Message.
parseMessage
::
[
ByteString
]
-- ^ The list of identifiers sent with the message.
->
ByteString
-- ^ The header data.
->
ByteString
-- ^ The parent header, which is just "{}" if there is no header.
...
...
@@ -32,16 +31,15 @@ parseMessage idents headerData parentHeader metadata content =
messageWithoutHeader
=
parser
messageType
$
Lazy
.
fromStrict
content
in
messageWithoutHeader
{
header
=
header
}
----- Module internals -----
-- | Parse a header from its ByteString components into a MessageHeader.
-- --- Module internals ----- | Parse a header from its ByteString components into a MessageHeader.
parseHeader
::
[
ByteString
]
-- ^ The list of identifiers.
->
ByteString
-- ^ The header data.
->
ByteString
-- ^ The parent header, or "{}" for Nothing.
->
ByteString
-- ^ The metadata, or "{}" for an empty map.
->
MessageHeader
-- The resulting message header.
parseHeader
idents
headerData
parentHeader
metadata
=
MessageHeader
{
identifiers
=
idents
MessageHeader
{
identifiers
=
idents
,
parentHeader
=
parentResult
,
metadata
=
metadataMap
,
messageId
=
messageUUID
...
...
@@ -50,8 +48,8 @@ parseHeader idents headerData parentHeader metadata =
,
msgType
=
messageType
}
where
-- Decode the header data and the parent header data into JSON objects.
--
If the parent header data is
absent, just have Nothing instead.
-- Decode the header data and the parent header data into JSON objects.
If the parent header data is
-- absent, just have Nothing instead.
Just
result
=
decode
$
Lazy
.
fromStrict
headerData
::
Maybe
Object
parentResult
=
if
parentHeader
==
"{}"
then
Nothing
...
...
@@ -71,8 +69,8 @@ noHeader :: MessageHeader
noHeader
=
error
"No header created"
parser
::
MessageType
-- ^ The message type being parsed.
->
LByteString
->
Message
-- ^ The parser that converts the body into a message.
--
This message
should have an undefined header.
->
LByteString
->
Message
-- ^ The parser that converts the body into a message.
This message
-- should have an undefined header.
parser
KernelInfoRequestMessage
=
kernelInfoRequestParser
parser
ExecuteRequestMessage
=
executeRequestParser
parser
CompleteRequestMessage
=
completeRequestParser
...
...
@@ -85,13 +83,12 @@ parser CommCloseMessage = commCloseParser
parser
HistoryRequestMessage
=
historyRequestParser
parser
other
=
error
$
"Unknown message type "
++
show
other
-- | Parse a kernel info request.
--
A kernel info request has no auxiliary information, so ignore the
body.
-- | Parse a kernel info request.
A kernel info request has no auxiliary information, so ignore the
-- body.
kernelInfoRequestParser
::
LByteString
->
Message
kernelInfoRequestParser
_
=
KernelInfoRequest
{
header
=
noHeader
}
-- | Parse an execute request.
-- Fields used are:
-- | Parse an execute request. Fields used are:
-- 1. "code": the code to execute.
-- 2. "silent": whether to execute silently.
-- 3. "store_history": whether to include this in history.
...
...
@@ -107,7 +104,8 @@ executeRequestParser content =
return
(
code
,
silent
,
storeHistory
,
allowStdin
)
Just
decoded
=
decode
content
Success
(
code
,
silent
,
storeHistory
,
allowStdin
)
=
parse
parser
decoded
in
ExecuteRequest
{
header
=
noHeader
in
ExecuteRequest
{
header
=
noHeader
,
getCode
=
code
,
getSilent
=
silent
,
getAllowStdin
=
allowStdin
...
...
@@ -147,7 +145,6 @@ objectInfoRequestParser = requestParser $ \obj -> do
dlevel
<-
obj
.:
"detail_level"
return
$
ObjectInfoRequest
noHeader
oname
dlevel
shutdownRequestParser
::
LByteString
->
Message
shutdownRequestParser
=
requestParser
$
\
obj
->
do
code
<-
obj
.:
"restart"
...
...
ipython-kernel/src/IHaskell/IPython/Message/UUID.hs
View file @
c53f70d8
-- | Description : UUID generator and data structure
--
-- Generate, parse, and pretty print UUIDs for use with IPython.
module
IHaskell.IPython.Message.UUID
(
UUID
,
random
,
randoms
,
)
where
module
IHaskell.IPython.Message.UUID
(
UUID
,
random
,
randoms
)
where
import
Control.Monad
(
mzero
,
replicateM
)
import
Control.Applicative
((
<$>
))
...
...
@@ -12,15 +9,15 @@ import Data.Text (pack)
import
Data.Aeson
import
Data.UUID.V4
(
nextRandom
)
-- We use an internal string representation because for the purposes of
-- IPython, it matters whether the letters are uppercase or lowercase and
-- whether the dashes are present in the correct locations. For the
-- purposes of new UUIDs, it does not matter, but IPython expects UUIDs
-- passed to kernels to be returned unchanged, so we cannot actually parse
-- them.
-- | A UUID (universally unique identifier).
data
UUID
=
UUID
String
deriving
(
Show
,
Read
,
Eq
,
Ord
)
data
UUID
=
-- We use an internal string representation because for the purposes of IPython, it
-- matters whether the letters are uppercase or lowercase and whether the dashes are
-- present in the correct locations. For the purposes of new UUIDs, it does not matter,
-- but IPython expects UUIDs passed to kernels to be returned unchanged, so we cannot
-- actually parse them.
UUID
String
deriving
(
Show
,
Read
,
Eq
,
Ord
)
-- | Generate a list of random UUIDs.
randoms
::
Int
-- ^ Number of UUIDs to generate.
...
...
ipython-kernel/src/IHaskell/IPython/Message/Writer.hs
View file @
c53f70d8
{-# LANGUAGE OverloadedStrings #-}
-- | Description : @ToJSON@ for Messages
--
-- This module contains the @ToJSON@ instance for @Message@.
module
IHaskell.IPython.Message.Writer
(
ToJSON
(
..
)
)
where
module
IHaskell.IPython.Message.Writer
(
ToJSON
(
..
))
where
import
Data.Aeson
import
Data.Map
(
Map
)
...
...
@@ -19,99 +18,86 @@ import IHaskell.IPython.Types
-- Convert message bodies into JSON.
instance
ToJSON
Message
where
toJSON
KernelInfoReply
{
versionList
=
vers
,
language
=
language
}
=
object
[
"protocol_version"
.=
string
"5.0"
,
-- current protocol version, major and minor
"language_version"
.=
vers
,
"language"
.=
language
]
toJSON
ExecuteReply
{
status
=
status
,
executionCounter
=
counter
,
pagerOutput
=
pager
}
=
object
[
"status"
.=
show
status
,
"execution_count"
.=
counter
,
"payload"
.=
toJSON
KernelInfoReply
{
versionList
=
vers
,
language
=
language
}
=
object
[
"protocol_version"
.=
string
"5.0"
-- current protocol version, major and minor
,
"language_version"
.=
vers
,
"language"
.=
language
]
toJSON
ExecuteReply
{
status
=
status
,
executionCounter
=
counter
,
pagerOutput
=
pager
}
=
object
[
"status"
.=
show
status
,
"execution_count"
.=
counter
,
"payload"
.=
if
null
pager
then
[]
else
[
object
[
"source"
.=
string
"page"
,
"text"
.=
pager
]],
"user_variables"
.=
emptyMap
,
"user_expressions"
.=
emptyMap
else
[
object
[
"source"
.=
string
"page"
,
"text"
.=
pager
]]
,
"user_variables"
.=
emptyMap
,
"user_expressions"
.=
emptyMap
]
toJSON
PublishStatus
{
executionState
=
executionState
}
=
object
[
"execution_state"
.=
executionState
toJSON
PublishStatus
{
executionState
=
executionState
}
=
object
[
"execution_state"
.=
executionState
]
toJSON
PublishStream
{
streamType
=
streamType
,
streamContent
=
content
}
=
object
[
"data"
.=
content
,
"name"
.=
streamType
]
toJSON
PublishDisplayData
{
source
=
src
,
displayData
=
datas
}
=
object
[
"source"
.=
src
,
"metadata"
.=
object
[]
,
"data"
.=
object
(
map
displayDataToJson
datas
)]
toJSON
PublishOutput
{
executionCount
=
execCount
,
reprText
=
reprText
}
=
object
[
"data"
.=
object
[
"text/plain"
.=
reprText
],
"execution_count"
.=
execCount
,
"metadata"
.=
object
[]
]
toJSON
PublishInput
{
executionCount
=
execCount
,
inCode
=
code
}
=
object
[
"execution_count"
.=
execCount
,
"code"
.=
code
]
toJSON
(
CompleteReply
_
matches
start
end
metadata
status
)
=
object
[
"matches"
.=
matches
,
"cursor_start"
.=
start
,
"cursor_end"
.=
end
,
"metadata"
.=
metadata
,
"status"
.=
if
status
then
string
"ok"
else
"error"
]
toJSON
PublishStream
{
streamType
=
streamType
,
streamContent
=
content
}
=
object
[
"data"
.=
content
,
"name"
.=
streamType
]
toJSON
PublishDisplayData
{
source
=
src
,
displayData
=
datas
}
=
object
[
"source"
.=
src
,
"metadata"
.=
object
[]
,
"data"
.=
object
(
map
displayDataToJson
datas
)
toJSON
o
@
ObjectInfoReply
{}
=
object
[
"oname"
.=
objectName
o
,
"found"
.=
objectFound
o
,
"ismagic"
.=
False
,
"isalias"
.=
False
,
"type_name"
.=
objectTypeString
o
,
"docstring"
.=
objectDocString
o
]
toJSON
PublishOutput
{
executionCount
=
execCount
,
reprText
=
reprText
}
=
object
[
"data"
.=
object
[
"text/plain"
.=
reprText
],
"execution_count"
.=
execCount
,
"metadata"
.=
object
[]
]
toJSON
PublishInput
{
executionCount
=
execCount
,
inCode
=
code
}
=
object
[
"execution_count"
.=
execCount
,
"code"
.=
code
]
toJSON
(
CompleteReply
_
matches
start
end
metadata
status
)
=
object
[
"matches"
.=
matches
,
"cursor_start"
.=
start
,
"cursor_end"
.=
end
,
"metadata"
.=
metadata
,
"status"
.=
if
status
then
string
"ok"
else
"error"
]
toJSON
o
@
ObjectInfoReply
{}
=
object
[
"oname"
.=
objectName
o
,
"found"
.=
objectFound
o
,
"ismagic"
.=
False
,
"isalias"
.=
False
,
"type_name"
.=
objectTypeString
o
,
"docstring"
.=
objectDocString
o
]
toJSON
ShutdownReply
{
restartPending
=
restart
}
=
object
[
"restart"
.=
restart
]
toJSON
ShutdownReply
{
restartPending
=
restart
}
=
object
[
"restart"
.=
restart
]
toJSON
ClearOutput
{
wait
=
wait
}
=
object
[
"wait"
.=
wait
]
toJSON
ClearOutput
{
wait
=
wait
}
=
object
[
"wait"
.=
wait
]
toJSON
RequestInput
{
inputPrompt
=
prompt
}
=
object
[
"prompt"
.=
prompt
]
toJSON
RequestInput
{
inputPrompt
=
prompt
}
=
object
[
"prompt"
.=
prompt
]
toJSON
req
@
CommOpen
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"target_name"
.=
commTargetName
req
,
"data"
.=
commData
req
]
toJSON
req
@
CommOpen
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"target_name"
.=
commTargetName
req
,
"data"
.=
commData
req
]
toJSON
req
@
CommData
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"data"
.=
commData
req
]
toJSON
req
@
CommData
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"data"
.=
commData
req
]
toJSON
req
@
CommClose
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"data"
.=
commData
req
]
toJSON
req
@
CommClose
{}
=
object
[
"comm_id"
.=
commUuid
req
,
"data"
.=
commData
req
]
toJSON
req
@
HistoryReply
{}
=
object
[
"history"
.=
map
tuplify
(
historyReply
req
)
]
where
tuplify
(
HistoryReplyElement
sess
linum
res
)
=
(
sess
,
linum
,
case
res
of
toJSON
req
@
HistoryReply
{}
=
object
[
"history"
.=
map
tuplify
(
historyReply
req
)]
where
tuplify
(
HistoryReplyElement
sess
linum
res
)
=
(
sess
,
linum
,
case
res
of
Left
inp
->
toJSON
inp
Right
(
inp
,
out
)
->
toJSON
out
)
toJSON
body
=
error
$
"Do not know how to convert to JSON for message "
++
show
body
-- | Print an execution state as "busy", "idle", or "starting".
instance
ToJSON
ExecutionState
where
toJSON
Busy
=
String
"busy"
...
...
@@ -129,7 +115,6 @@ displayDataToJson (DisplayData mimeType dataStr) =
pack
(
show
mimeType
)
.=
String
dataStr
----- Constants -----
emptyMap
::
Map
String
String
emptyMap
=
mempty
...
...
ipython-kernel/src/IHaskell/IPython/Stdin.hs
View file @
c53f70d8
{-# LANGUAGE OverloadedStrings, DoAndIfThenElse #-}
-- | This module provides a way in which the Haskell standard input may be
--
forwarded to the IPython frontend and thus allows the notebook to use
-- the standard input.
--
| This module provides a way in which the Haskell standard input may be forwarded to the IPython
--
frontend and thus allows the notebook to use
the standard input.
--
-- This relies on the implementation of file handles in GHC, and is
-- generally unsafe and terrible. However, it is difficult to find another
-- way to do it, as file handles are generally meant to point to streams
-- and files, and not networked communication protocols.
-- This relies on the implementation of file handles in GHC, and is generally unsafe and terrible.
-- However, it is difficult to find another way to do it, as file handles are generally meant to
-- point to streams and files, and not networked communication protocols.
--
-- In order to use this module, it must first be initialized with two
-- things. First of all, in order to know how to communicate with the
-- IPython frontend, it must know the kernel profile used for
-- communication. For this, use @recordKernelProfile@ once the profile is
-- known. Both this and @recordParentHeader@ take a directory name where
-- they can store this data.
-- In order to use this module, it must first be initialized with two things. First of all, in order
-- to know how to communicate with the IPython frontend, it must know the kernel profile used for
-- communication. For this, use @recordKernelProfile@ once the profile is known. Both this and
-- @recordParentHeader@ take a directory name where they can store this data.
--
-- Finally, the module must know what @execute_request@ message is
-- currently being replied to (which will request the input). Thus, every
-- time the language kernel receives an @execute_request@ message, it
-- should inform this module via @recordParentHeader@, so that the module
-- may generate messages with an appropriate parent header set. If this is
-- not done, the IPython frontends will not recognize the target of the
-- communication.
-- Finally, the module must know what @execute_request@ message is currently being replied to (which
-- will request the input). Thus, every time the language kernel receives an @execute_request@
-- message, it should inform this module via @recordParentHeader@, so that the module may generate
-- messages with an appropriate parent header set. If this is not done, the IPython frontends will
-- not recognize the target of the communication.
--
-- Finally, in order to activate this module, @fixStdin@ must be called
-- once. It must be passed the same directory name as @recordParentHeader@
-- and @recordKernelProfile@. Note that if this is being used from within
-- the GHC API, @fixStdin@ /must/ be called from within the GHC session
-- not from the host code.
module
IHaskell.IPython.Stdin
(
fixStdin
,
recordParentHeader
,
recordKernelProfile
)
where
-- Finally, in order to activate this module, @fixStdin@ must be called once. It must be passed the
-- same directory name as @recordParentHeader@ and @recordKernelProfile@. Note that if this is being
-- used from within the GHC API, @fixStdin@ /must/ be called from within the GHC session not from
-- the host code.
module
IHaskell.IPython.Stdin
(
fixStdin
,
recordParentHeader
,
recordKernelProfile
)
where
import
Control.Concurrent
import
Control.Applicative
((
<$>
))
...
...
@@ -53,9 +43,8 @@ stdinInterface :: MVar ZeroMQStdin
{-# NOINLINE stdinInterface #-}
stdinInterface
=
unsafePerformIO
newEmptyMVar
-- | Manipulate standard input so that it is sourced from the IPython
-- frontend. This function is build on layers of deep magical hackery, so
-- be careful modifying it.
-- | Manipulate standard input so that it is sourced from the IPython frontend. This function is
-- build on layers of deep magical hackery, so be careful modifying it.
fixStdin
::
String
->
IO
()
fixStdin
dir
=
do
-- Initialize the stdin interface.
...
...
@@ -78,6 +67,7 @@ stdinOnce dir = do
hDuplicateTo
newStdin
stdin
loop
stdinInput
oldStdin
newStdin
where
loop
stdinInput
oldStdin
newStdin
=
do
let
FileHandle
_
mvar
=
stdin
...
...
@@ -98,14 +88,14 @@ getInputLine dir = do
-- Send a request for input.
uuid
<-
UUID
.
random
parentHeader
<-
read
<$>
readFile
(
dir
++
"/.last-req-header"
)
let
header
=
MessageHeader
{
username
=
username
parentHeader
,
identifiers
=
identifiers
parentHeader
,
parentHeader
=
Just
parentHeader
,
messageId
=
uuid
,
sessionId
=
sessionId
parentHeader
,
metadata
=
Map
.
fromList
[]
,
msgType
=
InputRequestMessage
let
header
=
MessageHeader
{
username
=
username
parentHeader
,
identifiers
=
identifiers
parentHeader
,
parentHeader
=
Just
parentHeader
,
messageId
=
uuid
,
sessionId
=
sessionId
parentHeader
,
metadata
=
Map
.
fromList
[]
,
msgType
=
InputRequestMessage
}
let
msg
=
RequestInput
header
""
writeChan
req
msg
...
...
ipython-kernel/src/IHaskell/IPython/Types.hs
View file @
c53f70d8
This diff is collapsed.
Click to expand it.
ipython-kernel/src/IHaskell/IPython/ZeroMQ.hs
View file @
c53f70d8
This diff is collapsed.
Click to expand it.
verify_formatting.py
View file @
c53f70d8
...
...
@@ -44,7 +44,12 @@ except:
# Find all the source files
sources
=
[]
for
root
,
dirnames
,
filenames
in
os
.
walk
(
"src"
):
for
source_dir
in
[
"src"
,
"ipython-kernel"
]:
for
root
,
dirnames
,
filenames
in
os
.
walk
(
source_dir
):
# Skip cabal dist directories
if
"dist"
in
root
:
continue
for
filename
in
filenames
:
if
filename
.
endswith
(
".hs"
):
sources
.
append
(
os
.
path
.
join
(
root
,
filename
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment