on master help sign in
Add ops, accessors, unit, and tuples to source AST

This has a couple benefits: - More explicit - Fewer type constraints generated - No more checking “is this a tuple?” everywhere - Cannot represent a tuple with one entry - No more checking “is this an operator?” everywhere This change also begins separating variable names into two parts: (1) maybe a qualifier and (2) the actual name. This should enable nicer lookups in the canonicalization phase.

commit9111afaf2945a19c5fb3d02492931836902f391d authorEvan Czaplicki <evancz@users.noreply.github.com> dateWed 11 Oct 2017, 15:14 (9 years ago) parent3b6fe38
3 files changed+107−164
src/AST/Expression/Source.hs+14−25 src/AST/Pattern.hs+61−109 src/AST/Type.hs+32−30
src/AST/Expression/Source.hs+14−25
@@ -3,17 +3,16 @@ module AST.Expression.Source
33 ( RawExpr, RawExpr', RawDef, RawDef'(..)
44 , ValidExpr, ValidExpr', ValidDef(..)
55 , Expr, Expr'(..)
6− , var, tuple, zero, getPattern, collectLambdas
6+ , zero, collectLambdas
77 )
88 where
99
10+
1011import Data.Text (Text)
1112
12−import qualified AST.Helpers as Help
1313import qualified AST.Literal as Literal
1414import qualified AST.Pattern as Ptrn
1515import qualified AST.Type as Type
16−import qualified AST.Variable as Var
1716import qualified Reporting.Annotation as A
1817import qualified Reporting.Region as R
1918
@@ -28,18 +27,21 @@ type Expr def =
2827
2928data Expr' def
3029 = Literal Literal.Literal
31− | Var Var.Raw
30+ | Var (Maybe Text) Text
3231 | List [Expr def]
32+ | Op Text
3333 | Binop [(Expr def, A.Located Text)] (Expr def)
3434 | Lambda Ptrn.Raw (Expr def)
3535 | App (Expr def) (Expr def)
3636 | If [(Expr def, Expr def)] (Expr def)
3737 | Let [def] (Expr def)
3838 | Case (Expr def) [(Ptrn.Raw, Expr def)]
39− | Ctor Text [Expr def]
39+ | Accessor Text
4040 | Access (Expr def) Text
41− | Update (Expr def) [(A.Located Text, Expr def)]
41+ | Update (A.Located Text) [(A.Located Text, Expr def)]
4242 | Record [(A.Located Text, Expr def)]
43+ | Unit
44+ | Tuple (Expr def) (Expr def) [Expr def]
4345 | GLShader Text Text Literal.Shader
4446
4547
@@ -61,38 +63,25 @@ type RawDef =
6163
6264
6365data RawDef'
64− = Definition Ptrn.Raw RawExpr
65− | Annotation Text Type.Raw
66+ = Annotation Text Type.Raw
67+ | Definition Text [Ptrn.Raw] RawExpr
68+ | Destructure Ptrn.Raw RawExpr
6669
6770
68−data ValidDef =
69− Def R.Region Ptrn.Raw ValidExpr (Maybe Type.Raw)
71+data ValidDef
72+ = VDefinition R.Region Text [Ptrn.Raw] ValidExpr (Maybe Type.Raw)
73+ | VDestructure R.Region Ptrn.Raw ValidExpr
7074
7175
7276
7377-- HELPERS
7478
7579
76−var :: Text -> Expr' def
77−var x =
78− Var (Var.Raw x)
79−
80−
81−tuple :: [Expr def] -> Expr' def
82−tuple expressions =
83− Ctor (Help.makeTuple (length expressions)) expressions
84−
85−
8680zero :: Expr' def
8781zero =
8882 Literal (Literal.IntNum 0)
8983
9084
91−getPattern :: ValidDef -> Ptrn.Raw
92−getPattern (Def _ pattern _ _) =
93− pattern
94−
95−
9685collectLambdas :: Expr def -> ([Ptrn.Raw], Expr def)
9786collectLambdas lexpr@(A.A _ expr) =
9887 case expr of
src/AST/Pattern.hs+61−109
@@ -1,160 +1,112 @@
11{-# OPTIONS_GHC -Wall #-}
22{-# LANGUAGE OverloadedStrings #-}
3−module AST.Pattern where
3+module AST.Pattern
4+ ( Raw
5+ , Raw_(..)
6+ , Canonical
7+ , Canonical_(..)
8+ , boundVars
9+ , member
10+ , boundVarSet
11+ , boundVarList
12+ )
13+ where
14+
415
5−import qualified Data.List as List
6−import Data.Monoid ((<>))
716import qualified Data.Set as Set
817import Data.Text (Text)
9−import qualified Data.Text.Lazy as LazyText
10−import Data.Text.Lazy.Builder (Builder, fromText, toLazyText)
1118
12−import qualified AST.Helpers as Help
1319import qualified AST.Literal as L
1420import qualified AST.Variable as Var
1521import qualified Reporting.Annotation as A
16−import qualified Reporting.Region as R
1722
1823
19−type Pattern ann var =
20− A.Annotated ann (Pattern' ann var)
2124
25+-- RAW
2226
23−data Pattern' ann var
24− = Ctor var [Pattern ann var]
25− | Record [Text]
26− | Alias Text (Pattern ann var)
27− | Var Text
28− | Anything
29− | Literal L.Literal
3027
28+type Raw = A.Located Raw_
3129
32−type Raw =
33− Pattern R.Region Var.Raw
3430
31+data Raw_
32+ = RCtor (Maybe Text) Text [Raw]
33+ | RRecord [Text]
34+ | RUnit
35+ | RTuple Raw Raw [Raw]
36+ | RList [Raw]
37+ | RCons Raw Raw
38+ | RAlias Text Raw
39+ | RVar Text
40+ | RAnything
41+ | RLiteral L.Literal
3542
36−type Raw' =
37− Pattern' R.Region Var.Raw
3843
3944
40−type Canonical =
41− Pattern R.Region Var.Canonical
45+-- CANONICAL
4246
4347
44−isVar :: Text -> Pattern ann var -> Bool
45−isVar name (A.A _ pattern) =
46− case pattern of
47− Var pName ->
48− name == pName
48+type Canonical = A.Located Canonical_
4949
50− _ ->
51− False
5250
51+data Canonical_
52+ = Ctor Var.Canonical [Canonical]
53+ | Record [Text]
54+ | Unit
55+ | Tuple Canonical Canonical [Canonical]
56+ | Alias Text Canonical
57+ | Var Text
58+ | Anything
59+ | Literal L.Literal
5360
54−list :: R.Position -> [Raw] -> Raw
55−list end patterns =
56− case patterns of
57− [] ->
58− A.at end end (Ctor (Var.Raw "[]") [])
5961
60− pattern@(A.A (R.Region start _) _) : rest ->
61− A.at start end (Ctor (Var.Raw "::") [pattern, list end rest])
6262
63+-- FIND VARIABLES
6364
64−tuple :: [Raw] -> Raw'
65−tuple patterns =
66− let
67− name =
68− Help.makeTuple (length patterns)
69− in
70− Ctor (Var.Raw name) patterns
7165
66+boundVars :: Raw -> [A.Located Text]
67+boundVars (A.A region pattern) =
68+ case pattern of
69+ RVar name ->
70+ [ A.A region name ]
7271
72+ RAlias name realPattern ->
73+ A.A region name : boundVars realPattern
7374
74−-- FIND VARIABLES
75+ RCtor _ _ patterns ->
76+ concatMap boundVars patterns
7577
78+ RRecord fields ->
79+ map (A.A region) fields
7680
77−boundVars :: Pattern ann var -> [A.Annotated ann Text]
78−boundVars (A.A ann pattern) =
79− case pattern of
80− Var x ->
81− [A.A ann x]
81+ RUnit ->
82+ []
8283
83− Alias name realPattern ->
84− A.A ann name : boundVars realPattern
84+ RTuple a b cs ->
85+ concatMap boundVars (a:b:cs)
8586
86− Ctor _ patterns ->
87− concatMap boundVars patterns
87+ RList xs ->
88+ concatMap boundVars xs
8889
89− Record fields ->
90− map (A.A ann) fields
90+ RCons a b ->
91+ boundVars a ++ boundVars b
9192
92− Anything ->
93+ RAnything ->
9394 []
9495
95− Literal _ ->
96+ RLiteral _ ->
9697 []
9798
9899
99−member :: Text -> Pattern ann var -> Bool
100+member :: Text -> Raw -> Bool
100101member name pattern =
101102 elem name (map A.drop (boundVars pattern))
102103
103104
104−boundVarSet :: Pattern ann var -> Set.Set Text
105+boundVarSet :: Raw -> Set.Set Text
105106boundVarSet pattern =
106107 Set.fromList (map A.drop (boundVars pattern))
107108
108109
109−boundVarList :: Pattern ann var -> [Text]
110+boundVarList :: Raw -> [Text]
110111boundVarList pattern =
111112 Set.toList (boundVarSet pattern)
112−
113−
114−
115−-- TO BUILDER
116−
117−
118−toString :: Canonical -> String
119−toString var =
120− LazyText.unpack (toLazyText (toBuilder False var))
121−
122−
123−toText :: Canonical -> Text
124−toText var =
125− LazyText.toStrict (toLazyText (toBuilder False var))
126−
127−
128−toBuilder :: Bool -> Canonical -> Builder
129−toBuilder needsParens (A.A _ pattern) =
130− case pattern of
131− Var name ->
132− fromText name
133−
134− Ctor name [] ->
135− if Var.isTuple name then "()" else fromText (Var.toText name)
136−
137− Ctor name args ->
138− if Var.isTuple name then
139− "( " <> mconcat (List.intersperse ", " (map (toBuilder False) args)) <> " )"
140− else
141− parensIf needsParens $
142− fromText (Var.toText name) <> mconcat (map (\arg -> " " <> toBuilder True arg) args)
143−
144− Record fields ->
145− "{" <> mconcat (List.intersperse "," (map fromText fields)) <> "}"
146−
147− Alias alias subPattern ->
148− parensIf needsParens $
149− toBuilder False subPattern <> " as " <> fromText alias
150−
151− Anything ->
152− "_"
153−
154− Literal literal ->
155− L.toBuilder literal
156−
157−
158−parensIf :: Bool -> Builder -> Builder
159−parensIf needsParens builder =
160− if needsParens then "(" <> builder <> ")" else builder
src/AST/Type.hs+32−30
@@ -6,7 +6,7 @@ module AST.Type
66 , Super(..)
77 , deepDealias, iteratedDealias, dealias
88 , collectLambdas
9− , tuple, cmd, sub
9+ , cmd, sub
1010 )
1111 where
1212
@@ -16,7 +16,6 @@ import Data.Binary
1616import qualified Data.Map as Map
1717import Data.Text (Text)
1818
19−import qualified AST.Helpers as Help
2019import qualified AST.Module.Name as ModuleName
2120import qualified AST.Variable as Var
2221import qualified Reporting.Annotation as A
@@ -34,8 +33,10 @@ type Raw =
3433data Raw'
3534 = RLambda Raw Raw
3635 | RVar Text
37− | RType (A.Located Var.Raw) [Raw]
36+ | RType R.Region (Maybe Text) Text [Raw]
3837 | RRecord [(A.Located Text, Raw)] (Maybe Raw)
38+ | RUnit
39+ | RTuple Raw Raw [Raw]
3940
4041
4142data Canonical
@@ -43,6 +44,8 @@ data Canonical
4344 | Var Text
4445 | Type Var.Canonical [Canonical]
4546 | Record [(Text, Canonical)] (Maybe Canonical)
47+ | Unit
48+ | Tuple Canonical Canonical [Canonical]
4649 | Aliased Var.Canonical [(Text, Canonical)] (Aliased Canonical)
4750 deriving (Eq, Ord)
4851
@@ -65,15 +68,6 @@ data Super
6568-- CONSTRUCT USEFUL TYPES
6669
6770
68−tuple :: R.Region -> [Raw] -> Raw
69−tuple region types =
70− let
71− name =
72− Var.Raw (Help.makeTuple (length types))
73− in
74− A.A region (RType (A.A region name) types)
75−
76−
7771cmd :: ModuleName.Canonical -> Text -> Canonical
7872cmd =
7973 effect Var.cmd
@@ -113,6 +107,12 @@ deepDealias tipe =
113107 Type name args ->
114108 Type name (map deepDealias args)
115109
110+ Unit ->
111+ Unit
112+
113+ Tuple a b cs ->
114+ Tuple (deepDealias a) (deepDealias b) (map deepDealias cs)
115+
116116
117117iteratedDealias :: Canonical -> Canonical
118118iteratedDealias tipe =
@@ -156,6 +156,12 @@ dealiasHelp typeTable tipe =
156156 Type name args ->
157157 Type name (map go args)
158158
159+ Unit ->
160+ Unit
161+
162+ Tuple a b cs ->
163+ Tuple (go a) (go b) (map go cs)
164+
159165
160166
161167-- COLLECT LAMBDAS
@@ -178,29 +184,23 @@ collectLambdas tipe =
178184instance Binary Canonical where
179185 put tipe =
180186 case tipe of
181− Lambda t1 t2 ->
182− putWord8 0 >> put t1 >> put t2
183−
184− Var x ->
185− putWord8 1 >> put x
186−
187− Record fs ext ->
188− putWord8 2 >> put fs >> put ext
189−
190− Aliased var args t ->
191− putWord8 3 >> put var >> put args >> put t
192−
193− Type name ts ->
187+ Lambda t1 t2 -> putWord8 0 >> put t1 >> put t2
188+ Var x -> putWord8 1 >> put x
189+ Record fs ext -> putWord8 2 >> put fs >> put ext
190+ Unit -> putWord8 3
191+ Tuple a b cs -> putWord8 4 >> put a >> put b >> put cs
192+ Aliased var args t -> putWord8 5 >> put var >> put args >> put t
193+ Type name ts ->
194194 let
195195 potentialWord =
196− length ts + 5
196+ length ts + 7
197197 in
198198 if potentialWord <= fromIntegral (maxBound :: Word8) then
199199 do putWord8 (fromIntegral potentialWord)
200200 put name
201201 mapM_ put ts
202202 else
203− putWord8 4 >> put name >> put ts
203+ putWord8 6 >> put name >> put ts
204204
205205 get =
206206 do word <- getWord8
@@ -208,9 +208,11 @@ instance Binary Canonical where
208208 0 -> liftM2 Lambda get get
209209 1 -> liftM Var get
210210 2 -> liftM2 Record get get
211− 3 -> liftM3 Aliased get get get
212− 4 -> liftM2 Type get get
213− n -> liftM2 Type get (replicateM (fromIntegral (n - 5)) get)
211+ 3 -> return Unit
212+ 4 -> liftM3 Tuple get get get
213+ 5 -> liftM3 Aliased get get get
214+ 6 -> liftM2 Type get get
215+ n -> liftM2 Type get (replicateM (fromIntegral (n - 7)) get)
214216
215217
216218instance Binary t => Binary (Aliased t) where