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

Last change on this file since 4223 was 3855, checked in by cameron, 5 years ago

Generalize Advance(x) to Advance(x, n)

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