1
- module IdrisJvm.Codegen .ControlFlow
1
+ module IdrisJvm.Core .ControlFlow
2
2
3
3
import IdrisJvm.Core.Asm
4
4
import IdrisJvm.Core.Common
@@ -43,17 +43,36 @@ mutual
43
43
44
44
cgIf : Lazy (Asm () ) -> (Lazy (Asm () ) -> SExp -> Asm () ) -> LVar -> List SAlt -> Asm ()
45
45
cgIf ret cgBody e alts = do
46
- ifIndex <- FreshIfIndex
47
- let ifExpr = ifCasesWithLbls ifIndex alts
48
- let fallbackLabels = drop 1 ((\ (lbl, _ , _ ) => lbl) <$> ifExpr) ++ [ifEndLabel ifIndex]
49
- sequence_ $ CreateLabel . (\ (lbl, _ , _ ) => lbl) <$> ifExpr
50
- CreateLabel $ ifEndLabel ifIndex
51
- sequence_ $ (uncurry $ cgIfCase ifIndex ret cgBody e) <$> zip fallbackLabels ifExpr
52
- LabelStart (ifEndLabel ifIndex)
53
- Frame FSame 0 [] 0 []
54
-
55
- cgIfCase : Nat -> Lazy (Asm () ) -> (Lazy (Asm () ) -> SExp -> Asm () ) -> LVar -> String -> (String, Maybe (Asm () ), SAlt) -> Asm ()
56
- cgIfCase ifIndex ret cgBody e nextLabel (label, Just ifExpr, SConstCase _ expr) = do
46
+ ifIndex <- FreshIfIndex
47
+ let ifExpr = ifCasesWithLbls ifIndex alts
48
+ let fallbackLabels = drop 1 ((\ (lbl, _ , _ ) => lbl) <$> ifExpr) ++ [ifEndLabel ifIndex]
49
+ sequence_ $ CreateLabel . (\ (lbl, _ , _ ) => lbl) <$> ifExpr
50
+ CreateLabel $ ifEndLabel ifIndex
51
+ sequence_ $ gen ifIndex ret cgBody e <$> zip fallbackLabels ifExpr
52
+ LabelStart (ifEndLabel ifIndex)
53
+ Frame FSame 0 [] 0 []
54
+ where
55
+ gen : Nat
56
+ -> Lazy (Asm () )
57
+ -> (Lazy (Asm () ) -> SExp -> Asm () )
58
+ -> LVar
59
+ -> (String , String , Maybe (Asm () ), SAlt )
60
+ -> Asm ()
61
+ gen ifIndex ret cgBody e (nextLabel, label, ifExpr, expr)
62
+ = maybe (cgElseCase ifIndex ret cgBody e nextLabel label expr)
63
+ (\ condition => cgIfElseIfCase ifIndex ret cgBody e nextLabel label condition expr)
64
+ ifExpr
65
+
66
+ cgIfElseIfCase : Nat
67
+ -> Lazy (Asm () )
68
+ -> (Lazy (Asm () ) -> SExp -> Asm () )
69
+ -> LVar
70
+ -> String
71
+ -> String
72
+ -> Asm ()
73
+ -> SAlt
74
+ -> Asm ()
75
+ cgIfElseIfCase ifIndex ret cgBody e nextLabel label ifExpr (SConstCase _ expr) = do
57
76
LabelStart label
58
77
addFrame
59
78
Aload $ locIndex e
@@ -63,12 +82,18 @@ mutual
63
82
cgBody ret expr
64
83
Goto $ ifEndLabel ifIndex
65
84
66
- cgIfCase ifIndex ret cgBody _ _ (label, Nothing , SDefaultCase expr) = do
85
+ cgElseCase : Nat
86
+ -> Lazy (Asm () )
87
+ -> (Lazy (Asm () ) -> SExp -> Asm () )
88
+ -> LVar
89
+ -> String
90
+ -> String
91
+ -> SAlt
92
+ -> Asm ()
93
+ cgElseCase ifIndex ret cgBody _ _ label (SDefaultCase expr) = do
67
94
cgCase ret cgBody label expr
68
95
Goto $ ifEndLabel ifIndex
69
96
70
- cgIfCase _ _ _ _ _ _ = invokeError " Unexpected if expression"
71
-
72
97
cgCase : Lazy (Asm () ) -> (Lazy (Asm () ) -> SExp -> Asm () ) -> Label -> SExp -> Asm ()
73
98
cgCase ret cgBody label expr = do
74
99
LabelStart label
@@ -216,3 +241,42 @@ mutual
216
241
constCaseExpr VoidType = jerror " Constant VoidType cannot be compiled to 'if' yet"
217
242
constCaseExpr Forgot = jerror " Constant Forgot cannot be compiled to 'if' yet"
218
243
ifCaseExpr _ = Nothing
244
+
245
+ cgIfElse : Lazy (Asm () )
246
+ -> (Lazy (Asm () ) -> SExp -> Asm () )
247
+ -> LVar
248
+ -> (Label -> Asm () )
249
+ -> Maybe Int
250
+ -> SExp
251
+ -> SExp
252
+ -> Asm ()
253
+ cgIfElse ret cgBody e condition valueStore case1 case2 = do
254
+ ifIndex <- FreshIfIndex
255
+ let ifLabel = ifLabelName ifIndex 0
256
+ let elseLabel = ifLabelName ifIndex 1
257
+ let endLabel = ifEndLabel ifIndex
258
+ CreateLabel ifLabel
259
+ CreateLabel elseLabel
260
+ CreateLabel endLabel
261
+ Aload $ locIndex e
262
+ condition elseLabel
263
+ LabelStart ifLabel
264
+ maybe (pure () ) store valueStore
265
+ cgBody ret case1
266
+ Goto endLabel
267
+ LabelStart elseLabel
268
+ addFrame
269
+ cgBody ret case2
270
+ LabelStart endLabel
271
+ Frame FSame 0 [] 0 []
272
+ where
273
+ store : Int -> Asm ()
274
+ store loc = do
275
+ Aload $ locIndex e
276
+ Astore loc
277
+
278
+ cgIfNonNull : Lazy (Asm () ) -> (Lazy (Asm () ) -> SExp -> Asm () ) -> LVar -> Int -> SExp -> SExp -> Asm ()
279
+ cgIfNonNull ret cgBody e loc ifExp elseExp = cgIfElse ret cgBody e Ifnull (Just loc) ifExp elseExp
280
+
281
+ cgIfNull : Lazy (Asm () ) -> (Lazy (Asm () ) -> SExp -> Asm () ) -> LVar -> SExp -> SExp -> Asm ()
282
+ cgIfNull ret cgBody e ifExp elseExp = cgIfElse ret cgBody e Ifnonnull Nothing ifExp elseExp
0 commit comments