-
Notifications
You must be signed in to change notification settings - Fork 1
/
JS.hs
156 lines (139 loc) · 5.08 KB
/
JS.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{-# LANGUAGE ScopedTypeVariables #-}
module Main (
main
) where
import Control.Monad.IO.Class (MonadIO(..))
import Control.Concurrent.MVar (takeMVar, putMVar, newEmptyMVar)
import GHCJS.DOM
import GHCJS.DOM.Types (HTMLParagraphElement(..), HTMLSpanElement(..), unsafeCastTo, castTo, HTMLTextAreaElement(..), HTMLButtonElement(..))
import GHCJS.DOM.Document (getBodyUnsafe, createElementUnsafe, createTextNode, getElementById)
import GHCJS.DOM.Element (setInnerHTML)
import GHCJS.DOM.Node (appendChild)
import GHCJS.DOM.EventM (on, mouseClientXY)
import qualified GHCJS.DOM.Document as D (click)
import qualified GHCJS.DOM.Element as E (click)
import qualified GHCJS.DOM.HTMLTextAreaElement as TA (getValue)
import qualified GHCJS.DOM.HTMLButtonElement as B (getValue)
import qualified GHCJS.DOM.Node as N (setNodeValue)
import Loader
import TT (ModuleState(..))
import Control.Monad.Trans.State.Strict
import Pretty (render, sep, text, hang)
import JavaScript.Web.XMLHttpRequest
import qualified Data.JSString as JSS
import Data.String
demo = unlines
["\\(context : [Ind : Type;",
" Animal : Ind -> Type;",
" Human : Ind -> Type;",
" Dog : Ind -> Type;",
" Donkey : Ind -> Type;",
" Hug : Ind -> Ind -> Type;",
" Own : Ind -> Ind -> Type;",
" a0 : Ind;",
" aA : Animal a0;",
" aH : Human a0;",
" humanIsAnimal : (x:Ind) -> Human x -> Animal x;",
" ]) -> module",
"",
"open context",
"",
"Anim : Type",
"Anim = [x : Ind; isAnimal : Animal x]",
"",
"Huma : Type",
"Huma = Anim /\\ [x : Ind; isHuman : Human x]",
"",
"a : Huma",
"a = (x = a0, isHuman = aH, isAnimal = aA)",
"",
"b : Anim",
"b = a",
"",
"ManOwnADonkey : Type",
"ManOwnADonkey = [x : Ind;",
" y : Ind;",
" q : Animal x;",
" p : Human x;",
" q : Donkey y;",
" o : Own x y]",
"",
"f : ManOwnADonkey -> Huma",
"f r = (x = r.x, isHuman = r.p, isAnimal = r.q)",
"",
"ManOwnADonkey2 : Type",
"ManOwnADonkey2 = [x : Huma;",
" y : Ind;",
" q : Donkey y;",
" o : Own x.x y]",
"",
"f : ManOwnADonkey2 -> Huma",
"f r = r.x",
"",
"VP : Type",
"VP = Ind -> Type",
"",
"NP' : Type",
"NP' = (verb : VP) -> [subject : Ind; holds : verb subject]",
"",
"S : Type",
"S = [subject : Ind;",
" verb : Ind -> Type;",
" holds : verb subject]",
"",
"",
"appVP' : VP -> NP' -> S",
"appVP' vp np = (verb = vp, subject = s0.subject, holds = s0.holds)",
" where s0 : [subject : Ind; holds : vp subject]",
" s0 = np vp"]
main = do
putStrLn "ttr starting"
Just doc <- currentDocument
body <- getBodyUnsafe doc
setInnerHTML body (Just ("Type-theory Easter Egg<p/> <textarea id='input' cols=80 rows=33 style='font-family: monospace;font-size:12pt'>"++ demo ++"</textarea> <p/> <button id='checkButton'>check</button> <pre id='output'></pre>"))
Just elTextArea <- getElementById doc "input"
Just textArea <- castTo HTMLTextAreaElement elTextArea
Just elCheckButton <- getElementById doc "checkButton"
Just checkButton <- castTo HTMLButtonElement elCheckButton
Just newParagraph <- getElementById doc "output"
Just replyNode <- createTextNode doc "<Checker output>"
appendChild newParagraph (Just replyNode)
on checkButton E.click $ do
Just textAreaContents <- TA.getValue textArea
(l,_state) <- liftIO $ runStateT (loadExpression False webModuleReader "<textarea>" textAreaContents) initState
let (reply::String) = render $ case l of
Failed err -> sep [text "Checking failed:",err]
Loaded v t -> text "Checking successful."
N.setNodeValue replyNode (Just reply)
return ()
-- exitMVar <- liftIO newEmptyMVar
-- In case we want an exit button:
-- exit <- createElementUnsafe doc (Just "span") >>= unsafeCastTo HTMLSpanElement
-- text <- createTextNode doc "Click here to exit"
-- appendChild exit text
-- appendChild body (Just exit)
-- on exit E.click $ liftIO $ putMVar exitMVar ()
-- -- Force all all the lazy evaluation to be executed
-- syncPoint
-- -- In GHC compiled version the WebSocket connection will end when this
-- -- thread ends. So we will wait until the user clicks exit.
-- liftIO $ takeMVar exitMVar
-- setInnerHTML body (Just ("<h1>DONE!</h1>") )
return ()
webModuleReader f = do
let uri = (f ++ ".tt")
resp <- xhrString Request
{ reqMethod = GET
, reqURI = fromString uri
, reqLogin = Nothing
, reqHeaders = []
, reqWithCredentials = False
, reqData = NoData
}
return $ case contents resp of
Nothing -> Left $ hang 2 (text "URI could not be loaded:") (text uri)
Just s -> Right s
{-
dante-target: js-ttr
dante-repl-command-line: ("nix-shell" "ghcjs.nix" "--run" "ghcjs --interactive")
-}