@@ -161,10 +161,9 @@ compileStmt statement cont = case statement of
161
161
label l2
162
162
cont
163
163
SFor _ expr1 expr2 block -> do
164
- compileFor expr1 expr2 " 1 " (compileBlock block) (const cont)
164
+ compileFor expr1 expr2 ( EInt _pos 1 ) (compileBlock block) (const cont)
165
165
SForStep _ expr1 expr2 expr3 block -> do
166
- (_, v) <- compileExpr expr3
167
- compileFor expr1 expr2 v (compileBlock block) (const cont)
166
+ compileFor expr1 expr2 expr3 (compileBlock block) (const cont)
168
167
SBreak _ -> do
169
168
(_, l) <- asks (M. ! (Ident " #break" ))
170
169
goto l
@@ -187,7 +186,7 @@ compileStmt statement cont = case statement of
187
186
let a = eVar (" a" ++ show n)
188
187
let i = eVar (" i" ++ show n)
189
188
compileAssg typ a val $ do
190
- flip (compileFor i (ERangeExcl _pos (eInt 0 ) (EAttr _pos a (Ident " length" ))) " 1 " ) (const skip) $ do
189
+ flip (compileFor i (ERangeExcl _pos (eInt 0 ) (EAttr _pos a (Ident " length" ))) (eInt 1 ) ) (const skip) $ do
191
190
l <- nextLabel
192
191
flip (compileIf (ECmp _pos (Cmp1 _pos i (CmpGT _pos) (eInt 0 )))) l $ do
193
192
call tInt " @putchar" [(tChar, " 44" )] -- ,
@@ -245,12 +244,12 @@ compileIf expr body exit = do
245
244
return $ x
246
245
247
246
-- | Compiles a single `for` statement and continues with changed environment.
248
- compileFor :: Expr Pos -> Expr Pos -> Value -> Run a -> (a -> Run b ) -> Run b
249
- compileFor expr1 expr2 step body cont = do
247
+ compileFor :: Expr Pos -> Expr Pos -> Expr Pos -> Run a -> (a -> Run b ) -> Run b
248
+ compileFor expr1 expr2 expr3 body cont = do
250
249
es <- case expr1 of
251
250
ETuple _ es -> return $ es
252
251
otherwise -> return $ [expr1]
253
- rs <- initFor expr2 step
252
+ rs <- initFor expr2 expr3
254
253
let (ts1, ts2, starts, steps, cmps, gets) = unzip6 rs
255
254
ps <- mapM alloca ts1
256
255
forM (zip3 ts1 starts ps) $ \ (t, v, p) -> store t v p
@@ -278,41 +277,47 @@ compileFor expr1 expr2 step body cont = do
278
277
otherwise -> forM_ (zip3 ts2 es vs2) $ \ (t, e, v) -> compileAssg t e v skip
279
278
x <- localLabel " #break" l2 $ localLabel " #continue" l3 $ body
280
279
goto l3 >> label l3
281
- vs3 <- forM (zip3 ts1 vs1 steps) $ \ (t, v, s) -> binop " add" t v s
280
+ vs3 <- forM (zip3 ts1 vs1 steps) $ \ (t, v, s) -> case t of
281
+ TFloat _ -> binop " fadd" t v s
282
+ otherwise -> binop " add" t v s
282
283
forM (zip3 ts1 vs3 ps) $ \ (t, v, p) -> store t v p
283
284
goto l1
284
285
label l2
285
286
cont x
286
287
where
287
288
initForRangeIncl from to step = do
288
- [(t, v1), (_, v2)] <- mapM compileExpr [from, to]
289
- v3 <- case t of
290
- TInt _ -> return $ step
291
- otherwise -> trunc tInt t step
292
- v4 <- binop " icmp sgt" t v3 " 0"
289
+ [(t1, v1), (_, v2), (t2, v3)] <- mapM compileExpr [from, to, step]
290
+ v4 <- castValue t2 v3 t1
291
+ c <- case t1 of
292
+ TFloat _ -> return $ " fcmp o"
293
+ otherwise -> return $ " icmp s"
294
+ v5 <- case t1 of
295
+ TFloat _ -> binop (c ++ " gt" ) t1 v4 " 0.0"
296
+ otherwise -> binop (c ++ " gt" ) t1 v4 " 0"
293
297
let cmp v = do
294
- v5 <- binop " icmp sle " t v v2
295
- v6 <- binop " icmp sge " t v v2
296
- select v4 tBool v5 v6
297
- return $ (t, t , v1, v3 , cmp, return )
298
+ v6 <- binop (c ++ " le " ) t1 v v2
299
+ v7 <- binop (c ++ " ge " ) t1 v v2
300
+ select v5 tBool v6 v7
301
+ return $ (t1, t1 , v1, v4 , cmp, return )
298
302
initForRangeExcl from to step = do
299
- [(t, v1), (_, v2)] <- mapM compileExpr [from, to]
300
- v3 <- case t of
301
- TInt _ -> return $ step
302
- otherwise -> trunc tInt t step
303
- v4 <- binop " icmp sgt" t v3 " 0"
303
+ [(t1, v1), (_, v2), (t2, v3)] <- mapM compileExpr [from, to, step]
304
+ v4 <- castValue t2 v3 t1
305
+ c <- case t1 of
306
+ TFloat _ -> return $ " fcmp o"
307
+ otherwise -> return $ " icmp s"
308
+ v5 <- case t1 of
309
+ TFloat _ -> binop (c ++ " gt" ) t1 v4 " 0.0"
310
+ otherwise -> binop (c ++ " gt" ) t1 v4 " 0"
304
311
let cmp v = do
305
- v5 <- binop " icmp slt " t v v2
306
- v6 <- binop " icmp sgt " t v v2
307
- select v4 tBool v5 v6
308
- return $ (t, t , v1, v3 , cmp, return )
312
+ v6 <- binop (c ++ " lt " ) t1 v v2
313
+ v7 <- binop (c ++ " gt " ) t1 v v2
314
+ select v5 tBool v6 v7
315
+ return $ (t1, t1 , v1, v4 , cmp, return )
309
316
initForRangeInf from step = do
310
- (t, v1) <- compileExpr from
311
- v2 <- case t of
312
- TInt _ -> return $ step
313
- otherwise -> trunc tInt t step
317
+ [(t1, v1), (t2, v2)] <- mapM compileExpr [from, step]
318
+ v3 <- castValue t2 v2 t1
314
319
let cmp _ = return $ " true"
315
- return $ (t, t , v1, v2 , cmp, return )
320
+ return $ (t1, t1 , v1, v3 , cmp, return )
316
321
initForIterable iter step = do
317
322
(t, v1) <- compileExpr iter
318
323
t' <- case t of
@@ -321,22 +326,27 @@ compileFor expr1 expr2 step body cont = do
321
326
v2 <- gep t v1 [" 0" ] [0 ] >>= load (tPtr t')
322
327
v3 <- gep t v1 [" 0" ] [1 ] >>= load tInt
323
328
v4 <- binop " sub" tInt v3 " 1"
324
- v5 <- binop " icmp sgt" tInt step " 0"
325
- v6 <- select v5 tInt " 0" v4
329
+ (_, v5) <- compileExpr step
330
+ v6 <- binop " icmp sgt" tInt v5 " 0"
331
+ v7 <- select v6 tInt " 0" v4
326
332
let cmp v = do
327
- v7 <- binop " icmp sle" tInt v v4
328
- v8 <- binop " icmp sge" tInt v " 0"
329
- select v5 tBool v7 v8
333
+ v8 <- binop " icmp sle" tInt v v4
334
+ v9 <- binop " icmp sge" tInt v " 0"
335
+ select v6 tBool v8 v9
330
336
let get v = gep (tPtr t') v2 [v] [] >>= load t'
331
- return $ (tInt, t', v6, step , cmp, get)
337
+ return $ (tInt, t', v7, v5 , cmp, get)
332
338
initFor expr step = do
333
339
case expr of
334
340
ERangeIncl _ e1 e2 -> forM [step] $ initForRangeIncl e1 e2
335
341
ERangeExcl _ e1 e2 -> forM [step] $ initForRangeExcl e1 e2
336
342
ERangeInf _ e1 -> forM [step] $ initForRangeInf e1
337
- ETuple _ es -> forM es $ \ e -> do
338
- r <- initFor e step
339
- return $ head r
343
+ ETuple _ es1 -> case step of
344
+ ETuple _ es2 -> forM (zip es1 es2) $ \ (e1, e2) -> do
345
+ r <- initFor e1 e2
346
+ return $ head r
347
+ otherwise -> forM es1 $ \ e -> do
348
+ r <- initFor e step
349
+ return $ head r
340
350
otherwise -> forM [step] $ initForIterable expr
341
351
342
352
-- | Outputs LLVM code for a function definition and initialization of its default arguments.
@@ -526,7 +536,7 @@ compileExpr expression = case expression of
526
536
b <- return $ SBlock _pos [
527
537
SAssg _pos [EIndex _pos (eVar " result" ) (eVar " i" ), EIndex _pos (eVar " source" ) (eVar " j" )],
528
538
SAssgAdd _pos (eVar " j" ) (eVar " c" )]
529
- compileFor (eVar " i" ) (ERangeExcl _pos (eInt 0 ) (eVar " d" )) " 1 " (compileBlock b) (const skip)
539
+ compileFor (eVar " i" ) (ERangeExcl _pos (eInt 0 ) (eVar " d" )) (eInt 1 ) (compileBlock b) (const skip)
530
540
return $ (t, p2)
531
541
EAttr _ _ _ -> compileRval expression
532
542
ECall _ expr args -> do
@@ -803,10 +813,9 @@ compileExpr expression = case expression of
803
813
cpr: cprs -> compileArrayCpr cpr $ compileArrayCprs cprs cont
804
814
compileArrayCpr cpr cont = case cpr of
805
815
CprFor _ e1 e2 -> do
806
- compileFor e1 e2 " 1 " cont return
816
+ compileFor e1 e2 ( EInt _pos 1 ) cont return
807
817
CprForStep _ e1 e2 e3 -> do
808
- (_, v) <- compileExpr e3
809
- compileFor e1 e2 v cont return
818
+ compileFor e1 e2 e3 cont return
810
819
CprIf _ e -> do
811
820
(_, l) <- asks (M. ! (Ident " #continue" ))
812
821
x <- compileIf e cont l
0 commit comments