add data type for function
This commit is contained in:
+41
-12
@@ -13,7 +13,7 @@ module Language.Wasm.AST (
|
|||||||
|
|
||||||
import GHC.TypeLits
|
import GHC.TypeLits
|
||||||
import Data.Proxy
|
import Data.Proxy
|
||||||
import Data.Promotion.Prelude.List
|
import Data.Promotion.Prelude.List ((:++), (:!!))
|
||||||
import Data.Word (Word32, Word64)
|
import Data.Word (Word32, Word64)
|
||||||
|
|
||||||
import Language.Wasm.Structure (
|
import Language.Wasm.Structure (
|
||||||
@@ -56,6 +56,17 @@ type family Consume (args :: [VType]) (stack :: [VType]) (result :: [VType]) ::
|
|||||||
Text "Actual stack: " :<>: ShowType stack
|
Text "Actual stack: " :<>: ShowType stack
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type family IsRetMatch (stack :: [VType]) (ret :: [ValueType]) :: Bool where
|
||||||
|
IsRetMatch stack ret = Or (Equal (Consume (AsVType ret) stack '[]) '[]) (Equal (Consume (AsVType ret) stack '[]) '[Any])
|
||||||
|
|
||||||
|
type family Or (l :: Bool) (r :: Bool) :: Bool where
|
||||||
|
Or False r = r
|
||||||
|
Or True r = True
|
||||||
|
|
||||||
|
type family Equal a b :: Bool where
|
||||||
|
Equal a a = True
|
||||||
|
Equal a b = False
|
||||||
|
|
||||||
type family ReplaceVar (types :: [VType]) (val :: VType) :: [VType] where
|
type family ReplaceVar (types :: [VType]) (val :: VType) :: [VType] where
|
||||||
ReplaceVar '[] val = '[]
|
ReplaceVar '[] val = '[]
|
||||||
ReplaceVar (Var : rest) val = val : ReplaceVar rest val
|
ReplaceVar (Var : rest) val = val : ReplaceVar rest val
|
||||||
@@ -450,17 +461,35 @@ data InstrSeq (stack :: [VType]) ctx where
|
|||||||
InstrSeq stack ctx ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[Val I64] stack '[Val F64]) ctx
|
InstrSeq (Consume '[Val I64] stack '[Val F64]) ctx
|
||||||
|
|
||||||
-- (func (export "fac-rec") (param i64) (result i64)
|
{-
|
||||||
-- (if (result i64) (i64.eq (get_local 0) (i64.const 0))
|
(func $alloc (param $size i32) (result i32)
|
||||||
-- (then (i64.const 1))
|
(local $aligned-size i32)
|
||||||
-- (else
|
(local $addr i32)
|
||||||
-- (i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1))))
|
(set_local $aligned-size (call $alligned (get_local $size)))
|
||||||
-- )
|
(if (i32.lt_u (i32.add (get_global $heap-next) (get_local $aligned-size)) (get_global $heap-end))
|
||||||
-- )
|
(then
|
||||||
-- )
|
(set_local $addr (get_global $heap-next))
|
||||||
|
(set_global $heap-next (i32.add (get_global $heap-next) (get_local $aligned-size)))
|
||||||
|
(get_local $addr)
|
||||||
|
)
|
||||||
|
(else
|
||||||
|
(call $run-gc)
|
||||||
|
(call $alloc (get_local $size))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
-}
|
||||||
|
|
||||||
facRec :: InstrSeq '[Val I32] ('Ctx '[Val I32] '[] '[] '[I32] '[('FuncType '[I32] '[I32])] '[])
|
data Function params results globals funcs types where
|
||||||
facRec = define
|
Function :: (IsRetMatch stack ret ~ True)
|
||||||
|
=> Proxy (params :: [ValueType])
|
||||||
|
-> Proxy (locals :: [ValueType])
|
||||||
|
-> Proxy (ret :: [ValueType])
|
||||||
|
-> InstrSeq stack ('Ctx ((AsVType params) :++ (AsVType locals)) globals '[] ret funcs types)
|
||||||
|
-> Function params ret globals funcs types
|
||||||
|
|
||||||
|
facRec :: Function '[I32] '[I32] '[] '[('FuncType '[I32] '[I32])] '[]
|
||||||
|
facRec = Function (Proxy @'[I32]) (Proxy @'[]) (Proxy @'[I32]) $ body
|
||||||
& GetLocal idx0
|
& GetLocal idx0
|
||||||
& I32Const 0
|
& I32Const 0
|
||||||
& I32RelOp IEq
|
& I32RelOp IEq
|
||||||
@@ -480,7 +509,7 @@ facRec = define
|
|||||||
where
|
where
|
||||||
resI32 = Proxy @('Just I32)
|
resI32 = Proxy @('Just I32)
|
||||||
idx0 = Proxy @0
|
idx0 = Proxy @0
|
||||||
define = Empty
|
body = Empty
|
||||||
else' = Empty
|
else' = Empty
|
||||||
then' = Empty
|
then' = Empty
|
||||||
infixl 1 &
|
infixl 1 &
|
||||||
|
|||||||
Reference in New Issue
Block a user