1
+ {-# LANGUAGE FlexibleContexts #-}
1
2
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2
3
{-# LANGUAGE DeriveFunctor #-}
3
4
{-# LANGUAGE LambdaCase #-}
@@ -64,31 +65,37 @@ distributeFixities e = e
64
65
65
66
-- | A core pass prior to evaluation to cook all soup that can be
66
67
-- cooked.
67
- cookAllSoup :: Anaphora a => CoreExp a -> Interpreter (CoreExp a )
68
+ cookAllSoup ::
69
+ (Anaphora SymbolicAnaphora a ) => CoreExp a -> Interpreter (CoreExp a )
68
70
cookAllSoup = Interpreter . cookBottomUp False
69
71
70
72
-- | Entrypoint for evaluator if soup is discovered at runtime
71
- cook :: Anaphora a => [CoreExp a ] -> Interpreter (CoreExp a )
73
+ cook :: ( Anaphora SymbolicAnaphora a ) => [CoreExp a ] -> Interpreter (CoreExp a )
72
74
cook es = case cookSoup False es of
73
75
Right expr -> return expr
74
76
Left err -> throwEvalError err
75
77
76
78
-- | Take sequence of expression in operator soup and rearrange into
77
79
-- non-soup expression using operator fixity.
78
- cookSoup :: Anaphora a => Bool -> [CoreExp a ] -> Either CoreError (CoreExp a )
80
+ cookSoup ::
81
+ (Anaphora SymbolicAnaphora a )
82
+ => Bool
83
+ -> [CoreExp a ]
84
+ -> Either CoreError (CoreExp a )
79
85
cookSoup parentAnaphoric es = do
80
86
subcooked <- cookSubsoups inAnaphoricLambda filled
81
87
expr <- evalState shunt (initState subcooked inAnaphoricLambda)
82
88
if wrap
83
- then return $ (bindAnaphora . numberAnaphora) expr
89
+ then return $ processAnaphora expr
84
90
else return expr
85
91
where
86
92
(filled, imAnaphoric) = precook es
87
93
wrap = imAnaphoric && not parentAnaphoric
88
94
inAnaphoricLambda = parentAnaphoric || imAnaphoric
95
+ processAnaphora = bindAnaphora expressionAnaphora . numberAnaphora expressionAnaphora
89
96
90
97
cookScope ::
91
- (Anaphora a , Eq b , Show b )
98
+ (Eq b , Show b , Anaphora SymbolicAnaphora a )
92
99
=> Bool
93
100
-> Scope b CoreExp a
94
101
-> Interpreter (Scope b CoreExp a )
@@ -99,18 +106,25 @@ cookScope anaphoric scope =
99
106
--
100
107
-- Go through each filling first so and determine whether there are
101
108
-- anaphora at this level
102
- precook :: Anaphora a => [CoreExp a ] -> ([CoreExp a ], Bool )
109
+ precook :: ( Anaphora SymbolicAnaphora a ) => [CoreExp a ] -> ([CoreExp a ], Bool )
103
110
precook = fillGaps
104
111
105
112
106
113
107
114
-- | Recurse down cooking any operator soups from the bottom upwards
108
- cookSubsoups :: Anaphora a => Bool -> [CoreExp a ] -> Either CoreError [CoreExp a ]
115
+ cookSubsoups ::
116
+ (Anaphora SymbolicAnaphora a )
117
+ => Bool
118
+ -> [CoreExp a ]
119
+ -> Either CoreError [CoreExp a ]
109
120
cookSubsoups anaphoric = mapM (cookBottomUp anaphoric)
110
121
111
122
112
123
cookBottomUp ::
113
- Anaphora a => Bool -> CoreExp a -> Either CoreError (CoreExp a )
124
+ (Anaphora SymbolicAnaphora a )
125
+ => Bool
126
+ -> CoreExp a
127
+ -> Either CoreError (CoreExp a )
114
128
cookBottomUp anaphoric (CoreOpSoup _ exprs) = cookSoup anaphoric exprs
115
129
cookBottomUp anaphoric (CoreArgTuple smid exprs) =
116
130
CoreArgTuple smid <$> traverse (cookBottomUp anaphoric) exprs
@@ -133,7 +147,9 @@ cookBottomUp _ e = Right e
133
147
134
148
135
149
-- | Run the shunting algorithm until finished or errored
136
- shunt :: Anaphora a => State (ShuntState a ) (Either CoreError (CoreExp a ))
150
+ shunt ::
151
+ (Show a , Anaphora SymbolicAnaphora a )
152
+ => State (ShuntState a ) (Either CoreError (CoreExp a ))
137
153
shunt = (shunt1 `untilM_` finished) >> result
138
154
where
139
155
finished = complete <$> get
@@ -157,7 +173,7 @@ data ShuntState a = ShuntState
157
173
, shuntInsideAnaphoricLambda :: Bool
158
174
} deriving (Show )
159
175
160
- initState :: Anaphora a => [CoreExp a ] -> Bool -> ShuntState a
176
+ initState :: [CoreExp a ] -> Bool -> ShuntState a
161
177
initState es anaphoric =
162
178
ShuntState
163
179
{ shuntOutput = []
@@ -298,7 +314,10 @@ pushback e = state $ \s -> ((), s {shuntSource = e : shuntSource s})
298
314
-- | Check the expression can be safely followed by what's coming up
299
315
-- in next in the source and insert catenation operator or implicit
300
316
-- parameter otherwise (giving us haskell style "sections" @(+)@ etc.)
301
- ensureValidSequence :: Anaphora a => Maybe (CoreExp a ) -> State (ShuntState a ) ()
317
+ ensureValidSequence ::
318
+ (Anaphora SymbolicAnaphora a )
319
+ => Maybe (CoreExp a )
320
+ -> State (ShuntState a ) ()
302
321
ensureValidSequence lhs =
303
322
peekSource >>= \ rhs ->
304
323
case validExprSeq lhs rhs of
@@ -307,7 +326,7 @@ ensureValidSequence lhs =
307
326
Nothing -> return ()
308
327
309
328
-- | A step of the shunting yard algorithm
310
- shunt1 :: Anaphora a => State (ShuntState a ) ()
329
+ shunt1 :: ( Anaphora SymbolicAnaphora a ) => State (ShuntState a ) ()
311
330
shunt1 =
312
331
popNext >>= \ case
313
332
Just expr@ CoreOperator {} -> ensureValidSequence (Just expr) >> seatOp expr
@@ -333,32 +352,38 @@ bindSides Nothing = (OpLike, OpLike)
333
352
334
353
-- | Two exprs are valid together if one is OpLike and one is
335
354
-- ValueLike on the sides that touch
336
- validExprSeq :: Anaphora a => Maybe (CoreExp a ) -> Maybe (CoreExp a ) -> Maybe (CoreExp a )
355
+ validExprSeq ::
356
+ (Anaphora SymbolicAnaphora a )
357
+ => Maybe (CoreExp a )
358
+ -> Maybe (CoreExp a )
359
+ -> Maybe (CoreExp a )
337
360
validExprSeq l r = filler ((snd . bindSides) l) ((fst . bindSides) r)
338
361
339
362
-- | We can make an invalid sequence valid by inserting a catenation
340
363
-- op or an anaphoric parameter
341
- filler :: Anaphora a => BindSide -> BindSide -> Maybe (CoreExp a )
364
+ filler :: ( Anaphora SymbolicAnaphora a ) => BindSide -> BindSide -> Maybe (CoreExp a )
342
365
filler ValueLike ValueLike = Just catOp
343
- filler OpLike OpLike = Just $ return unnumberedAnaphor
366
+ filler OpLike OpLike = Just $ return $ unnumberedAnaphor expressionAnaphora
344
367
filler _ _ = Nothing
345
368
346
369
-- | Make a given expression valid by inserting catenation and
347
370
-- anaphora as required and track whether the sequence contains any
348
371
-- anaphora.
349
- fillGaps :: Anaphora a => [CoreExp a ] -> ([CoreExp a ], Bool )
372
+ fillGaps :: ( Anaphora SymbolicAnaphora a ) => [CoreExp a ] -> ([CoreExp a ], Bool )
350
373
fillGaps exprs =
351
374
let (es, anaphoric) = foldl' accum ([] , False ) sides
352
- in (reverse es, anaphoric)
375
+ in (reverse es, anaphoric)
353
376
where
354
377
sides = map Just exprs ++ [Nothing ]
355
- anaphoricMaybe = getAny . foldMap Any . fmap isAnaphoricVar
378
+ anaphoricMaybe =
379
+ getAny . foldMap Any . fmap (isAnaphoricVar expressionAnaphora)
356
380
accum (l, b) e =
357
- let (l', b') = case validExprSeq (headMay l) e of
358
- Just v
359
- | isAnaphoricVar v -> (v : l, True )
360
- | otherwise -> (v : l, b || anaphoricMaybe e)
361
- Nothing -> (l, b || anaphoricMaybe e)
362
- in case e of
363
- Just x -> (x: l', b')
364
- Nothing -> (l', b')
381
+ let (l', b') =
382
+ case validExprSeq (headMay l) e of
383
+ Just v
384
+ | isAnaphoricVar expressionAnaphora v -> (v : l, True )
385
+ | otherwise -> (v : l, b || anaphoricMaybe e)
386
+ Nothing -> (l, b || anaphoricMaybe e)
387
+ in case e of
388
+ Just x -> (x : l', b')
389
+ Nothing -> (l', b')
0 commit comments