-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstepEvaluator.hs
213 lines (184 loc) · 7.88 KB
/
stepEvaluator.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
{-# LANGUAGE GADTs, TemplateHaskell #-}
{- Davin Chia, Kit Tse
- CS413 Final Project
-
- stepMachine.hs
-}
import Language.Haskell.TH
import Language.Haskell.Meta.Parse
import Language.Haskell.TH.Syntax
import MapParser
import MapExpr
main :: IO ()
main = do putStrLn "Please enter source code: "
code <- getLine
let Right ast = parseExp code
putStrLn (show ast)
-- checks to make sure AST produced from source code is as expected;
-- program quits if not
let validStructure = validateASTStructure ast
if (not validStructure)
then do putStrLn "Unexpected src code format. Please try again.\n"
main
else do putStrLn "Structure: check."
-- checks to make sure source code deals with Integer type (for now);
-- quits if not
let validType = validateIntegerType ast
if (not validType)
then do putStrLn "Invalid type. Please try again.\n"
main
else do putStrLn "Type: check."
-- checks to make sure source code uses allowed operator;
-- currently supports: +, *, -, /, ==, /=, <, >, <=, >=
-- quits if not
let validOp = validateOp ast
if (not validOp)
then do putStrLn "Invalid operation. Please try again.\n"
main
else do putStrLn "Operation: check.\n"
-- turns Exp from source code into our own Expr;
-- if conversation/translation is successful, evaluate it step by
-- step
let result = parseAST ast
run result
-- asks user for another line of source code
main
nextState :: Expr -> Expr
nextState m@(Map (IMap cur lExp args)) = Map iMap
where baseCase = eval cur
nextVal = I (head (eval args))
remainder = drop 1 (eval args)
exp = convertILExprToExpr lExp
iMap = IMap (IL (baseCase ++ [ eval . exp $ nextVal ])) lExp
(IL remainder)
nextState m@(Map (DMap cur lExp args)) = Map dMap
where baseCase = eval cur
nextVal = D (head (eval args))
remainder = drop 1 (eval args)
exp = convertDLExprToExpr lExp
dMap = DMap (DL (baseCase ++ [ eval . exp $ nextVal ])) lExp
(DL remainder)
nextState m@(Map (BMap cur lExp args)) = Map bMap
where baseCase = eval cur
nextVal = I (head (eval args))
remainder = drop 1 (eval args)
result = eval . (convertBLExprToExpr lExp) $ nextVal
bMap = BMap (BL (baseCase ++ [ result ])) lExp
(IL remainder)
nextState m@(Filter (IFilter cur lExp args)) = Filter iFil
where baseCase = eval cur
nextVal = I (head (eval args))
remainder = drop 1 (eval args)
predicate = convertBLExprToExpr lExp
result = eval . predicate $ nextVal
iFil = IFilter (IL ((\r -> if r then baseCase ++ [ eval $ nextVal ] else baseCase) result)) lExp
(IL remainder)
nextState m@(Foldl (IFoldL ifOp curr args)) = Foldl iFoldl
where nextVal = I (head (eval args))
remainder = drop 1 (eval args)
result = eval $ (convertInfixLExprToExpr ifOp) curr nextVal
iFoldl = IFoldL ifOp (I result)
(IL remainder)
-- run prints the current state and calculates the next state
run :: Expr -> IO ()
run (Map (IMap cur _ (IL []))) = putStrLn $ show cur
run e@(Map m@(IMap cur lExp args)) = do
let bc = eval cur
let nextVal = I (head (eval args))
let remainder = drop 1 (eval args)
let op = convertILExprToExpr lExp
let exp = op nextVal
let evalExp = eval exp
let state = nextState e
putStrLn $ show m
putStrLn $ " 1. " ++ show bc ++ " : " ++ show exp ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 2. " ++ show bc ++ " : " ++ show evalExp ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 3. " ++ show (bc ++ [evalExp]) ++ " : map " ++ show lExp
++ " " ++ show remainder ++ "\n"
run state
run (Map (DMap cur _ (DL []))) = putStrLn $ show cur
run e@(Map m@(DMap cur lExp args)) = do
let bc = eval cur
let nextVal = D (head (eval args))
let remainder = drop 1 (eval args)
let op = convertDLExprToExpr lExp
let exp = op nextVal
let evalExp = eval exp
let state = nextState e
putStrLn $ show m
putStrLn $ " 1. " ++ show bc ++ " : " ++ show exp ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 2. " ++ show bc ++ " : " ++ show evalExp ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 3. " ++ show (bc ++ [evalExp]) ++ " : map " ++ show lExp
++ " " ++ show remainder ++ "\n"
run state
run (Map (BMap cur _ (IL []))) = putStrLn $ show cur
run e@(Map m@(BMap cur lExp args)) = do
let bc = eval cur
let nextVal = I (head (eval args))
let remainder = drop 1 (eval args)
let predicate = convertBLExprToExpr lExp
let exp = predicate nextVal
let result = eval exp
let state = nextState e
putStrLn $ show m
putStrLn $ " 1. " ++ show bc ++ " : " ++ show exp ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 2. " ++ show bc ++ " : " ++ show result ++ " : map "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 3. " ++ show (bc ++ [result]) ++ " : map " ++ show lExp
++ " " ++ show remainder ++ "\n"
run state
run (Filter (IFilter cur _ (IL []))) = putStrLn $ show cur
run e@(Filter m@(IFilter cur lExp args)) = do
let bc = eval cur
let nextVal = I (head (eval args))
let remainder = drop 1 (eval args)
let predicate = convertBLExprToExpr lExp
let exp = predicate nextVal
let result = eval exp
let state = nextState e
putStrLn $ show m
putStrLn $ " 1. " ++ show bc ++ " : " ++ show exp ++ " : filter "
++ show lExp ++ " " ++ show remainder
putStrLn $ " 2. " ++ show bc ++ " : " ++ show result ++ " : filter "
++ show lExp ++ " " ++ show remainder
if (result)
then do
putStrLn $ " 3. " ++ show bc ++ " : " ++ show nextVal ++ " : filter " ++ show lExp
++ " " ++ show remainder
putStrLn $ " 4. " ++ show (bc ++ [eval nextVal]) ++ " : filter " ++ show lExp
++ " " ++ show remainder ++ "\n"
else do
putStrLn $ " 3. " ++ show bc ++ " : None : filter " ++ show lExp
++ " " ++ show remainder
putStrLn $ " 4. " ++ show bc ++ " : filter " ++ show lExp
++ " " ++ show remainder ++ "\n"
run state
run (Foldl (IFoldL _ cur (IL []))) = putStrLn $ show cur
run e@(Foldl m@(IFoldL ifOp cur args)) = do
let nextVal = I (head (eval args))
let remainder = drop 1 (eval args)
let op = (convertInfixLExprToExpr ifOp) cur nextVal
let result = eval op
let state = nextState e
putStrLn $ show m
putStrLn $ " 1. foldl "
++ show ifOp ++ " (" ++ show op ++ ") " ++ show remainder
putStrLn $ " 2. foldl "
++ show ifOp ++ " (" ++ show result ++ ") " ++ show remainder
-- if (result)
-- then do
-- putStrLn $ " 3. " ++ show bc ++ " : " ++ show nextVal ++ " : filter " ++ show lExp
-- ++ " " ++ show remainder
-- putStrLn $ " 4. " ++ show (bc ++ [eval nextVal]) ++ " : filter " ++ show lExp
-- ++ " " ++ show remainder ++ "\n"
-- else do
-- putStrLn $ " 3. " ++ show bc ++ " : None : filter " ++ show lExp
-- ++ " " ++ show remainder
-- putStrLn $ " 4. " ++ show bc ++ " : filter " ++ show lExp
-- ++ " " ++ show remainder ++ "\n"
run state