Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
module Trans where
splitAtLast (x : xs)
| null xs
= ([] , x)
| otherwise
= let
(bs , a)
= splitAtLast xs
in
(x : bs , a)
type Var
= String
type Num
= Int
type AM
= [AMAtom]
data AMAtom
= PushN Num
| Add
| Mult
| Sub
| PushT Bool
| Eq
| Le
| And
| Neg
| Fetch Var
| Store Var
| Noop
| Branch AM AM
| Loop AM
data AExp
= AConst Num
| Var Var
| AExp :+: AExp
| AExp :-: AExp
| AExp :*: AExp
data BExp
= BConst Bool
| AExp :=: AExp
| AExp :<=: AExp
| Not BExp
| BExp :&: BExp
data W
= Assign Var AExp
| Skip
| W :. W
| Cond BExp W W
| While BExp W
class SX a where
atomic :: a -> Bool
instance SX AExp where
atomic e
= case e of
AConst _
-> True
Var _
-> True
_
-> False
instance SX BExp where
atomic e
= case e of
e1 :&: e2
-> False
_
-> True
instance SX W where
atomic s
= case s of
Assign _ _
-> True
Skip
-> True
_
-> False
instance SX AMAtom where
atomic _
= True
instance SX a => SX [a] where
atomic _
= False
pShowsPrec z w s
| atomic w
= showsPrec z w s
| otherwise
= '(' : showsPrec z w (')' : s)
instance Show AMAtom where
showsPrec z a s
= let
help
= case a of
Add
-> "ADD"
Mult
-> "MULT"
Sub
-> "SUB"
Eq
-> "EQ"
Le
-> "LE"
And
-> "AND"
Neg
-> "NEG"
Noop
-> "NOOP"
in
case a of
PushN n
-> "PUSHN-" ++ showsPrec z n s
PushT t
-> "PUSHT-" ++ showsPrec z t s
Fetch x
-> "FETCH-" ++ x ++ s
Store x
-> "STORE-" ++ x ++ s
Branch xs ys
-> "BRANCH " ++ pShowsPrec z xs (' ' : pShowsPrec z ys s)
Loop xs
-> "LOOP " ++ pShowsPrec z xs s
_
-> help ++ s
showList as s
| null as
= "eps" ++ s
| otherwise
= let
(bs , a)
= splitAtLast as
in
foldr (\a s -> pShowsPrec 0 a (" ; " ++ s)) (pShowsPrec 0 a s) bs
instance Show AExp where
showsPrec z exp s
= case exp of
AConst n
-> showsPrec z n s
Var x
-> showsPrec z x s
e1 :+: e2
-> pShowsPrec z e1 (" + " ++ pShowsPrec z e2 s)
e1 :-: e2
-> pShowsPrec z e1 (" - " ++ pShowsPrec z e2 s)
e1 :*: e2
-> pShowsPrec z e1 (" * " ++ pShowsPrec z e2 s)
instance Show BExp where
showsPrec z exp s
= case exp of
BConst b
-> showsPrec z b s
e1 :=: e2
-> showsPrec z e1 (" = " ++ showsPrec z e2 s)
e1 :<=: e2
-> showsPrec z e1 (" <= " ++ showsPrec z e2 s)
Not e
-> "not " ++ pShowsPrec z e s
e1 :&: e2
-> pShowsPrec z e1 (" and " ++ pShowsPrec z e2 s)
instance Show W where
showsPrec z stmt s
= case stmt of
Assign x e
-> showsPrec z x (" := " ++ showsPrec z e s)
Skip
-> "skip" ++ s
s1 :. s2
-> pShowsPrec z s1 (" ; " ++ pShowsPrec z s2 s)
Cond e s1 s2
-> "if" ++
showsPrec z e (
" then " ++
showsPrec z s1 (
" else " ++ showsPrec z s2 s
)
)
While e s1
-> "while " ++ showsPrec z e (" do " ++ showsPrec z s1 s)
class Trans a where
trans :: a -> AM
transsPrec :: a -> AM -> AM
trans
= flip transsPrec []
transsPrec x as
= trans x ++ as
instance Trans AExp where
transsPrec e as
= case e of
AConst n
-> PushN n : as
Var x
-> Fetch x : as
e1 :+: e2
-> transsPrec e2 (transsPrec e1 (Add : as))
e1 :-: e2
-> transsPrec e2 (transsPrec e1 (Sub : as))
e1 :*: e2
-> transsPrec e2 (transsPrec e1 (Mult : as))
instance Trans BExp where
transsPrec e as
= case e of
BConst t
-> PushT t : as
e1 :=: e2
-> transsPrec e2 (transsPrec e1 (Eq : as))
e1 :<=: e2
-> transsPrec e2 (transsPrec e1 (Le : as))
Not e1
-> transsPrec e1 (Neg : as)
e1 :&: e2
-> transsPrec e2 (transsPrec e1 (And : as))
instance Trans W where
transsPrec s as
= case s of
Assign x e
-> transsPrec e (Store x : as)
Skip
-> Noop : as
s1 :. s2
-> transsPrec s1 (transsPrec s2 as)
Cond e s1 s2
-> transsPrec e (Branch (trans s1) (trans s2) : as)
While e s1
-> let
help
= trans e
in
help ++ Loop (transsPrec s1 help) : as