-
Notifications
You must be signed in to change notification settings - Fork 0
/
KarelSemantics.hs
59 lines (51 loc) · 2.37 KB
/
KarelSemantics.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
-- | Team Members: Bryce Egley ONID: egleyb, Kenneth Price ONID: pricek, Kenneth Thompson ONID: thomkenn
module KarelSemantics where
import Prelude hiding (Either(..))
import Data.Function (fix)
import KarelSyntax
import KarelState
-- | Valuation function for Test.
test :: Test -> World -> Robot -> Bool
test (Not t) w r = not (test t w r)
test (Facing c) _ r = c == (getFacing r)
test (Clear d) w r = isClear (relativePos d r) w
test Beeper w r = hasBeeper (getPos r) w
test Empty _ r = isEmpty r
-- | Valuation function for Stmt.
stmt :: Stmt -> Defs -> World -> Robot -> Result
stmt Shutdown _ _ r = Done r
stmt PickBeeper _ w r = let p = getPos r
in if hasBeeper p w
then OK (decBeeper p w) (incBag r)
else Error ("No beeper to pick at: " ++ show p)
stmt Move _ w r = let np = (relativePos Front r) in
if isClear np w
then OK w (setPos (relativePos Front r) r)
else Error ("Blocked at: " ++ show np)
stmt PutBeeper _ w r = let p = getPos r in
if not (isEmpty r)
then OK (incBeeper p w) (decBag r)
else Error ("No beeper to put.")
stmt (Turn d) _ w r = OK w (updateFacing (cardTurn d) r)
stmt (Block [s]) m w r = stmt s m w r
stmt (Block (s:ss)) m w r = case (stmt s m w r) of
(OK wn rn) -> stmt (Block ss) m wn rn
res -> res
stmt (If t s1 s2) m w r = if (test t w r) then (stmt s1 m w r) else (stmt s2 m w r)
stmt (Call c) m w r = case (lookup c m) of
Just s -> stmt s m w r
Nothing -> Error ("Undefined macro: " ++ c)
stmt (Iterate 1 s) m w r = stmt s m w r
stmt (Iterate i s) m w r = case (stmt s m w r) of
(OK wn rn) -> stmt (Iterate (i-1) s) m wn rn
res -> res
stmt (While t s) m w r = if (test t w r)
then case (stmt s m w r) of
(OK wn rn) -> stmt (While t s) m wn rn
res -> res
else
(OK w r)
stmt _ _ _ _ = Error ("Invalid command");
-- | Run a Karel program.
prog :: Prog -> World -> Robot -> Result
prog (m,s) w r = stmt s m w r