forked from purescript/purescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExpr.hs
More file actions
122 lines (110 loc) · 2.87 KB
/
Expr.hs
File metadata and controls
122 lines (110 loc) · 2.87 KB
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
-- |
-- The core functional representation
--
module Language.PureScript.CoreFn.Expr where
import Prelude.Compat
import Control.Arrow ((***))
import Language.PureScript.AST.Literals
import Language.PureScript.CoreFn.Binders
import Language.PureScript.Names
import Language.PureScript.PSString (PSString)
-- |
-- Data type for expressions and terms
--
data Expr a
-- |
-- A literal value
--
= Literal a (Literal (Expr a))
-- |
-- A data constructor (type name, constructor name, field names)
--
| Constructor a (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident]
-- |
-- A record property accessor
--
| Accessor a PSString (Expr a)
-- |
-- Partial record update
--
| ObjectUpdate a (Expr a) [(PSString, Expr a)]
-- |
-- Function introduction
--
| Abs a Ident (Expr a)
-- |
-- Function application
--
| App a (Expr a) (Expr a)
-- |
-- Variable
--
| Var a (Qualified Ident)
-- |
-- A case expression
--
| Case a [Expr a] [CaseAlternative a]
-- |
-- A let binding
--
| Let a [Bind a] (Expr a)
deriving (Show, Functor)
-- |
-- A let or module binding.
--
data Bind a
-- |
-- Non-recursive binding for a single value
--
= NonRec a Ident (Expr a)
-- |
-- Mutually recursive binding group for several values
--
| Rec [((a, Ident), Expr a)] deriving (Show, Functor)
-- |
-- A guard is just a boolean-valued expression that appears alongside a set of binders
--
type Guard a = Expr a
-- |
-- An alternative in a case statement
--
data CaseAlternative a = CaseAlternative
{ -- |
-- A collection of binders with which to match the inputs
--
caseAlternativeBinders :: [Binder a]
-- |
-- The result expression or a collect of guarded expressions
--
, caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
} deriving (Show)
instance Functor CaseAlternative where
fmap f (CaseAlternative cabs car) = CaseAlternative
(fmap (fmap f) cabs)
(either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
-- |
-- Extract the annotation from a term
--
extractAnn :: Expr a -> a
extractAnn (Literal a _) = a
extractAnn (Constructor a _ _ _) = a
extractAnn (Accessor a _ _) = a
extractAnn (ObjectUpdate a _ _) = a
extractAnn (Abs a _ _) = a
extractAnn (App a _ _) = a
extractAnn (Var a _) = a
extractAnn (Case a _ _) = a
extractAnn (Let a _ _) = a
-- |
-- Modify the annotation on a term
--
modifyAnn :: (a -> a) -> Expr a -> Expr a
modifyAnn f (Literal a b) = Literal (f a) b
modifyAnn f (Constructor a b c d) = Constructor (f a) b c d
modifyAnn f (Accessor a b c) = Accessor (f a) b c
modifyAnn f (ObjectUpdate a b c) = ObjectUpdate (f a) b c
modifyAnn f (Abs a b c) = Abs (f a) b c
modifyAnn f (App a b c) = App (f a) b c
modifyAnn f (Var a b) = Var (f a) b
modifyAnn f (Case a b c) = Case (f a) b c
modifyAnn f (Let a b c) = Let (f a) b c