12
12
--
13
13
-----------------------------------------------------------------------------
14
14
15
- {-# LANGUAGE OverloadedStrings #-}
15
+ {-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
16
16
17
17
module Main (
18
18
main
@@ -40,8 +40,13 @@ import qualified System.IO.UTF8 as U
40
40
41
41
import qualified Paths_trypurescript as Paths
42
42
43
- preludeFilename :: IO FilePath
44
- preludeFilename = Paths. getDataFileName " prelude/prelude.purs"
43
+ import qualified Data.ByteString as B
44
+ import qualified Data.ByteString.UTF8 as BU
45
+
46
+ import Data.FileEmbed
47
+
48
+ prelude :: String
49
+ prelude = BU. toString $ (embedFile " prelude/prelude.purs" )
45
50
46
51
data Compiled = Compiled { js :: String
47
52
, externs :: String
@@ -72,257 +77,34 @@ mono :: H.Html -> H.Html
72
77
mono h = h ! A. class_ " mono"
73
78
74
79
examplesJs :: String
75
- examplesJs = unlines
76
- [ " $('#examples').change(function() {"
77
- , " var name = $('#examples').val();"
78
- , " if (name) {"
79
- , " window.location = '/example/' + name;"
80
- , " }"
81
- , " });"
82
- ]
80
+ examplesJs = BU. toString $ (embedFile " assets/examples.js" )
83
81
84
82
css :: String
85
- css = unlines
86
- [ " body { font-family: 'Lato', sans-serif; color: #404040; margin: 0; }"
87
- , " .mono { font-family: 'Ubuntu Mono', monospace; white-space: pre; word-break: break-all; word-wrap: break-word; }"
88
- , " .header { margin: 0; background: #202028; box-shadow: 0 0 10px #808080; color: #E0E0E0; }"
89
- , " .splitter { margin: 0; height: 5px; background: #606068; }"
90
- , " .center { margin: 0 auto; padding: 20px; }"
91
- , " a { color: #808080; }"
92
- , " button { background: #d0d0d0; color: #606060; padding-top: 3px; padding-bottom: 3px; font-weight: bold; border-radius: 1px; border: 1px solid #c0c0c0; box-shadow: 1px 1px 0 0 #ffffff inset; padding-left: 15px; padding-right: 15px; cursor: pointer; }"
93
- , " button:hover { background: #e0e0e0; }"
94
- , " #code, #js { margin: 10px; }" ]
83
+ css = BU. toString $ (embedFile " assets/style.css" )
95
84
96
85
gaq :: String
97
- gaq = unlines
98
- [ " var _gaq = _gaq || [];"
99
- , " _gaq.push(['_setAccount', 'UA-33896432-1']);"
100
- , " _gaq.push(['_trackPageview']);"
101
- , " (function() {"
102
- , " var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;"
103
- , " ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';"
104
- , " var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);"
105
- , " })();" ]
86
+ gaq = BU. toString $ (embedFile " assets/gaq.js" )
106
87
107
- ace :: Bool -> String
108
- ace js = unlines $
109
- [ " var editor = ace.edit('code');"
110
- , " editor.setTheme('ace/theme/dawn');"
111
- , " editor.renderer.setShowGutter(false);"
112
- , " var session = editor.getSession();"
113
- , " session.setMode('ace/mode/haskell');"
114
- , " session.setValue($('#textarea').val());"
115
- , " session.setUseWrapMode(true);"
116
- , " session.on('change', function(){"
117
- , " $('#textarea').val(editor.getSession().getValue());"
118
- , " });"
119
- , " if ($('#js')[0]) {"
120
- , " var js = ace.edit('js');"
121
- , " js.setTheme('ace/theme/dawn');"
122
- , " js.renderer.setShowGutter(false);"
123
- , " js.setReadOnly(true);"
124
- , " var session = js.getSession();"
125
- , " session.setUseWrapMode(true);"
126
- ]
127
- ++ (if js then
128
- [ " session.setMode('ace/mode/javascript');" ]
129
- else
130
- [] ) ++
131
- [ " }"
132
- , " function setHeight() {"
133
- , " var top = $('#code').offset().top;"
134
- , " var tot = $(window).height();"
135
- , " var height = Math.max(tot - top - 50, 200);"
136
- , " $('#code').height(height + 'px');"
137
- , " $('#js').height(height + 'px');"
138
- , " }"
139
- , " $(setHeight);"
140
- , " $(window).on('resize', setHeight);" ]
88
+ ace :: String
89
+ ace = BU. toString $ (embedFile " assets/ace.js" )
90
+
91
+ defaultCode :: String
92
+ defaultCode = BU. toString $ (embedFile " examples/default.purs" )
141
93
142
94
examples :: [(String , (String , String ))]
143
95
examples =
144
- [ (" adt" ,
145
- (" Algebraic Data Types" ,
146
- unlines [ " module Main where"
147
- , " "
148
- , " import Prelude"
149
- , " "
150
- , " data Person = Person { name :: String, age :: Number }"
151
- , " "
152
- , " foreign import numberToString :: Number -> String"
153
- , " "
154
- , " showPerson (Person { name = name, age = age }) ="
155
- , " name ++ \" , aged \" ++ numberToString age"
156
- ]))
157
- , (" ops" ,
158
- (" Operators" ,
159
- unlines [ " module Main where"
160
- , " "
161
- , " import Prelude ()"
162
- , " "
163
- , " infixl 5 >>>"
164
- , " "
165
- , " (>>>) :: forall a b c. (a -> b) -> (b -> c) -> a -> c"
166
- , " (>>>) f g a = g (f a)"
167
- , " "
168
- , " foreign import foo :: String -> Number"
169
- , " foreign import bar :: Number -> Boolean"
170
- , " "
171
- , " test = foo >>> bar"
172
- ]))
173
- , (" arrays" ,
174
- (" Arrays" ,
175
- unlines [ " module Main where"
176
- , " "
177
- , " import Prelude"
178
- , " "
179
- , " sum (x:xs) = x + sum xs"
180
- , " sum _ = 0"
181
- , " "
182
- , " sumOfProducts (x : y : xs) = x * y + sumOfProducts xs"
183
- , " sumOfProducts _ = 0"
184
- ]))
185
- , (" rows" ,
186
- (" Row Polymorphism" ,
187
- unlines [ " module Main where"
188
- , " "
189
- , " import Prelude"
190
- , " "
191
- , " showPerson o = o.lastName ++ \" , \" ++ o.firstName"
192
- ]))
193
- , (" ffi" ,
194
- (" FFI" ,
195
- unlines [ " module Main where"
196
- , " "
197
- , " foreign import data IO :: * -> *"
198
- , " "
199
- , " foreign import log \" function log(s) { return function() { console.log(s) }; }\" :: String -> IO { }"
200
- , " "
201
- , " main = log \" Hello World!\" "
202
- ]))
203
- , (" blocks" ,
204
- (" Mutable Variables" ,
205
- unlines [ " module Main where"
206
- , " "
207
- , " import Prelude"
208
- , " import Control.Monad.Eff"
209
- , " import Control.Monad.ST"
210
- , " "
211
- , " collatz :: Number -> Number"
212
- , " collatz n = runPure (runST (do"
213
- , " r <- newSTRef n"
214
- , " count <- newSTRef 0"
215
- , " untilE $ do"
216
- , " modifySTRef count $ (+) 1"
217
- , " m <- readSTRef r"
218
- , " writeSTRef r $ if m % 2 == 0 then m / 2 else 3 * m + 1"
219
- , " return $ m == 1"
220
- , " readSTRef count))"
221
- ]))
222
- , (" modules" ,
223
- (" Modules" ,
224
- unlines [ " module M1 where"
225
- , " "
226
- , " import Prelude"
227
- , " "
228
- , " incr :: Number -> Number"
229
- , " incr x = x + 1"
230
- , " "
231
- , " module Main where"
232
- , " "
233
- , " test = M1.incr 10"
234
- ]))
235
- , (" rank2" ,
236
- (" Rank N Types" ,
237
- unlines [ " module Main where"
238
- , " "
239
- , " type Nat = forall a. a -> (a -> a) -> a"
240
- , " "
241
- , " zero :: Nat"
242
- , " zero a _ = a"
243
- , " "
244
- , " succ :: Nat -> Nat"
245
- , " succ n a f = f (n a f)"
246
- , " "
247
- , " type Lens a b = forall f. (a -> f a) -> b -> f b"
248
- , " "
249
- , " compose :: forall a b c. Lens a b -> Lens b c -> Lens a c"
250
- , " compose l1 l2 f = l2 (l1 f)"
251
- ]))
252
- , (" recursion" ,
253
- (" Recursion" ,
254
- unlines [ " module Main where"
255
- , " "
256
- , " import Prelude"
257
- , " "
258
- , " isOdd :: Number -> Boolean"
259
- , " isOdd 0 = false"
260
- , " isOdd n = isEven (n - 1)"
261
- , " "
262
- , " isEven :: Number -> Boolean"
263
- , " isEven 0 = true"
264
- , " isEven n = isOdd (n - 1)"
265
- ]))
266
- , (" do" ,
267
- (" Do Notation" ,
268
- unlines [ " module Main where"
269
- , " "
270
- , " import Prelude"
271
- , " "
272
- , " data Maybe a = Nothing | Just a"
273
- , " "
274
- , " instance monadMaybe :: Prelude.Monad Maybe where"
275
- , " return = Just"
276
- , " (>>=) Nothing _ = Nothing"
277
- , " (>>=) (Just a) f = f a"
278
- , " "
279
- , " isEven n | n % 2 == 0 = Just {}"
280
- , " isEven _ = Nothing"
281
- , " "
282
- , " evenSum a b = do"
283
- , " n <- a"
284
- , " m <- b"
285
- , " let sum = n + m"
286
- , " isEven sum"
287
- , " return sum"
288
- ]))
289
- , (" tco" ,
290
- (" Tail-Call Elimination" ,
291
- unlines [ " module Main where"
292
- , " "
293
- , " import Prelude"
294
- , " "
295
- , " factHelper prod 0 = prod"
296
- , " factHelper prod n = factHelper (prod * n) (n - 1)"
297
- , " "
298
- , " fact = factHelper 1"
299
- ]))
300
- , (" typeclasses" ,
301
- (" Type Classes" ,
302
- unlines [ " module Main where"
303
- , " "
304
- , " import Prelude ((++))"
305
- , " "
306
- , " class Show a where"
307
- , " show :: a -> String"
308
- , " "
309
- , " instance showString :: Show String where"
310
- , " show s = s"
311
- , " "
312
- , " instance showBoolean :: Show Boolean where"
313
- , " show true = \" true\" "
314
- , " show false = \" false\" "
315
- , " "
316
- , " instance showArray :: (Show a) => Show [a] where"
317
- , " show arr = \" [\" ++ go arr ++ \" ]\" "
318
- , " where"
319
- , " go :: forall a. (Show a) => [a] -> String"
320
- , " go [] = \"\" "
321
- , " go [x] = show x"
322
- , " go (x:xs) = show x ++ \" , \" ++ go xs"
323
- , " "
324
- , " test = show [true, false]"
325
- ]))
96
+ [ (" adt" , (" Algebraic Data Types" , BU. toString $ (embedFile " examples/adt.purs" )))
97
+ , (" ops" , (" Operators" , BU. toString $ (embedFile " examples/operators.purs" )))
98
+ , (" arrays" , (" Arrays" , BU. toString $ (embedFile " examples/arrays.purs" )))
99
+ , (" rows" , (" Row Polymorphism" , BU. toString $ (embedFile " examples/rows.purs" )))
100
+ , (" ffi" , (" FFI" , BU. toString $ (embedFile " examples/ffi.purs" )))
101
+ , (" mutable" , (" Mutable Variables" , BU. toString $ (embedFile " examples/mutable.purs" )))
102
+ , (" modules" , (" Modules" , BU. toString $ (embedFile " examples/modules.purs" )))
103
+ , (" rank2" , (" Rank N Types" , BU. toString $ (embedFile " examples/rankn.purs" )))
104
+ , (" recursion" , (" Recursion" , BU. toString $ (embedFile " examples/recursion.purs" )))
105
+ , (" do" , (" Do Notation" , BU. toString $ (embedFile " examples/do.purs" )))
106
+ , (" tco" , (" Tail-Call Elimination" , BU. toString $ (embedFile " examples/tco.purs" )))
107
+ , (" typeclasses" , (" Type Classes" , BU. toString $ (embedFile " examples/typeclasses.purs" )))
326
108
]
327
109
328
110
page :: Maybe String -> Maybe String -> Maybe Response -> ActionM ()
@@ -373,7 +155,8 @@ page ex input res = html $ renderHtml $ do
373
155
H. div ! A. style " position: absolute; width: 50%; left: 50%;" $ do
374
156
H. h2 $ H. toHtml $ str " Generated Javascript"
375
157
H. div ! A. id " js" $ H. toHtml . str $ text
376
- H. script ! A. type_ " text/javascript" $ preEscapedToHtml (ace success)
158
+ H. script ! A. type_ " text/javascript" $ preEscapedToHtml $ str $ " var compiledSuccessfully = " ++ if success then " true;" else " false;"
159
+ H. script ! A. type_ " text/javascript" $ preEscapedToHtml ace
377
160
378
161
responseToJs :: Maybe Response -> (Bool , String )
379
162
responseToJs Nothing = (False , " " )
@@ -383,20 +166,10 @@ responseToJs (Just (Response (Right (Compiled js _)))) = (True, js)
383
166
384
167
server :: Int -> IO ()
385
168
server port = do
386
- prelude <- preludeFilename >>= U. readFile
387
169
let preludeModules = either (error . show ) id $ P. runIndentParser " " P. parseModules prelude
388
170
scotty port $ do
389
171
get " /" $ do
390
- page Nothing (Just (unlines [ " -- Type PureScript code here and click 'Compile' ..."
391
- , " -- "
392
- , " -- Or select an example from the list at the top right of the page"
393
- , " "
394
- , " module Main where"
395
- , " "
396
- , " import Debug.Trace"
397
- , " "
398
- , " main = trace \" Hello, World!\" "
399
- ])) Nothing
172
+ page Nothing (Just defaultCode) Nothing
400
173
get " /example/:name" $ do
401
174
name <- param " name"
402
175
case lookup name examples of
0 commit comments