This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches -Wno-missing-signatures #-}
|
{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches -Wno-missing-signatures #-}
|
||||||
{- HLINT ignore "Avoid lambda using `infix`" -}
|
{- HLINT ignore "Avoid lambda using `infix`" -}
|
||||||
module Gyehoek.ANF
|
module Gyehoek.ANF
|
||||||
(toANF)
|
(toANF, lower)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
@@ -28,6 +28,8 @@ import Data.Foldable
|
|||||||
import Data.List.NonEmpty (NonEmpty((:|)), toList)
|
import Data.List.NonEmpty (NonEmpty((:|)), toList)
|
||||||
import Gyehoek.QBE (FuncDef(FuncDef))
|
import Gyehoek.QBE (FuncDef(FuncDef))
|
||||||
import Data.Foldable1
|
import Data.Foldable1
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Data.String (fromString)
|
||||||
|
|
||||||
|
|
||||||
-- data Val
|
-- data Val
|
||||||
@@ -107,6 +109,7 @@ instance Semigroup QBE.Program where
|
|||||||
QBE.Program (ts <> ts') (ds <> ds') (fs <> fs')
|
QBE.Program (ts <> ts') (ds <> ds') (fs <> fs')
|
||||||
|
|
||||||
instance Monoid QBE.Program where
|
instance Monoid QBE.Program where
|
||||||
|
mempty :: QBE.Program
|
||||||
mempty = QBE.Program mempty mempty mempty
|
mempty = QBE.Program mempty mempty mempty
|
||||||
|
|
||||||
funcdef :: QBE.Ident QBE.Global -> [QBE.Param] -> NonEmpty QBE.Block -> FuncDef
|
funcdef :: QBE.Ident QBE.Global -> [QBE.Param] -> NonEmpty QBE.Block -> FuncDef
|
||||||
@@ -148,6 +151,16 @@ buildBlock :: QBE.Ident QBE.Label -> BlockBuilder -> QBE.Block
|
|||||||
buildBlock n bb = QBE.Block n [] (is ^.. each) j
|
buildBlock n bb = QBE.Block n [] (is ^.. each) j
|
||||||
where (is,j) = evalBlockBuilder bb
|
where (is,j) = evalBlockBuilder bb
|
||||||
|
|
||||||
|
lowerName :: Name -> QBE.Ident t
|
||||||
|
lowerName = fromString . T.unpack
|
||||||
|
|
||||||
|
lowerPrim :: Prim -> _ -> _
|
||||||
|
lowerPrim PrimAdd k = k $ QBE.ValGlobal "plus"
|
||||||
|
lowerPrim PrimMul k = k $ QBE.ValGlobal "star"
|
||||||
|
lowerPrim PrimSub k = k $ QBE.ValGlobal "_"
|
||||||
|
lowerPrim PrimDiv k = k $ QBE.ValGlobal "slash"
|
||||||
|
lowerPrim p k = _
|
||||||
|
|
||||||
lowerVal
|
lowerVal
|
||||||
:: forall es. (GenSym :> es)
|
:: forall es. (GenSym :> es)
|
||||||
=> Val
|
=> Val
|
||||||
@@ -155,6 +168,8 @@ lowerVal
|
|||||||
-> Eff es BlockBuilder
|
-> Eff es BlockBuilder
|
||||||
|
|
||||||
lowerVal (ValInt n) k = k . QBE.ValConst . QBE.CInt . fromIntegral $ n
|
lowerVal (ValInt n) k = k . QBE.ValConst . QBE.CInt . fromIntegral $ n
|
||||||
|
lowerVal (ValVar x) k = k . QBE.ValTemporary . lowerName $ x
|
||||||
|
lowerVal (ValPrim p) k = lowerPrim p k
|
||||||
lowerVal _ k = _
|
lowerVal _ k = _
|
||||||
|
|
||||||
lower'
|
lower'
|
||||||
@@ -167,9 +182,8 @@ lower' (ExpVal v) k = lowerVal v k
|
|||||||
|
|
||||||
lower' (ExpLetApply r f xs e) k =
|
lower' (ExpLetApply r f xs e) k =
|
||||||
blah (lowerVal @es <$> (f:|xs)) \(f':xs') -> do
|
blah (lowerVal @es <$> (f:|xs)) \(f':xs') -> do
|
||||||
r <- gensym
|
|
||||||
Emit [ QBE.Call
|
Emit [ QBE.Call
|
||||||
(Just (r, QBE.AbiBaseTy QBE.Long))
|
(Just (lowerName r, QBE.AbiBaseTy QBE.Long))
|
||||||
f'
|
f'
|
||||||
Nothing
|
Nothing
|
||||||
(QBE.Arg (QBE.AbiBaseTy QBE.Long) <$> xs')
|
(QBE.Arg (QBE.AbiBaseTy QBE.Long) <$> xs')
|
||||||
@@ -179,6 +193,11 @@ lower' (ExpLetApply r f xs e) k =
|
|||||||
|
|
||||||
lower' _ k = _
|
lower' _ k = _
|
||||||
|
|
||||||
-- lower e = do
|
lower :: GenSym :> es => QBE.Ident QBE.Label -> Exp -> Eff es QBE.Block
|
||||||
-- _ <- runCodeGen (lower' e \r -> _)
|
lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just)
|
||||||
-- _
|
|
||||||
|
wrapProgram :: Foldable1 t => t QBE.Block -> QBE.Program
|
||||||
|
wrapProgram bs = QBE.Program [] [] [main] where
|
||||||
|
main = QBE.FuncDef [QBE.Export]
|
||||||
|
(Just (QBE.AbiBaseTy QBE.Word))
|
||||||
|
"main" Nothing [] QBE.NoVariadic (toNonEmpty bs)
|
||||||
|
|||||||
15
closure.scm
Normal file
15
closure.scm
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
(define (adder x)
|
||||||
|
(lambda (y)
|
||||||
|
(+ x y)))
|
||||||
|
|
||||||
|
((adder 3) 4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(define (adder x)
|
||||||
|
(list (lambda (self y)
|
||||||
|
(+ (nth self 1) y))
|
||||||
|
x))
|
||||||
|
|
||||||
|
(let ((closure (adder 3)))
|
||||||
|
((nth closure 0) closure 4))
|
||||||
70
t.s
Normal file
70
t.s
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.text
|
||||||
|
zerop:
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
cmpl $0, %edi
|
||||||
|
jnz .Lbb2
|
||||||
|
movl $1, %eax
|
||||||
|
jmp .Lbb3
|
||||||
|
.Lbb2:
|
||||||
|
movl $0, %eax
|
||||||
|
.Lbb3:
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.type zerop, @function
|
||||||
|
.size zerop, .-zerop
|
||||||
|
/* end function zerop */
|
||||||
|
|
||||||
|
.text
|
||||||
|
factorial:
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
subq $8, %rsp
|
||||||
|
pushq %rbx
|
||||||
|
movq %rdi, %rbx
|
||||||
|
callq zerop
|
||||||
|
movq %rbx, %rdi
|
||||||
|
cmpl $0, %eax
|
||||||
|
jnz .Lbb6
|
||||||
|
movq %rdi, %rbx
|
||||||
|
subq $1, %rdi
|
||||||
|
callq factorial
|
||||||
|
movq %rbx, %rdi
|
||||||
|
imulq %rdi, %rax
|
||||||
|
jmp .Lbb7
|
||||||
|
.Lbb6:
|
||||||
|
movl $1, %eax
|
||||||
|
.Lbb7:
|
||||||
|
popq %rbx
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.type factorial, @function
|
||||||
|
.size factorial, .-factorial
|
||||||
|
/* end function factorial */
|
||||||
|
|
||||||
|
.data
|
||||||
|
.balign 8
|
||||||
|
fstr:
|
||||||
|
.ascii "fac 3 = %d\n"
|
||||||
|
.byte 0
|
||||||
|
/* end data */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
main:
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
movl $3, %edi
|
||||||
|
callq factorial
|
||||||
|
movq %rax, %rsi
|
||||||
|
leaq fstr(%rip), %rdi
|
||||||
|
movl $0, %eax
|
||||||
|
callq printf
|
||||||
|
movl $0, %eax
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.type main, @function
|
||||||
|
.size main, .-main
|
||||||
|
/* end function main */
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
16
t.scm
Normal file
16
t.scm
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
(define (factorial n)
|
||||||
|
(if (zero? n)
|
||||||
|
1
|
||||||
|
(* n (factorial (- n 1)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; ANF
|
||||||
|
|
||||||
|
(define (factorial n)
|
||||||
|
(let ((r₁ (zero? n)))
|
||||||
|
(if r₁
|
||||||
|
1
|
||||||
|
(let ((r₂ (- n 1))
|
||||||
|
(r₃ (factorial r₂))
|
||||||
|
(r₄ (* n r₃)))
|
||||||
|
r₄))))
|
||||||
30
t.ssa
Normal file
30
t.ssa
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
function l $zerop (l %n) {
|
||||||
|
@start
|
||||||
|
jnz %n, @b1, @b2
|
||||||
|
@b1
|
||||||
|
ret 0
|
||||||
|
@b2
|
||||||
|
ret 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function l $factorial (l %n) {
|
||||||
|
@start
|
||||||
|
%r1 =l call $zerop (l %n)
|
||||||
|
jnz %r1, @b1, @b2
|
||||||
|
@b1
|
||||||
|
ret 1
|
||||||
|
@b2
|
||||||
|
%r2 =l sub %n, 1
|
||||||
|
%r3 =l call $factorial (l %r2)
|
||||||
|
%r4 =l mul %n, %r3
|
||||||
|
ret %r4
|
||||||
|
}
|
||||||
|
|
||||||
|
data $fstr = { b "fac 3 = %d\n", b 0 }
|
||||||
|
|
||||||
|
export function w $main () {
|
||||||
|
@start
|
||||||
|
%r =l call $factorial (l 3)
|
||||||
|
call $printf (l $fstr, ..., l %r)
|
||||||
|
ret 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user