source: proto/RE/Haskell/RunPablo.hs @ 3619

Last change on this file since 3619 was 3599, checked in by cameron, 6 years ago

Haskell prototype interpreter and regular expression simulator

File size: 3.9 KB
RevLine 
[3599]1--
2-- module RunPablo performs simulated execution of Pablo statements
3--
4module RunPablo (PabloE(..), PabloS(..), PabloVal(..), PabloStore, evalPabloE, runPabloS, evalPabloS) where
5
6import Data.Bits
7
8data PabloE = All(Int) | Var(String) | And(PabloE, PabloE) | Or(PabloE, PabloE) | Not(PabloE)
9              | CharClass(String) | Advance(PabloE) | MatchStar(PabloE, PabloE) 
10   deriving Show 
11
12data PabloS = Assign(String, PabloE) |  If (PabloE, [PabloS])| While (PabloE, [PabloS]) 
13   deriving Show
14
15-- values in Pablo are bitstreams represented as arbitrary length integers
16-- or undefined
17data PabloVal = Undefined | Bitstream Integer deriving (Show, Eq)
18
19------------------------------------------------------------------------------
20-- A PabloStore is a representation mapping variable names to values
21-- We use a simple list of pairs representation.
22
23type PabloStore = [(String, PabloVal)]
24
25lookUp :: (PabloStore, String) -> PabloVal
26lookUp ([], key) = Undefined
27lookUp ((k1, v1):more, key) 
28  | k1 == key  = v1
29  | otherwise  = lookUp(more, key)
30
31store :: (PabloStore, String, PabloVal) -> PabloStore
32store(mem, key, v) = (key, v): mem
33------------------------------------------------------------------------------
34--
35-- We can now evaluate a Pablo expression in the context of a
36-- store and a text string
37
38evalPabloE :: (PabloE, PabloStore, String) -> PabloVal
39
40evalPabloE (All 0, m, t) = Bitstream 0
41evalPabloE (All 1, m, t) = Bitstream (-1)
42
43evalPabloE (Var s, m, t) = lookUp(m, s)
44
45evalPabloE (And(e1, e2), m, t) = applyBinary(pabloAnd, evalPabloE(e1, m, t), evalPabloE(e2, m, t))
46evalPabloE (Or(e1, e2), m, t) = applyBinary(pabloOr, evalPabloE(e1, m, t), evalPabloE(e2, m, t))
47evalPabloE (MatchStar(e1, e2), m, t) = applyBinary(matchStar, evalPabloE(e1, m, t), evalPabloE(e2, m, t))
48
49evalPabloE (Not(e), m, t) = applyUnary(pabloNot, evalPabloE(e, m, t))
50evalPabloE (Advance(e), m, t) = applyUnary(pabloAdvance, evalPabloE(e, m, t))
51
52evalPabloE (CharClass(c), m, t) = computeCharClass(c, t)
53
54
55applyBinary :: ((Integer, Integer) -> Integer, PabloVal, PabloVal) -> PabloVal
56applyBinary (op, Bitstream a, Bitstream b) = Bitstream (op(a, b))
57applyBinary (op, _, _) = Undefined
58
59applyUnary :: (Integer -> Integer, PabloVal) -> PabloVal
60applyUnary (op, Bitstream a) = Bitstream (op a)
61applyUnary (op, _) = Undefined
62
63pabloAnd :: (Integer, Integer) -> Integer
64pabloAnd (a, b) = a .&. b
65
66pabloOr :: (Integer, Integer) -> Integer
67pabloOr (a, b) = a .|. b
68
69pabloXor :: (Integer, Integer) -> Integer
70pabloXor (a, b) = xor a b
71
72matchStar :: (Integer, Integer) -> Integer
73matchStar (m, c) = pabloOr(m, pabloXor(pabloAnd(m, c) + c, c))
74
75pabloNot :: Integer -> Integer
76pabloNot(a) = complement(a)
77
78pabloAdvance :: Integer -> Integer
79pabloAdvance(a) = a + a
80
81computeCharClass(cc, t) = Bitstream (computeCC_helper(cc, t, 1))
82computeCC_helper(cc, [], powerOf2) = 0
83computeCC_helper(cc, c:cs, powerOf2)
84   | elem c cc = powerOf2 + computeCC_helper(cc, cs, (powerOf2 * 2))
85   | otherwise = computeCC_helper(cc, cs, (powerOf2 * 2))
86
87------------------------------------------------------------------------------
88--
89-- We can now execute a Pablo program in the context of a text string
90--
91
92runPabloS :: ([PabloS], PabloStore, String) -> PabloStore
93
94runPabloS ([], m, text) = m
95
96runPabloS(Assign(v, e): moreS, m, text) = runPabloS(moreS, store(m, v, evalPabloE(e, m, text)), text)
97
98runPabloS(If(e, stmts): moreS, m, text)
99  | evalPabloE(e, m, text) /= Bitstream 0 = runPabloS(moreS, runPabloS(stmts, m, text), text)
100  | otherwise                             = runPabloS(moreS, m, text)
101
102runPabloS(While(e, stmts): moreS, m, text)
103  | evalPabloE(e, m, text) /= Bitstream 0 = runPabloS(While(e, stmts): moreS, runPabloS(stmts, m, text), text)
104  | otherwise                             = runPabloS(moreS, m, text)
105
106
107evalPabloS :: ([PabloS], String, String) -> PabloVal
108evalPabloS(program, output_var, text) = lookUp(runPabloS(program, [], text), output_var)
109
Note: See TracBrowser for help on using the repository browser.