-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathTypes.hs
109 lines (90 loc) · 3.07 KB
/
Types.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
module Types where
import qualified Data.Map as M
data Insn =
Label String
| Block [Insn]
| Jmp String
| JmpCond String
| Get String
| Set String
| Arith ([Value] -> [[Value]])
| Enter String
| TryEnter String
| Leave String
| Spawn String Prog
| Assert String
instance Show Insn where
show (Label s) = "label " ++ s ++ ":"
show (Block is) = "block " ++ show is
show (Jmp s) = "jmp " ++ s
show (JmpCond s) = "jmpcond " ++ s
show (Get s) = "get " ++ s
show (Set s) = "set " ++ s
show (Arith _) = "arith <...>"
show (Enter s) = "enter " ++ s
show (TryEnter s) = "tryenter " ++ s
show (Leave s) = "leave " ++ s
show (Spawn s _) = "spawn " ++ s
show (Assert s) = "assert " ++ s
data Value = IntValue Int | BoolValue Bool | PidValue Pid deriving (Ord, Eq)
instance Show Value where
show (IntValue i) = show i
show (BoolValue b) = show b
show (PidValue p) = show p
data Pid = Pid Int deriving (Eq, Ord)
instance Show Pid where
show (Pid p) = show p
data Prog = Prog
{
prog_insns :: [Insn]
}
data ProcState = Running
{
proc_prog :: Prog,
proc_ip :: Int,
proc_stack :: [Value],
proc_waitedMon :: Maybe String
}
| Finished
data MonState = MonFree | MonOccupied { mon_owner :: Pid, mon_depth :: Int {- , mon_waiters :: Queue Pid -} } deriving (Ord, Eq, Show)
data ProgramState = ProgramState
{
st_procs :: M.Map Pid (String, ProcState),
st_vars :: M.Map String Value,
st_mons :: M.Map String MonState,
st_lastStepped :: Maybe Pid
}
instance Show ProgramState where
show st = show (st_vars st, st_mons st, [(pid, name, showProc p) | (pid,(name,p)) <- M.toList (st_procs st)])
where
showProc Finished = "<finished>"
showProc r@Running{proc_waitedMon=Nothing, proc_ip=ip} = show ip
showProc r@Running{proc_waitedMon=Just m, proc_ip=ip} = show ip ++ "?" ++ m
stateSig s = (st_vars s, st_mons s, [(pid, sigP p) | (pid,(name,p)) <- M.toList (st_procs s)] )
where
sigP Finished = Nothing
sigP r@Running{} = Just (proc_ip r, proc_stack r, proc_waitedMon r)
instance Eq ProgramState where
(==) a b = (stateSig a == stateSig b)
instance Ord ProgramState where
compare a b = compare (stateSig a) (stateSig b)
initState :: [(String,Value)] -> [String] -> Prog -> ProgramState
initState vars mons entryPoint = ProgramState {
st_procs = M.fromList [(Pid 0, ("entry", Running {proc_prog = entryPoint, proc_ip = 0, proc_stack = [], proc_waitedMon = Nothing}))],
st_vars = M.fromList vars,
st_mons = M.fromList [(m, MonFree) | m <- mons],
st_lastStepped = Nothing
}
compile :: [Insn] -> Prog
compile is = Prog {prog_insns = expandBlocks is}
where
expandBlocks = concatMap (\i -> case i of { Block is -> expandBlocks is ; j -> [j] })
isLocal :: Insn -> Bool
isLocal (Block insns) = all isLocal insns
isLocal Get{} = False
isLocal Set{} = False
isLocal Enter{} = False
isLocal TryEnter{} = False
isLocal Leave{} = False
isLocal Spawn{} = False
isLocal _ = True