Skip to content

Commit 3e609ee

Browse files
committed
only reload disco-live.disco when it changes
1 parent dcdef3b commit 3e609ee

File tree

5 files changed

+66
-35
lines changed

5 files changed

+66
-35
lines changed

disco-live.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ executable disco-live
3838
, base >=4.8 && <4.22
3939
, containers >=0.5 && <0.8
4040
, disco ==0.2.1
41+
, hashable >=1.4 && <1.6
4142
, haskeline >=0.8 && <0.9
4243
, lens >=4.14 && <5.4
4344
, polysemy ==1.9.2.1
@@ -47,3 +48,4 @@ executable disco-live
4748
other-modules:
4849
Eval
4950
Interpreter
51+
State

src/Eval.hs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE TypeApplications #-}
33
module Eval
4-
( RefRepl
5-
, initDisco
6-
, eval
4+
( eval
75
, loadFile
86
) where
97

10-
import System.Environment
8+
import Data.Char (isSpace)
9+
import Data.Hashable (hash)
10+
import Data.IORef
1111

1212
import qualified Interpreter
13-
import Data.IORef
13+
import State
1414

1515
{-----------------------------------------------------------------------------
1616
Rendering Logic
1717
------------------------------------------------------------------------------}
18-
type RefRepl = IORef Interpreter.Repl
1918

20-
eval :: RefRepl -> String -> IO String
19+
eval :: RefState -> String -> IO String
2120
eval ref command = do
22-
repl0 <- readIORef ref
23-
(result, repl1) <- Interpreter.execute command repl0
24-
writeIORef ref repl1
25-
pure result
21+
AppState repl0 h <- readIORef ref
22+
(result, repl1) <- Interpreter.execute command repl0
23+
writeIORef ref (AppState repl1 h)
24+
pure result
2625

27-
loadFile :: RefRepl -> String -> IO String
26+
loadFile :: RefState -> String -> IO (Maybe String)
2827
loadFile ref s = do
29-
writeFile "disco-live.disco" s
30-
repl0 <- readIORef ref
31-
(result, repl1) <-
32-
Interpreter.execute (":load disco-live.disco") repl0
33-
writeIORef ref repl1
34-
pure result
35-
36-
initDisco :: IO RefRepl
37-
initDisco = do
38-
-- NOTE: We set path environment variables here,
39-
-- because processing the .wasm module with `wizer` may bake
40-
-- them into the code.
41-
setEnv "disco_datadir" "stdlib"
42-
newIORef Interpreter.initial
28+
AppState repl0 h <- readIORef ref
29+
let h' = hash s
30+
if h' /= h && not (all isSpace s)
31+
then do
32+
writeFile "disco-live.disco" s
33+
(result, repl1) <- Interpreter.execute (":load disco-live.disco") repl0
34+
writeIORef ref (AppState repl1 h')
35+
pure (Just result)
36+
else
37+
pure Nothing

src/Interpreter.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{-# LANGUAGE RankNTypes #-}
44
{-# LANGUAGE PolyKinds #-}
55
{-# LANGUAGE TypeApplications #-}
6-
module Interpreter
6+
module Interpreter
77
( Repl
88
, Command
99
, Result
@@ -15,7 +15,7 @@ import Disco.AST.Surface (emptyModule)
1515
import Disco.Context hiding (filter)
1616
import Disco.Error
1717
import Disco.Eval
18-
import Disco.Interactive.Commands
18+
import Disco.Interactive.Commands
1919
( dispatch
2020
, discoCommands
2121
, parseLine

src/Main.hs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module Main where
33
import Control.Monad (when)
44
import GHC.Wasm.Prim
55

6-
import Eval (RefRepl, eval, initDisco, loadFile)
6+
import Eval (eval, loadFile)
7+
import State
78

89
{-----------------------------------------------------------------------------
910
JavaScript Imports
@@ -52,7 +53,7 @@ foreign export javascript "setup" setup :: IO ()
5253
-- | Main entrypoint.
5354
setup :: IO ()
5455
setup = do
55-
ref <- initDisco
56+
ref <- initState
5657

5758
-- Register callback for button click.
5859
evalButton <- js_document_getElementById (toJSString "eval")
@@ -64,25 +65,27 @@ setup = do
6465
js_addEventListener exprIn (toJSString "keyup") callback
6566

6667
-- | Handle 'keyup'.
67-
onExprKeyUp :: RefRepl -> JSVal -> IO ()
68+
onExprKeyUp :: RefState -> JSVal -> IO ()
6869
onExprKeyUp ref event = do
6970
key <- js_event_key event
7071
when (fromJSString key == "Enter") $ handleEval ref
7172

7273
-- | Handle button clicks.
73-
onEvalButtonClick :: RefRepl -> JSVal -> IO ()
74+
onEvalButtonClick :: RefState -> JSVal -> IO ()
7475
onEvalButtonClick ref _ = handleEval ref
7576

7677
-- | Handle evaluation request.
77-
handleEval :: RefRepl -> IO ()
78+
handleEval :: RefState -> IO ()
7879
handleEval ref = do
7980
module_ <- fromJSString <$> js_view_state_doc_toString
8081
exprIn <- js_document_getElementById (toJSString "expr")
8182
expr <- fromJSString <$> js_input_value exprIn
8283

8384
logHistory $ "disco> " <> expr
84-
result <- loadFile ref module_
85-
logHistory result
85+
mresult <- loadFile ref module_
86+
case mresult of
87+
Nothing -> pure ()
88+
Just result -> logHistory result
8689
result <- eval ref expr
8790
logHistory result
8891

src/State.hs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module State
2+
( AppState (..)
3+
, RefState
4+
, initState
5+
)
6+
where
7+
8+
import Data.IORef
9+
import System.Environment
10+
11+
import qualified Interpreter
12+
13+
data AppState = AppState
14+
{ replState :: !Interpreter.Repl
15+
, editorHash :: !Int
16+
}
17+
18+
type RefState = IORef AppState
19+
20+
initState :: IO RefState
21+
initState = do
22+
repl <- initDisco
23+
newIORef (AppState repl 0)
24+
25+
initDisco :: IO Interpreter.Repl
26+
initDisco = do
27+
-- NOTE: We set path environment variables here,
28+
-- because processing the .wasm module with `wizer` may bake
29+
-- them into the code.
30+
setEnv "disco_datadir" "stdlib"
31+
pure Interpreter.initial

0 commit comments

Comments
 (0)