diff --git a/notebooks/Test.ipynb b/notebooks/Test.ipynb index d8e26d5b..3d6fa9b5 100644 --- a/notebooks/Test.ipynb +++ b/notebooks/Test.ipynb @@ -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": [ - "Not in scope: `+'
Perhaps you meant `IHaskellPrelude.+' (imported from Prelude)
" - ], "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": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "
\n"
+        "
Unshowable:Parser ListNo instance for (Show (Parser List)) arising from a use of `print'
Possible fix: add an instance declaration for (Show (Parser List))
In a stmt of an interactive GHCi command: print it
" ], "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", diff --git a/src/IHaskell/Eval/Parser.hs b/src/IHaskell/Eval/Parser.hs index 1cb01c07..4569754e 100644 --- a/src/IHaskell/Eval/Parser.hs +++ b/src/IHaskell/Eval/Parser.hs @@ -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.