-
Notifications
You must be signed in to change notification settings - Fork 2
/
Syntax.hs
101 lines (88 loc) · 2.63 KB
/
Syntax.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
module Syntax where
import Descend
import Control.Monad
-- Abstact syntax
-- ==============
type Id = String
type Guard = Maybe Exp
data Exp =
Bind Exp Exp
| Apply Exp [Exp]
| Tuple [Exp]
| Case Exp [(Exp, Guard, [Exp])]
| If [(Exp, [Exp])]
| Cond Exp [Exp] [Exp]
| Lambda [([Exp], Guard, [Exp])]
| Int Integer
| List [Exp]
| ListComp Exp [ListCompStmt]
| ListEnum Exp Exp
| Do Id [DoStmt]
| Cons Exp Exp
| Id Id
| Atom Id
| Var Id
| Fun Id Int
| Closure Id Int
deriving (Eq, Show)
data ListCompStmt =
ListCompGuard Exp
| ListCompBind Exp Exp
deriving (Eq, Show)
data DoStmt =
DoExpr Exp
| DoBind Exp Exp
deriving (Eq, Show)
data Decl =
ImportDecl Id
| FunDecl Id [Exp] Guard [Exp]
| ClosureDecl Id [Id] [Exp] Guard [Exp]
deriving Show
-- Primitives
-- ==========
isPrim :: Id -> Bool
isPrim id = id `elem`
[ "+", "-", "==", "/=", "<", "<=", ">", ">="
, "band", "bor", "bxor", "bsl", "bsr", "bsra"
]
-- Traversal
-- =========
instance Descend Exp where
descendM f (Bind p e) = Bind <$> f p <*> f e
descendM f (Apply x es) = Apply <$> f x <*> mapM f es
descendM f (Tuple es) = Tuple <$> mapM f es
descendM f (Case e alts) = Case <$> f e <*>
sequence [ (,,) <$> f p <*> mapM f g <*> mapM f es | (p, g, es) <- alts ]
descendM f (If alts) = If <$>
sequence [ (,) <$> f c <*> mapM f es | (c, es) <- alts ]
descendM f (Cond cond es0 es1) =
Cond <$> f cond <*> mapM f es0 <*> mapM f es1
descendM f (Lambda eqns) = Lambda <$>
sequence [ (,,) <$> mapM f ps <*> mapM f g <*> mapM f rhs
| (ps, g, rhs) <- eqns ]
descendM f (ListComp e stmts) =
ListComp <$> f e <*> mapM listCompStmt stmts
where
listCompStmt (ListCompGuard e) = ListCompGuard <$> f e
listCompStmt (ListCompBind p e) = ListCompBind <$> f p <*> f e
descendM f (Do mod stmts) = Do mod <$> mapM doStmt stmts
where
doStmt (DoExpr e) = DoExpr <$> f e
doStmt (DoBind p e) = DoBind <$> f p <*> f e
descendM f (ListEnum from to) = ListEnum <$> f from <*> f to
descendM f (Id x) = return (Id x)
descendM f (Int i) = return (Int i)
descendM f (Fun g n) = return (Fun g n)
descendM f (Closure g n) = return (Closure g n)
descendM f (Atom a) = return (Atom a)
descendM f (Var v) = return (Var v)
descendM f (List es) = List <$> mapM f es
descendM f (Cons h t) = Cons <$> f h <*> f t
onExp :: (Exp -> Exp) -> [Decl] -> [Decl]
onExp f ds = map exp ds
where
exp (FunDecl v ps g es) =
FunDecl v (map f ps) (f `fmap` g) (map f es)
exp (ClosureDecl v vs ps g es) =
ClosureDecl v vs (map f ps) (f `fmap` g) (map f es)
exp other = other