mirror of
https://github.com/IHaskell/IHaskell.git
synced 2025-04-17 20:06:07 +00:00
All declarations are now grouped. allows operators more easily.
This commit is contained in:
parent
c30de057c7
commit
11130856b6
@ -3,7 +3,7 @@
|
||||
"celltoolbar": "Hiding",
|
||||
"language": "haskell",
|
||||
"name": "",
|
||||
"signature": "sha256:b630a2733d4a58680ceb3b868982dc891d570e9ccad5ce31a29d5e1c110962b7"
|
||||
"signature": "sha256:1a476f19eca338ce4e01b81006d0a165e437bdcebbbea6d1ac10e0cd217740ee"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
@ -36,8 +36,15 @@
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
":ext NoImplicitPrelude\n",
|
||||
"4 + 4"
|
||||
"infixl 3 <<>>\n",
|
||||
"a <<>> 1 = a + 1\n",
|
||||
"a <<>> 3 = a - 1\n",
|
||||
"(<<>>) a b = a * 3\n",
|
||||
"\n",
|
||||
"f :: Int -> Int\n",
|
||||
"f x = x + x\n",
|
||||
"\n",
|
||||
"f 3 <<>> f 3"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {
|
||||
@ -45,18 +52,14 @@
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"html": [
|
||||
"<span class='err-msg'>Not in scope: `+'<br/>Perhaps you meant `IHaskellPrelude.+' (imported from Prelude)</span>"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"text": [
|
||||
"Not in scope: `+'\n",
|
||||
"Perhaps you meant `IHaskellPrelude.+' (imported from Prelude)"
|
||||
"18"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@ -100,113 +103,28 @@
|
||||
"parser"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {
|
||||
"hidden": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"javascript": [
|
||||
"// Only load this script once.\n",
|
||||
"var kernel = IPython.notebook.kernel;\n",
|
||||
"var initialized = kernel !== undefined && kernel != null;\n",
|
||||
"console.log(\"Initialized\", initialized);\n",
|
||||
"if (initialized && window.parsecWidgetRegistered === undefined) {\n",
|
||||
"\n",
|
||||
"// Do not load this script again.\n",
|
||||
"window.parsecWidgetRegistered = true;\n",
|
||||
"\n",
|
||||
"var parsecWidgetCounter = 0;\n",
|
||||
"\n",
|
||||
"// Register the comm target.\n",
|
||||
"var ParsecWidget = function (comm) {\n",
|
||||
" this.comm = comm;\n",
|
||||
" this.comm.on_msg($.proxy(this.handler, this));\n",
|
||||
"\n",
|
||||
" // Get the cell that was probably executed.\n",
|
||||
" // The msg_id:cell mapping will make this possible without guessing.\n",
|
||||
" this.cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index()-1);\n",
|
||||
"\n",
|
||||
" // Store this widget so we can use it from callbacks.\n",
|
||||
" var widget = this;\n",
|
||||
"\n",
|
||||
" // Editor options.\n",
|
||||
" var options = {\n",
|
||||
" lineNumbers: true,\n",
|
||||
" // Show parsec errors as lint errors.\n",
|
||||
" gutters: [\"CodeMirror-lint-markers\"],\n",
|
||||
" lintWith: {\n",
|
||||
" \"getAnnotations\": function(cm, update, opts) {\n",
|
||||
" var errs = [];\n",
|
||||
" if (widget.hasError) {\n",
|
||||
" var col = widget.error[\"col\"];\n",
|
||||
" var line = widget.error[\"line\"];\n",
|
||||
" errs = [{\n",
|
||||
" from: CodeMirror.Pos(line - 1, col - 1),\n",
|
||||
" to: CodeMirror.Pos(line - 1, col),\n",
|
||||
" message: widget.error[\"msg\"],\n",
|
||||
" severity: \"error\"\n",
|
||||
" }];\n",
|
||||
" }\n",
|
||||
" update(cm, errs);\n",
|
||||
" },\n",
|
||||
" \"async\": true,\n",
|
||||
" }\n",
|
||||
" };\n",
|
||||
"\n",
|
||||
" // Create the editor.\n",
|
||||
" var out = this.cell.output_area.element;\n",
|
||||
" this.textarea = out.find(\"#parsec-editor\")[0];\n",
|
||||
" this.output = out.find(\"#parsec-output\")[0];\n",
|
||||
" // Give the elements a different name.\n",
|
||||
" this.textarea.id += parsecWidgetCounter;\n",
|
||||
" this.output.id += parsecWidgetCounter;\n",
|
||||
" parsecWidgetCounter++;\n",
|
||||
"\n",
|
||||
" var editor = CodeMirror.fromTextArea(this.textarea, options);\n",
|
||||
" var editor = editor;\n",
|
||||
"\n",
|
||||
" // Update every key press.\n",
|
||||
" editor.on(\"keyup\", function() {\n",
|
||||
" var text = editor.getDoc().getValue();\n",
|
||||
" comm.send({\"text\": text});\n",
|
||||
" });\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"ParsecWidget.prototype.handler = function(msg) {\n",
|
||||
" var data = msg.content.data;\n",
|
||||
" this.hasError = data[\"status\"] == \"error\";\n",
|
||||
" console.log('handler', msg);\n",
|
||||
" if (this.hasError) {\n",
|
||||
" this.output.innerHTML = data[\"msg\"];\n",
|
||||
" this.error = data;\n",
|
||||
" } else {\n",
|
||||
" this.output.innerHTML = data[\"result\"];\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"// Register this widget.\n",
|
||||
"IPython.notebook.kernel.comm_manager.register_target('parsec', IPython.utils.always_new(ParsecWidget));\n",
|
||||
"console.log(\"Registering Parsec widget.\");\n",
|
||||
"}\n"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"html": [
|
||||
"<!-- CodeMirror component -->\n",
|
||||
"<link rel=\"stylesheet\" href=\"/static/components/codemirror/addon/lint/lint.css\">\n",
|
||||
"<script src=\"/static/components/codemirror/addon/lint/lint.js\" charset=\"utf-8\"></script>\n",
|
||||
"\n",
|
||||
"<!-- Parsec widget DOM -->\n",
|
||||
"<form><textarea id=\"parsec-editor\">Insert parser text here...</textarea></form>\n",
|
||||
"<pre id=\"parsec-output\"></pre>\n"
|
||||
"<div class='collapse-group'><span class='btn' href='#' id='unshowable'>Unshowable:<span class='show-type'>Parser List</span></span><span class='err-msg collapse'>No instance for (Show (Parser List)) arising from a use of `print'<br/>Possible fix: add an instance declaration for (Show (Parser List))<br/>In a stmt of an interactive GHCi command: print it</span></div><script>$('#unshowable').on('click', function(e) {\n",
|
||||
" e.preventDefault();\n",
|
||||
" var $this = $(this);\n",
|
||||
" var $collapse = $this.closest('.collapse-group').find('.err-msg');\n",
|
||||
" $collapse.collapse('toggle');\n",
|
||||
"});\n",
|
||||
"</script>"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
"output_type": "display_data",
|
||||
"text": [
|
||||
"No instance for (Show (Parser List)) arising from a use of `print'\n",
|
||||
"Possible fix: add an instance declaration for (Show (Parser List))\n",
|
||||
"In a stmt of an interactive GHCi command: print it"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 2
|
||||
"prompt_number": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
|
@ -189,46 +189,23 @@ parseCodeChunk code startLine = do
|
||||
-- a single declaration. These declarations may also include a type
|
||||
-- signature, which is also joined with the subsequent declarations.
|
||||
joinFunctions :: [Located CodeBlock] -> [Located CodeBlock]
|
||||
joinFunctions (Located line (Declaration decl) : rest) =
|
||||
-- Find all declarations having the same name as this one.
|
||||
let (decls, other) = havingSameName rest in
|
||||
-- Convert them into a single declaration.
|
||||
Located line (Declaration (joinLines $ map (undecl . unloc) decls)) : joinFunctions other
|
||||
where
|
||||
undecl (Declaration decl) = decl
|
||||
undecl _ = error "Expected declaration!"
|
||||
|
||||
-- Get all declarations with the same name as the first declaration.
|
||||
-- The name of a declaration is the first word, which we expect to be
|
||||
-- the name of the function.
|
||||
havingSameName :: [Located CodeBlock] -> ([Located CodeBlock], [Located CodeBlock])
|
||||
havingSameName blocks =
|
||||
let name = head $ words decl
|
||||
sameName = takeWhile (isNamedDecl name) rest
|
||||
others = drop (length sameName) rest in
|
||||
(Located line (Declaration decl) : sameName, others)
|
||||
|
||||
isNamedDecl :: String -> Located CodeBlock -> Bool
|
||||
isNamedDecl name (Located _ (Declaration dec)) = head (words dec) == name
|
||||
isNamedDecl _ _ = False
|
||||
|
||||
-- Allow a type signature followed by declarations to be joined to the
|
||||
-- declarations. Parse the declaration joining separately.
|
||||
joinFunctions (Located line (TypeSignature sig) : Located dl (Declaration decl) : rest) =
|
||||
Located line (Declaration $ sig ++ "\n" ++ joinedDecl):remaining
|
||||
where Located _ (Declaration joinedDecl):remaining = joinFunctions $ Located dl (Declaration decl) : rest
|
||||
|
||||
-- Also allow two type signatures. This is necessary for operator
|
||||
-- declarations in which you have a fixity declaration.
|
||||
joinFunctions (Located line (TypeSignature sig) :
|
||||
Located _ (TypeSignature sig') :
|
||||
Located dl (Declaration decl) : rest) =
|
||||
Located line (Declaration $ intercalate "\n" [sig, sig', joinedDecl]):remaining
|
||||
where Located _ (Declaration joinedDecl):remaining = joinFunctions $ Located dl (Declaration decl) : rest
|
||||
|
||||
joinFunctions (x:xs) = x : joinFunctions xs
|
||||
joinFunctions [] = []
|
||||
joinFunctions blocks = Located lnum (conjoin $ map unloc decls) : joinFunctions rest
|
||||
where
|
||||
decls = takeWhile (signatureOrDecl . unloc) blocks
|
||||
rest = drop (length decls) blocks
|
||||
lnum = line $ head decls
|
||||
|
||||
signatureOrDecl (Declaration _) = True
|
||||
signatureOrDecl (TypeSignature _) = True
|
||||
signatureOrDecl _ = False
|
||||
|
||||
str (Declaration s) = s
|
||||
str (TypeSignature s) = s
|
||||
str _ = error "Expected declaration or signature"
|
||||
|
||||
conjoin :: [CodeBlock] -> CodeBlock
|
||||
conjoin = Declaration . intercalate "\n" . map str
|
||||
|
||||
-- | Parse a directive of the form :directiveName.
|
||||
parseDirective :: String -- ^ Directive string.
|
||||
|
Loading…
x
Reference in New Issue
Block a user