diff --git a/.gitignore b/.gitignore index 07a17261..8985851d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.hi +notebooks/Test.ipynb *.o dist IHaskell/GHC diff --git a/notebooks/Test.ipynb b/notebooks/Test.ipynb deleted file mode 100644 index 68f5514c..00000000 --- a/notebooks/Test.ipynb +++ /dev/null @@ -1,595 +0,0 @@ -{ - "metadata": { - "celltoolbar": "Hiding", - "language": "haskell", - "name": "", - "signature": "sha256:7262ddac633b02f026eb4bc29633234f9f8327226256b7f1660e72296f21935b" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import IHaskell.Display\n", - "\n", - "-- My widget type\n", - "data Slider = Slider\n", - "\n", - "instance IHaskellDisplay Slider where\n", - " display Slider = return $ Display []\n", - " \n", - "instance IHaskellWidget Slider where\n", - " targetName _ = \"WidgetModel\"\n", - " open _ s = s undefined >> error \"what\"\n", - " " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "heading", - "level": 4, - "metadata": { - "hidden": false - }, - "source": [ - ":set -XFlexibleInstances\n", - "import Control.Applicative (liftA2)" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "class MyEq a where\n", - " myEq :: a -> a -> Bool\n", - " \n", - "class MyNum a where\n", - " myPlus :: a -> a -> a\n", - " \n", - "instance MyEq (Maybe Int) where\n", - " myEq = (==)\n", - " \n", - "instance MyNum (Maybe Int) where\n", - " myPlus = liftA2 (+)\n", - "\n", - "find :: MyEq a => [a] -> a -> Maybe Int\n", - "find [] _ = Nothing\n", - "find (x:xs) y = \n", - " if myEq x y then Just 0\n", - " else myPlus (Just 1) (find xs y)\n", - " \n", - "find [Just 3] (Just 3 :: Maybe Int)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "html": [ - "Just0" - ], - "metadata": {}, - "output_type": "display_data", - "text": [ - "Just 0" - ] - } - ], - "prompt_number": 2 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - ":t Just" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "html": [ - "Just :: forall a. a -> Maybe a" - ], - "metadata": {}, - "output_type": "display_data", - "text": [ - "Just :: forall a. a -> Maybe a" - ] - } - ], - "prompt_number": 5 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import Prelude.OldIO\n", - "\n", - "main :: [IOResponse] -> [IORequest]\n", - "main responses = [getLine, printResult]\n", - " where\n", - " getLine = GetLine\n", - " printResult = Print inputLine\n", - "\n", - " ConsoleLine inputLine:_ = responses" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "run main" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "display_data", - "text": [ - "hello" - ] - } - ], - "prompt_number": 4 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import Text.Parsec\n", - "import Text.Parsec.String\n", - "import Text.Parsec.Prim\n", - "import Text.Parsec.Char\n", - "\n", - "data List = List [Float] deriving Show\n", - "\n", - "let -- Parse a nonempty int list like [1, 2, 3]\n", - " parser :: Parser List\n", - " parser = do\n", - " char '['\n", - " values <- option [] $ many1 (try float <|> int)\n", - " char ']'\n", - " return $ List values\n", - " \n", - " -- Parse an element of an int list, like \"3, \"\n", - " int :: Parser Float\n", - " int = do\n", - " value <- many1 $ oneOf \"0123456789\"\n", - " optional $ char ','\n", - " whitespace\n", - " return (fromIntegral (read value :: Int) :: Float)\n", - " \n", - " float :: Parser Float\n", - " float = do\n", - " value <- many1 $ oneOf \"0123456789\"\n", - " char '.'\n", - " after <- many1 $ oneOf \"0123456789\"\n", - " optional $ char ','\n", - " whitespace\n", - " return (read (value ++ \".\" ++ after) :: Float)\n", - " \n", - " -- Parse any whitespace\n", - " whitespace = many $ oneOf \" \\t\"" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "parser" - ], - "language": "python", - "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", - "// Codemirror lint.js\n", - "// Must be included here, otherwise linting cannot happen the first time the widget is loaded.\n", - "(function() {\n", - " \"use strict\";\n", - " var GUTTER_ID = \"CodeMirror-lint-markers\";\n", - " var SEVERITIES = /^(?:error|warning)$/;\n", - "\n", - " function showTooltip(e, content) {\n", - " var tt = document.createElement(\"div\");\n", - " tt.className = \"CodeMirror-lint-tooltip\";\n", - " tt.appendChild(content.cloneNode(true));\n", - " document.body.appendChild(tt);\n", - "\n", - " function position(e) {\n", - " if (!tt.parentNode) return CodeMirror.off(document, \"mousemove\", position);\n", - " tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + \"px\";\n", - " tt.style.left = (e.clientX + 5) + \"px\";\n", - " }\n", - " CodeMirror.on(document, \"mousemove\", position);\n", - " position(e);\n", - " if (tt.style.opacity != null) tt.style.opacity = 1;\n", - " return tt;\n", - " }\n", - " function rm(elt) {\n", - " if (elt.parentNode) elt.parentNode.removeChild(elt);\n", - " }\n", - " function hideTooltip(tt) {\n", - " if (!tt.parentNode) return;\n", - " if (tt.style.opacity == null) rm(tt);\n", - " tt.style.opacity = 0;\n", - " setTimeout(function() { rm(tt); }, 600);\n", - " }\n", - "\n", - " function showTooltipFor(e, content, node) {\n", - " var tooltip = showTooltip(e, content);\n", - " function hide() {\n", - " CodeMirror.off(node, \"mouseout\", hide);\n", - " if (tooltip) { hideTooltip(tooltip); tooltip = null; }\n", - " }\n", - " var poll = setInterval(function() {\n", - " if (tooltip) for (var n = node;; n = n.parentNode) {\n", - " if (n == document.body) return;\n", - " if (!n) { hide(); break; }\n", - " }\n", - " if (!tooltip) return clearInterval(poll);\n", - " }, 400);\n", - " CodeMirror.on(node, \"mouseout\", hide);\n", - " }\n", - "\n", - " function LintState(cm, options, hasGutter) {\n", - " this.marked = [];\n", - " this.options = options;\n", - " this.timeout = null;\n", - " this.hasGutter = hasGutter;\n", - " this.onMouseOver = function(e) { onMouseOver(cm, e); };\n", - " }\n", - "\n", - " function parseOptions(cm, options) {\n", - " if (options instanceof Function) return {getAnnotations: options};\n", - " if (!options || options === true) options = {};\n", - " if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), \"lint\");\n", - " if (!options.getAnnotations) throw new Error(\"Required option 'getAnnotations' missing (lint addon)\");\n", - " return options;\n", - " }\n", - "\n", - " function clearMarks(cm) {\n", - " var state = cm.state.lint;\n", - " if (state.hasGutter) cm.clearGutter(GUTTER_ID);\n", - " for (var i = 0; i < state.marked.length; ++i)\n", - " state.marked[i].clear();\n", - " state.marked.length = 0;\n", - " }\n", - "\n", - " function makeMarker(labels, severity, multiple, tooltips) {\n", - " var marker = document.createElement(\"div\"), inner = marker;\n", - " marker.className = \"CodeMirror-lint-marker-\" + severity;\n", - " if (multiple) {\n", - " inner = marker.appendChild(document.createElement(\"div\"));\n", - " inner.className = \"CodeMirror-lint-marker-multiple\";\n", - " }\n", - "\n", - " if (tooltips != false) CodeMirror.on(inner, \"mouseover\", function(e) {\n", - " showTooltipFor(e, labels, inner);\n", - " });\n", - "\n", - " return marker;\n", - " }\n", - "\n", - " function getMaxSeverity(a, b) {\n", - " if (a == \"error\") return a;\n", - " else return b;\n", - " }\n", - "\n", - " function groupByLine(annotations) {\n", - " var lines = [];\n", - " for (var i = 0; i < annotations.length; ++i) {\n", - " var ann = annotations[i], line = ann.from.line;\n", - " (lines[line] || (lines[line] = [])).push(ann);\n", - " }\n", - " return lines;\n", - " }\n", - "\n", - " function annotationTooltip(ann) {\n", - " var severity = ann.severity;\n", - " if (!SEVERITIES.test(severity)) severity = \"error\";\n", - " var tip = document.createElement(\"div\");\n", - " tip.className = \"CodeMirror-lint-message-\" + severity;\n", - " tip.appendChild(document.createTextNode(ann.message));\n", - " return tip;\n", - " }\n", - "\n", - " function startLinting(cm) {\n", - " var state = cm.state.lint, options = state.options;\n", - " if (options.async)\n", - " options.getAnnotations(cm, updateLinting, options);\n", - " else\n", - " updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));\n", - " }\n", - "\n", - " function updateLinting(cm, annotationsNotSorted) {\n", - " clearMarks(cm);\n", - " var state = cm.state.lint, options = state.options;\n", - "\n", - " var annotations = groupByLine(annotationsNotSorted);\n", - "\n", - " for (var line = 0; line < annotations.length; ++line) {\n", - " var anns = annotations[line];\n", - " if (!anns) continue;\n", - "\n", - " var maxSeverity = null;\n", - " var tipLabel = state.hasGutter && document.createDocumentFragment();\n", - "\n", - " for (var i = 0; i < anns.length; ++i) {\n", - " var ann = anns[i];\n", - " var severity = ann.severity;\n", - " if (!SEVERITIES.test(severity)) severity = \"error\";\n", - " maxSeverity = getMaxSeverity(maxSeverity, severity);\n", - "\n", - " if (options.formatAnnotation) ann = options.formatAnnotation(ann);\n", - " if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));\n", - "\n", - " if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {\n", - " className: \"CodeMirror-lint-mark-\" + severity,\n", - " __annotation: ann\n", - " }));\n", - " }\n", - "\n", - " if (state.hasGutter)\n", - " cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,\n", - " state.options.tooltips));\n", - " }\n", - " if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);\n", - " }\n", - "\n", - " function onChange(cm) {\n", - " var state = cm.state.lint;\n", - " clearTimeout(state.timeout);\n", - " state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);\n", - " }\n", - "\n", - " function popupSpanTooltip(ann, e) {\n", - " var target = e.target || e.srcElement;\n", - " showTooltipFor(e, annotationTooltip(ann), target);\n", - " }\n", - "\n", - " // When the mouseover fires, the cursor might not actually be over\n", - " // the character itself yet. These pairs of x,y offsets are used to\n", - " // probe a few nearby points when no suitable marked range is found.\n", - " var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];\n", - "\n", - " function onMouseOver(cm, e) {\n", - " if (!/\\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;\n", - " for (var i = 0; i < nearby.length; i += 2) {\n", - " var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],\n", - " top: e.clientY + nearby[i + 1]}));\n", - " for (var j = 0; j < spans.length; ++j) {\n", - " var span = spans[j], ann = span.__annotation;\n", - " if (ann) return popupSpanTooltip(ann, e);\n", - " }\n", - " }\n", - " }\n", - "\n", - " function optionHandler(cm, val, old) {\n", - " if (old && old != CodeMirror.Init) {\n", - " clearMarks(cm);\n", - " cm.off(\"change\", onChange);\n", - " CodeMirror.off(cm.getWrapperElement(), \"mouseover\", cm.state.lint.onMouseOver);\n", - " delete cm.state.lint;\n", - " }\n", - "\n", - " if (val) {\n", - " var gutters = cm.getOption(\"gutters\"), hasLintGutter = false;\n", - " for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;\n", - " var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);\n", - " cm.on(\"change\", onChange);\n", - " if (state.options.tooltips != false)\n", - " CodeMirror.on(cm.getWrapperElement(), \"mouseover\", state.onMouseOver);\n", - "\n", - " startLinting(cm);\n", - " }\n", - " }\n", - "\n", - " CodeMirror.defineOption(\"lintWith\", false, optionHandler); // deprecated\n", - " CodeMirror.defineOption(\"lint\", false, optionHandler); // deprecated\n", - "})();\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(this.hasError);\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" - ], - "metadata": {}, - "output_type": "display_data" - } - ], - "prompt_number": 2 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "print $ 1+ 1" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "display_data", - "text": [ - "2" - ] - } - ], - "prompt_number": 4 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "data Thing = Thing Int Int" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "f :: Int -> Thing -> Int\n", - "f i (Thing a b) = i * (a + b)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 2 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import Data.List.Utils (replace)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import Shelly\n", - "import qualified Data.Text as T\n", - "\n", - "shelly $ lsT $ fromText $ T.pack \"/home\"" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "display_data", - "text": [ - "[]" - ] - } - ], - "prompt_number": 3 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] - } - ], - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/src/IHaskell/Eval/Evaluate.hs b/src/IHaskell/Eval/Evaluate.hs index a9403e9b..5324d0e6 100644 --- a/src/IHaskell/Eval/Evaluate.hs +++ b/src/IHaskell/Eval/Evaluate.hs @@ -117,6 +117,7 @@ globalImports = , "import qualified IHaskell.IPython.Stdin" , "import qualified System.Posix.IO as IHaskellIO" , "import qualified System.IO as IHaskellSysIO" + , "import qualified Language.Haskell.TH as IHaskellTH" ] -- | Run an interpreting action. This is effectively runGhc with @@ -706,7 +707,7 @@ evalCommand output (Expression expr) state = do isWidget <- attempt $ exprType widgetExpr -- Check if this is a template haskell declaration - let declExpr = printf "((id :: DecsQ -> DecsQ) (%s))" expr::String + let declExpr = printf "((id :: IHaskellTH.DecsQ -> IHaskellTH.DecsQ) (%s))" expr::String isTHDeclaration <- attempt $ exprType declExpr write $ "Can Display: " ++ show canRunDisplay