appy
build / build (push) Successful in 1m11s

This commit is contained in:
2026-07-20 05:33:23 -06:00
parent 2f471ae4b1
commit 7ab98341b9
6 changed files with 308 additions and 35 deletions
+3 -1
View File
@@ -2,4 +2,6 @@
. ((eval . ((eval
. (progn (defun apply-cabal-fmt-h () . (progn (defun apply-cabal-fmt-h ()
(haskell-mode-buffer-apply-command "cabal-fmt")) (haskell-mode-buffer-apply-command "cabal-fmt"))
(add-hook 'before-save-hook #'apply-cabal-fmt-h nil t)))))) (add-hook 'before-save-hook #'apply-cabal-fmt-h nil t)
(add-to-list 'haskell-font-lock-quasi-quote-modes
'("cps" . scheme-mode)))))))
+2
View File
@@ -0,0 +1,2 @@
ret > ExitSuccess
out > 25
+2 -3
View File
@@ -54,11 +54,10 @@ convert (Scm.ExpLambda xs e) k = do
convert (Scm.ExpApply f xs) k = convert (Scm.ExpApply f xs) k =
telescope (convert @es) (f:|xs) \(f':|xs') -> do telescope (convert @es) (f:|xs) \(f':|xs') -> do
-- r <- gensym' "r" r <- gensym' "r"
x <- gensym' "x" x <- gensym' "x"
m <- k (ValVar x) m <- k (ValVar x)
-- pure $ ExpFix [(r, MkKappa [x] m)] $ ExpApply f' (xs' ++ [ValVar r]) pure $ ExpLetRec [(r, AbsKappa' [x] m)] $ ExpApply f' xs' r
_
convert (Scm.ExpBegin xs) k = _ convert (Scm.ExpBegin xs) k = _
+80 -9
View File
@@ -25,6 +25,8 @@ import Language.Sexp.Located qualified as SL
import Control.Monad.Fix import Control.Monad.Fix
import qualified Gyehoek.Sexp import qualified Gyehoek.Sexp
import Data.Text qualified as T import Data.Text qualified as T
import Data.Foldable (fold)
import Gyehoek.Sexp (encodeOrShow, toSexp)
data Env = MkEnv data Env = MkEnv
@@ -41,6 +43,9 @@ instance Ixed Env where
tonat :: Integral a => a -> Natural
tonat = fromIntegral
-- | @makeSmallFixnum@ emits an expression injecting the i32 on top -- | @makeSmallFixnum@ emits an expression injecting the i32 on top
-- of the stack into the SCM unitype. -- of the stack into the SCM unitype.
makeSmallFixnum :: Wasm.Expr makeSmallFixnum :: Wasm.Expr
@@ -56,7 +61,7 @@ makeSmallFixnum = [expr|
pushArg :: Natural -> Wasm.Expr -> Wasm.Expr pushArg :: Natural -> Wasm.Expr -> Wasm.Expr
pushArg n e = [expr| pushArg n e = [expr|
(global.get $arg-array) (global.get $arg-array)
(global.get #{n}) (i32.const #{n})
##{e} ##{e}
(array.set $arg-array-type) (array.set $arg-array-type)
|] |]
@@ -124,6 +129,22 @@ lower' g (ExpIf c t f) = do
(else ##{f'})) (else ##{f'}))
|] |]
lower' g (ExpLetRec [(r,AbsKappa kap)] e) = do
idx <- lowerKappa g kap
let g' = g & #kvars <>~ [r]
e' <- lower' g' e
pure [expr|
(@gyehoek "push cont" :idx #{idx})
(array.set $cont-stack-type
(global.get $cont-stack)
(global.get $cont-stack-top)
(ref.func 4))
(global.set $cont-stack-top
(i32.add (global.get $cont-stack-top)
(i32.const 1)))
##{e'}
|]
lower' g (ExpLetRec [(r,AbsLambda lam)] e) = do lower' g (ExpLetRec [(r,AbsLambda lam)] e) = do
idx <- lowerLambda g lam idx <- lowerLambda g lam
let g' = g & #vars <>~ [r] let g' = g & #vars <>~ [r]
@@ -137,19 +158,45 @@ lower' g (ExpLetRec [(r,AbsLambda lam)] e) = do
##{e'} ##{e'}
|] |]
lower' g (ExpContinue k [x]) = do lower' g (ExpApply f xs ktail) = do
arg <- pushArg 0 <$> lowerVal g x let nargs = length xs
f' <- lowerVal g f
let l = succ $ V.elemIndex ktail g.kvars ^?! _Just
args <- fold <$>
itraverse (\i -> fmap (pushArg $ tonat i) . lowerVal g) xs
pure [expr| pure [expr|
##{arg} (@gyehoek "load args")
##{args}
(i32.const 1) (i32.const 1)
(global.get $cont-stack) ##{f'}
(global.get $cont-stack-top) (ref.cast (ref $closure))
(array.get $cont-stack-type) (struct.get $closure $code)
ref.as_non_null (return_call_ref $cont-type)
;; (@gyehoek todo
;; (f' ##{f'})
;; (ktail #{l}))
|]
lower' g e@(ExpContinue k xs) = do
let nargs = length xs
args <- fold <$>
itraverse (\i -> fmap (pushArg $ tonat i) . lowerVal g) xs
let origin = encodeOrShow @_ @Text e
pure [expr|
(@gyehoek :origin #{origin})
(@gyehoek "push args")
##{args}
(@gyehoek "nargs")
(i32.const #{nargs})
(@gyehoek "pop cont stack")
(global.get $cont-stack-top) (global.get $cont-stack-top)
(i32.const #{l}) (i32.const #{l})
i32.sub i32.sub
(global.set $cont-stack-top) (global.set $cont-stack-top)
(global.get $cont-stack)
(global.get $cont-stack-top)
(array.get $cont-stack-type)
ref.as_non_null
(return_call_ref $cont-type) (return_call_ref $cont-type)
|] |]
where where
@@ -159,8 +206,28 @@ lower' g e = error $ case Gyehoek.Sexp.encode e of
Left _ -> show e Left _ -> show e
Right x -> T.unpack x Right x -> T.unpack x
lowerKappa :: GenMod :> es => Env -> Kappa -> Eff es Idx
lowerKappa g e@(MkKappa xs m) = do
let g' = g & #vars .~ V.fromList xs
m' <- lower' g' m
let body = mconcat
[ xs & ifoldMap \n _ ->
let n' = succ n
in popArg n <> [expr|(local.set #{n'})|]
, m'
]
let origin = encodeOrShow @_ @Text e
idx <- Wasm.defineFunction [wat|
(func (param i32)
(@gyehoek :origin #{origin})
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
##{body})
|]
Wasm.emit [wats|(elem declare funcref (ref.func #{idx}))|]
pure idx
lowerLambda :: GenMod :> es => Env -> Lambda -> Eff es Idx lowerLambda :: GenMod :> es => Env -> Lambda -> Eff es Idx
lowerLambda g (MkLambda xs ktail m) = do lowerLambda g e@(MkLambda xs ktail m) = do
let g' = g & #vars .~ V.fromList xs let g' = g & #vars .~ V.fromList xs
& #kvars <>~ [ktail] & #kvars <>~ [ktail]
m' <- lower' g' m m' <- lower' g' m
@@ -170,8 +237,10 @@ lowerLambda g (MkLambda xs ktail m) = do
in popArg n <> [expr|(local.set #{n'})|] in popArg n <> [expr|(local.set #{n'})|]
, m' , m'
] ]
let origin = encodeOrShow @_ @Text e
idx <- Wasm.defineFunction [wat| idx <- Wasm.defineFunction [wat|
(func (param i32) (func (param i32)
(@gyehoek :origin #{origin})
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq)) (local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
##{body}) ##{body})
|] |]
@@ -253,8 +322,10 @@ lower e = fmap Wasm.renderModule . Wasm.execGenMod $ do
runtime <- emitRuntime runtime <- emitRuntime
let g = MkEnv mempty mempty let g = MkEnv mempty mempty
e' <- lower' g e e' <- lower' g e
let origin = encodeOrShow @_ @Text e
Wasm.defineFunction [wat| Wasm.defineFunction [wat|
(func $scm-entry (param i32) (func $scm-entry (param i32)
(@gyehoek :origin #{origin})
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq)) (local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
##{e'}) ##{e'})
|] |]
+86 -14
View File
@@ -37,33 +37,105 @@
ref.as_non_null ref.as_non_null
(global.set $result)) (global.set $result))
(func (func
$scm-entry
(param i32) (param i32)
(@gyehoek
:origin
(lambda
(x lambda-tail1)
(prim (* x x) (kappa (r2) (continue lambda-tail1 r2)))))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq)) (local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(i32.const 123)
(i32.const 1)
i32.shl
ref.i31
(call $gh-truthy?)
(if
(then
(global.get $arg-array) (global.get $arg-array)
(global.get 0) (i32.const 0)
(i32.const 777) (array.get $arg-array-type)
ref.as_non_null
(local.set 1)
(local.get 1)
(i31.get_s (ref.cast (ref i31)))
(i32.const 1)
i32.shr_u
(local.get 1)
(i31.get_s (ref.cast (ref i31)))
(i32.const 1)
i32.shr_u
i32.mul
(i32.const 1) (i32.const 1)
i32.shl i32.shl
ref.i31 ref.i31
(local.set 2)
(@gyehoek :origin (continue lambda-tail1 r2))
(@gyehoek "push args")
(global.get $arg-array)
(i32.const 0)
(local.get 2)
(array.set $arg-array-type)
(@gyehoek "nargs")
(i32.const 1)
(@gyehoek "pop cont stack")
(global.get $cont-stack-top)
(i32.const 1)
i32.sub
(global.set $cont-stack-top)
(global.get $cont-stack)
(global.get $cont-stack-top)
(array.get $cont-stack-type)
ref.as_non_null
(return_call_ref $cont-type))
(elem declare funcref (ref.func 3))
(func
(param i32)
(@gyehoek :origin (kappa (x4) (continue halt x4)))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(global.get $arg-array)
(i32.const 0)
(array.get $arg-array-type)
ref.as_non_null
(local.set 1)
(global.get $arg-array)
(i32.const 0)
(local.get 1)
(array.set $arg-array-type) (array.set $arg-array-type)
(return_call $halt (i32.const 1))) (return_call $halt (i32.const 1)))
(else (elem declare funcref (ref.func 4))
(func
$scm-entry
(param i32)
(@gyehoek
:origin
(letrec
((lambda-body0
(lambda
(x lambda-tail1)
(prim (* x x) (kappa (r2) (continue lambda-tail1 r2))))))
(letrec
((r3 (kappa (x4) (continue halt x4))))
(lambda-body0 5 r3))))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(i32.const 0)
(ref.func 3)
(struct.new $closure)
(local.set 1)
(@gyehoek "push cont" :idx 4)
(array.set
$cont-stack-type
(global.get $cont-stack)
(global.get $cont-stack-top)
(ref.func 4))
(global.set
$cont-stack-top
(i32.add (global.get $cont-stack-top) (i32.const 1)))
(@gyehoek "load args")
(global.get $arg-array) (global.get $arg-array)
(global.get 0) (i32.const 0)
(i32.const 555) (i32.const 5)
(i32.const 1) (i32.const 1)
i32.shl i32.shl
ref.i31 ref.i31
(array.set $arg-array-type) (array.set $arg-array-type)
(return_call $halt (i32.const 1))))) (i32.const 1)
(local.get 1)
(ref.cast (ref $closure))
(struct.get $closure $code)
(return_call_ref $cont-type))
(func (func
(export "main") (export "main")
(call $scm-entry (i32.const 0)) (call $scm-entry (i32.const 0))
+127
View File
@@ -0,0 +1,127 @@
(module
(import "gyehoek" "write" (func $gh-write (param (ref eq))))
(import "gyehoek" "truthy?" (func $gh-truthy? (param (ref eq)) (result i32)))
(type $heap-object (sub (struct (field $hash (mut i32)))))
(type $cont-type (func (param i32)))
(type $cont-stack-type (array (mut (ref null $cont-type))))
(type
$closure
(sub
$heap-object
(struct
(field $hash (mut i32))
(field $code (ref $cont-type)))))
(global $cont-stack-top (mut i32) (i32.const 0))
(global
$cont-stack
(ref $cont-stack-type)
(array.new_default $cont-stack-type (i32.const 128)))
(type $arg-array-type (array (mut (ref null eq))))
(global
$arg-array
(ref $arg-array-type)
(array.new_default $arg-array-type (i32.const 32)))
(global $result (mut (ref null eq)) (ref.null eq))
(func
$halt
(param i32)
(global.get $arg-array)
(i32.const 0)
(array.get $arg-array-type)
ref.as_non_null
(global.set $result))
(func
(param i32)
(@gyehoek
:origin
(lambda (x lambda-tail1)
(prim (* x x) (kappa (r2) (continue lambda-tail1 r2)))))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(global.get $arg-array)
(i32.const 0)
(array.get $arg-array-type)
ref.as_non_null
(local.set 1)
(local.get 1)
(i31.get_s (ref.cast (ref i31)))
(i32.const 1)
i32.shr_u
(local.get 1)
(i31.get_s (ref.cast (ref i31)))
(i32.const 1)
i32.shr_u
i32.mul
(i32.const 1)
i32.shl
ref.i31
(local.set 2)
(global.get $arg-array)
(i32.const 0)
(local.get 2)
(array.set $arg-array-type)
(i32.const 1)
(global.get $cont-stack)
(global.get $cont-stack-top)
(array.get $cont-stack-type)
ref.as_non_null
(global.get $cont-stack-top)
(i32.const 1)
i32.sub
(global.set $cont-stack-top)
(return_call_ref $cont-type))
(elem declare funcref (ref.func 3))
(func
(param i32)
(@gyehoek :origin (kappa (x4) (continue halt x4)))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(global.get $arg-array)
(i32.const 0)
(array.get $arg-array-type)
ref.as_non_null
(local.set 1)
(global.get $arg-array)
(i32.const 0)
(local.get 1)
(array.set $arg-array-type)
(return_call $halt (i32.const 1)))
(func
$scm-entry
(param i32)
(@gyehoek
:origin
(letrec ((lambda-body0
(lambda (x lambda-tail1)
(prim (* x x) (kappa (r2) (continue lambda-tail1 r2))))))
(letrec ((r3 (kappa (x4) (continue halt x4))))
(lambda-body0 5 r3))))
(local (ref eq) (ref eq) (ref eq) (ref eq) (ref eq))
(i32.const 0)
(ref.func 3)
(struct.new $closure)
(local.set 1)
(@gyehoek "push return cont" :idx 4)
(array.set $cont-stack-type
(global.get $cont-stack)
(global.get $cont-stack-top)
(ref.func 4))
(global.set $cont-stack-top
(i32.add (global.get $cont-stack-top)
(i32.const 1)))
(@gyehoek "load args")
(global.get $arg-array)
(i32.const 0)
(i32.const 5)
(i32.const 1)
i32.shl
ref.i31
(array.set $arg-array-type)
(@gyehoek todo (f' (local.get 1)) (ktail 1))
(return_call_ref $cont-type
(i32.const 1)
(struct.get $closure $code
(ref.cast (ref $closure) (local.get 1)))))
(elem declare funcref (ref.func 4))
(func
(export "main")
(call $scm-entry (i32.const 0))
(call $gh-write (ref.as_non_null (global.get $result)))))