-
Notifications
You must be signed in to change notification settings - Fork 0
/
Interpreter1.hs
84 lines (69 loc) · 2.42 KB
/
Interpreter1.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
--------------------------------------------------------------------------------
-- Pepe Gallardo, January 2004
--
-- A monadic interpreter for Dijkstra's Guarded Command Language:
-- https://en.wikipedia.org/wiki/Guarded_Command_Language
--
-- Initial version (without non-determinism neither environments)
--
-- Drawbacks: * Language is deterministic
-- * We must propagate enviroment through different
-- functions making use of it
-- * Errors abort interpreter execution
--------------------------------------------------------------------------------
import qualified Environment as Env
import Expression
import Command
import Examples
import Data.List(intercalate)
import Control.Exception(catch, ErrorCall)
--------------------------------------------------------------------------------
-- The (identity) monad
--------------------------------------------------------------------------------
newtype Mon a = M a deriving Show
instance Monad Mon where
-- return :: a -> Mon a
return x = M x
-- fail :: String -> Mon a
fail str = error str
-- (>>=) :: Mon a -> (a -> Mon b) -> Mon b
M x >>= f = f x
--------------------------------------------------------------------------------
-- Sematics of commands
--------------------------------------------------------------------------------
-- Returns new Environment after executing sentence
sem :: Environment -> Command -> Mon Environment
sem rho Skip =
return rho
sem rho Abort =
fail "Program aborted"
sem rho (var := e) = do
v <- eval rho e
rho' <- Env.set rho (var,v)
return rho'
sem rho (s1 :$ s2) = do
rho' <- sem rho s1
rho'' <- sem rho' s2
return rho''
sem rho (If gs) = do
ss <- select rho gs
case ss of
[] -> fail "Program aborted: all guards are false"
s:_ -> sem rho s
sem rho (Do gs) = do
ss <- select rho gs
case ss of
[] -> return rho
s:_ -> sem rho (s :$ Do gs)
-- Running a program. Prints out final environment
run :: Command -> IO ()
run prog = printEnv rho `catch` \error -> print (error :: ErrorCall)
where
M rho = sem Env.empty prog
printEnv = putStrLn
. intercalate ", "
. Env.fold (\var val -> ((var++"->"++show val):)) []
--------------------------------------------------------------------------------
-- Run all examples
--------------------------------------------------------------------------------
main = sequence_ [ do run e; putStr "\n" | e <- examples ]