Skip to content

Commit d9ba215

Browse files
committed
ES: bugfix in Conversion
Now it correctly transforms node, literal and unit patterns.
1 parent d76c830 commit d9ba215

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

grin/src/Grin/ExtendedSyntax/Grin.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ _Lit :: Traversal' Val Lit
5454
_Lit f (Lit l) = Lit <$> f l
5555
_Lit _ rest = pure rest
5656

57+
-- NOTE: This will return NM "" for everyrhing that is not a Var
5758
_Var :: Traversal' Val Name
5859
_Var f (Var name) = Var <$> f name
5960
_Var _ rest = pure rest

grin/src/Transformations/ExtendedSyntax/Conversion.hs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,26 @@ oldNodeToNewNode tag vals
115115
| any (isn't _Var) vals = error $ "ConstTagNode " ++ show (PP $ ConstTagNode tag vals) ++ " has a non-variable argument."
116116
| otherwise = New.ConstTagNode (convert tag) (map (convert . view _Var) vals)
117117

118-
oldNodeToAsPat :: Tag -> [Val] -> Name -> New.BPat
119-
oldNodeToAsPat tag args name
120-
| New.ConstTagNode newTag newArgs <- oldNodeToNewNode tag args
121-
= New.AsPat newTag newArgs (convert name)
118+
oldNodePatToAsPat :: Tag -> [Val] -> Name -> NameM New.BPat
119+
oldNodePatToAsPat tag args name = do
120+
args' <- forM args $ \case
121+
Var v -> pure $ convert v
122+
{- NOTE: Unit and Lit patterns can be "skipped". If the variable holds
123+
the same value as we are matching against, then it redundant. If it does
124+
not, then the semantics of the program is undefined (so we can do anything with it).
125+
126+
Here we will just generate a variable pattern in place of literal and unit patterns.
127+
-}
128+
_ -> convert <$> deriveWildCard
129+
let tag' = convert tag
130+
name' = convert name
131+
pure $ New.AsPat tag' args' name'
122132

123133
instance Convertible Val New.Val where
124-
convert (ConstTagNode t vals) = oldNodeToNewNode t vals
134+
-- NOTE: This should only be called for node values, but not for node patterns in LPats
135+
convert (ConstTagNode tag vals)
136+
| any (isn't _Var) vals = error $ "ConstTagNode " ++ show (PP $ ConstTagNode tag vals) ++ " has a non-variable argument."
137+
| otherwise = New.ConstTagNode (convert tag) (map (convert . view _Var) vals)
125138
convert v@(VarTagNode _ _) = error $ "Cannot transform VarTagNode to new syntax: " ++ show (PP v)
126139
convert v@(ValTag _) = error $ "Cannot transform ValTag to new syntax: " ++ show (PP v)
127140
convert Unit = New.Unit
@@ -149,7 +162,9 @@ instance Convertible Exp New.Exp where
149162
(EBind lhs1 (Var var) rhs1)
150163
| EBind (SReturn (Var var')) (ConstTagNode tag args) rhs2 <- rhs1
151164
, var == var'
152-
-> pure $ New.EBindF lhs1 (oldNodeToAsPat tag args var) rhs2
165+
-> do
166+
newNodePat <- oldNodePatToAsPat tag args var
167+
pure $ New.EBindF lhs1 newNodePat rhs2
153168
{- NOTE: The following transformation can be done, because
154169
unit and literal patterns are redundant. If the variable has
155170
the same value as the pattern, then we can safely remove the
@@ -179,14 +194,21 @@ instance Convertible Exp New.Exp where
179194
180195
v.0 <- pure <value>
181196
<...>
182-
<node pat> @ a.0 <- pure v.0
197+
<node pat> @ a.0 <- pure v.0 -- a.0 is a fresh variable
183198
<rhs>
184199
-}
185200
(EBind lhs (ConstTagNode tag args) rhs) -> do
186-
asPatName <- deriveNewName "a"
187-
pure $ New.EBindF lhs (oldNodeToAsPat tag args asPatName) rhs
201+
asPatName <- deriveNewName "a"
202+
newNodePat <- oldNodePatToAsPat tag args asPatName
203+
pure $ New.EBindF lhs newNodePat rhs
188204
(EBind lhs (Var var) rhs)
189205
-> pure $ New.EBindF lhs (New.VarPat $ convert var) rhs
206+
(EBind lhs pat@Lit{} rhs) -> do
207+
patName <- deriveNewName "a"
208+
pure $ New.EBindF lhs (New.VarPat $ convert patName) rhs
209+
(EBind lhs pat@Unit rhs) -> do
210+
patName <- deriveWildCard
211+
pure $ New.EBindF lhs (New.VarPat $ convert patName) rhs
190212
(ECase scrut alts)
191213
| isn't _Var scrut -> error $ "Non-variable pattern in case scrutinee: " ++ show (PP scrut)
192214
| (Var var) <- scrut -> pure $ New.ECaseF (convert var) alts
@@ -207,6 +229,7 @@ instance Convertible Exp New.Exp where
207229
(Alt cpat exp) -> do
208230
altName <- deriveNewName "alt"
209231
pure $ New.AltF (convert cpat) (convert altName) exp
232+
e -> error $ "Cannot convert to new: " ++ show (PP e)
210233

211234
instance Convertible New.TagType TagType where
212235
convert = \case

grin/src/Transformations/Names.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ deriveNewName name = do
4343
then deriveNewName name
4444
else pure newName
4545

46+
deriveWildCard :: NameM Name
47+
deriveWildCard = do
48+
(newWildCard, conflict) <- state $ \env@NameEnv{..} ->
49+
let wildcard = "_"
50+
idx = Map.findWithDefault 0 wildcard namePool
51+
new = packName $ printf "%s%d" wildcard idx
52+
in ( (new, Set.member new nameSet)
53+
, env {namePool = Map.insert wildcard (succ idx) namePool, nameSet = Set.insert new nameSet}
54+
)
55+
if conflict
56+
then deriveWildCard
57+
else pure newWildCard
58+
4659
boolTF :: a -> a -> Bool -> a
4760
boolTF true false x = if x then true else false
4861

0 commit comments

Comments
 (0)