replace several type args with one context
This commit is contained in:
+84
-48
@@ -2,11 +2,9 @@
|
|||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE TypeOperators #-}
|
{-# LANGUAGE TypeOperators #-}
|
||||||
{-# LANGUAGE KindSignatures #-}
|
|
||||||
{-# LANGUAGE PolyKinds #-}
|
{-# LANGUAGE PolyKinds #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
|
||||||
|
|
||||||
module Language.Wasm.AST (
|
module Language.Wasm.AST (
|
||||||
|
|
||||||
@@ -75,6 +73,10 @@ type family LabelAsArgs (label :: Maybe ValueType) :: [VType] where
|
|||||||
LabelAsArgs (Just val) = '[Val val]
|
LabelAsArgs (Just val) = '[Val val]
|
||||||
LabelAsArgs Nothing = '[]
|
LabelAsArgs Nothing = '[]
|
||||||
|
|
||||||
|
type family AsVType (values :: [ValueType]) :: [VType] where
|
||||||
|
AsVType (v : vs) = Val v : AsVType vs
|
||||||
|
AsVType '[] = '[]
|
||||||
|
|
||||||
class KnownNats ns where
|
class KnownNats ns where
|
||||||
natVals :: Proxy ns -> [Integer]
|
natVals :: Proxy ns -> [Integer]
|
||||||
|
|
||||||
@@ -87,70 +89,104 @@ instance (KnownNat n, KnownNats ns) => KnownNats (n : ns) where
|
|||||||
dup :: Proxy (n : ns) -> (Proxy n, Proxy ns)
|
dup :: Proxy (n : ns) -> (Proxy n, Proxy ns)
|
||||||
dup _ = (Proxy, Proxy)
|
dup _ = (Proxy, Proxy)
|
||||||
|
|
||||||
data InstrSeq (stack :: [VType]) (locals :: [VType]) (globals :: [GlobalType]) (labels :: [Maybe ValueType]) where
|
data Ctx (locals :: [VType]) (globals :: [GlobalType]) (labels :: [Maybe ValueType]) (returns :: [ValueType])
|
||||||
Empty :: InstrSeq '[] locals globals labels
|
|
||||||
Unreachable :: InstrSeq stack locals globals labels -> InstrSeq '[Any] locals globals labels
|
type family GetLocals ctx :: [VType] where
|
||||||
Nop :: InstrSeq stack locals globals labels -> InstrSeq stack locals globals labels
|
GetLocals (Ctx locals globals labels returns) = locals
|
||||||
|
|
||||||
|
type family GetGlobals ctx :: [GlobalType] where
|
||||||
|
GetGlobals (Ctx locals globals labels returns) = globals
|
||||||
|
|
||||||
|
type family GetLabels ctx :: [Maybe ValueType] where
|
||||||
|
GetLabels (Ctx locals globals labels returns) = labels
|
||||||
|
|
||||||
|
type family WithLabel ctx (label :: Maybe ValueType) where
|
||||||
|
WithLabel (Ctx locals globals labels returns) label = Ctx locals globals (label : labels) returns
|
||||||
|
|
||||||
|
type family GetReturns ctx :: [ValueType] where
|
||||||
|
GetReturns (Ctx locals globals labels returns) = returns
|
||||||
|
|
||||||
|
data InstrSeq (stack :: [VType]) ctx where
|
||||||
|
Empty :: InstrSeq '[] ctx
|
||||||
|
Unreachable :: InstrSeq stack ctx -> InstrSeq '[Any] ctx
|
||||||
|
Nop :: InstrSeq stack ctx -> InstrSeq stack ctx
|
||||||
Block :: (IsLabelMatch label result ~ True) =>
|
Block :: (IsLabelMatch label result ~ True) =>
|
||||||
InstrSeq result locals globals (label : labels) ->
|
Proxy (label :: Maybe ValueType) ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq result (WithLabel ctx label) ->
|
||||||
InstrSeq (result :++ stack) locals globals labels
|
InstrSeq stack ctx ->
|
||||||
|
InstrSeq (result :++ stack) ctx
|
||||||
Loop :: (IsLabelMatch label result ~ True) =>
|
Loop :: (IsLabelMatch label result ~ True) =>
|
||||||
InstrSeq result locals globals (label : labels) ->
|
Proxy (label :: Maybe ValueType) ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq result (WithLabel ctx label) ->
|
||||||
InstrSeq (result :++ stack) locals globals labels
|
InstrSeq stack ctx ->
|
||||||
|
InstrSeq (result :++ stack) ctx
|
||||||
If :: (IsLabelMatch label result ~ True, MatchStack '[Val I32] stack ~ True) =>
|
If :: (IsLabelMatch label result ~ True, MatchStack '[Val I32] stack ~ True) =>
|
||||||
InstrSeq result locals globals (label : labels) ->
|
Proxy (label :: Maybe ValueType) ->
|
||||||
InstrSeq result locals globals (label : labels) ->
|
InstrSeq result (WithLabel ctx label) ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq result (WithLabel ctx label) ->
|
||||||
InstrSeq (Consume '[Val I32] stack result) locals globals labels
|
InstrSeq stack ctx ->
|
||||||
Br :: (KnownNat label, MatchStack (LabelAsArgs (labels :!! label)) stack ~ True) =>
|
InstrSeq (Consume '[Val I32] stack result) ctx
|
||||||
|
Br :: (KnownNat label, MatchStack (LabelAsArgs ((GetLabels ctx) :!! label)) stack ~ True) =>
|
||||||
Proxy label ->
|
Proxy label ->
|
||||||
InstrSeq stack locals globals lables ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq '[Any] locals globals labels
|
InstrSeq '[Any] ctx
|
||||||
BrIf :: (KnownNat label, MatchStack ((LabelAsArgs (labels :!! label)) :++ '[Val I32]) stack ~ True) =>
|
BrIf :: (KnownNat label, MatchStack ((LabelAsArgs ((GetLabels ctx) :!! label)) :++ '[Val I32]) stack ~ True) =>
|
||||||
Proxy label ->
|
Proxy label ->
|
||||||
InstrSeq stack locals globals lables ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume ((LabelAsArgs (labels :!! label)) :++ '[Val I32]) stack (LabelAsArgs (labels :!! label))) locals globals labels
|
InstrSeq (Consume ((LabelAsArgs ((GetLabels ctx) :!! label)) :++ '[Val I32]) stack (LabelAsArgs ((GetLabels ctx) :!! label))) ctx
|
||||||
BrTable :: (KnownNat defaultLabel, KnownNats localLabels, MatchStack ((LabelAsArgs (labels :!! defaultLabel)) :++ '[Val I32]) stack ~ True) =>
|
BrTable :: (
|
||||||
|
KnownNat defaultLabel,
|
||||||
|
KnownNats localLabels,
|
||||||
|
MatchStack ((LabelAsArgs ((GetLabels ctx) :!! defaultLabel)) :++ '[Val I32]) stack ~ True
|
||||||
|
) =>
|
||||||
Proxy (localLabels :: [Nat]) ->
|
Proxy (localLabels :: [Nat]) ->
|
||||||
Proxy defaultLabel ->
|
Proxy defaultLabel ->
|
||||||
InstrSeq stack locals globals lables ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume ((LabelAsArgs (labels :!! defaultLabel)) :++ '[Val I32]) stack '[Any]) locals globals labels
|
InstrSeq (Consume ((LabelAsArgs ((GetLabels ctx) :!! defaultLabel)) :++ '[Val I32]) stack '[Any]) ctx
|
||||||
Drop :: InstrSeq (any : stack) locals globals labels -> InstrSeq stack locals globals labels
|
Return :: (MatchStack (AsVType (GetReturns ctx)) stack ~ True) =>
|
||||||
|
InstrSeq stack ctx ->
|
||||||
|
InstrSeq (Consume (AsVType (GetReturns ctx)) stack '[Any]) ctx
|
||||||
|
-- Call :: (MatchStack (AsVType returns) stack ~ True) =>
|
||||||
|
-- Proxy function ->
|
||||||
|
-- InstrSeq stack locals globals lables returns ->
|
||||||
|
Drop :: InstrSeq (any : stack) ctx -> InstrSeq stack ctx
|
||||||
Select :: (MatchStack '[Var, Var, Val I32] stack ~ True) =>
|
Select :: (MatchStack '[Var, Var, Val I32] stack ~ True) =>
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[Var, Var, Val I32] stack '[Var]) locals globals labels
|
InstrSeq (Consume '[Var, Var, Val I32] stack '[Var]) ctx
|
||||||
GetLocal :: (KnownNat local) =>
|
GetLocal :: (KnownNat local) =>
|
||||||
Proxy local ->
|
Proxy local ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq ((locals :!! local) : stack) locals globals labels
|
InstrSeq (((GetLocals ctx) :!! local) : stack) ctx
|
||||||
SetLocal :: (KnownNat local, MatchStack '[locals :!! local] stack ~ True) =>
|
SetLocal :: (KnownNat local, MatchStack '[(GetLocals ctx) :!! local] stack ~ True) =>
|
||||||
Proxy local ->
|
Proxy local ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[locals :!! local] stack '[]) locals globals labels
|
InstrSeq (Consume '[(GetLocals ctx) :!! local] stack '[]) ctx
|
||||||
TeeLocal :: (KnownNat local, MatchStack '[locals :!! local] stack ~ True) =>
|
TeeLocal :: (KnownNat local, MatchStack '[(GetLocals ctx) :!! local] stack ~ True) =>
|
||||||
Proxy local ->
|
Proxy local ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[locals :!! local] stack '[locals :!! local]) locals globals labels
|
InstrSeq (Consume '[(GetLocals ctx) :!! local] stack '[(GetLocals ctx) :!! local]) ctx
|
||||||
GetGlobal :: (KnownNat global) =>
|
GetGlobal :: (KnownNat global) =>
|
||||||
Proxy global ->
|
Proxy global ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq ((GetGlobalType (globals :!! global)) : stack) locals globals labels
|
InstrSeq ((GetGlobalType ((GetGlobals ctx) :!! global)) : stack) ctx
|
||||||
SetGlobal :: (KnownNat global, MatchStack '[GetGlobalType (globals :!! global)] stack ~ True, IsMutable (globals :!! global) ~ True) =>
|
SetGlobal :: (
|
||||||
|
KnownNat global,
|
||||||
|
MatchStack '[GetGlobalType ((GetGlobals ctx) :!! global)] stack ~ True,
|
||||||
|
IsMutable ((GetGlobals ctx) :!! global) ~ True
|
||||||
|
) =>
|
||||||
Proxy global ->
|
Proxy global ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[GetGlobalType (globals :!! global)] stack '[]) locals globals labels
|
InstrSeq (Consume '[GetGlobalType ((GetGlobals ctx) :!! global)] stack '[]) ctx
|
||||||
I32Const :: InstrSeq stack locals globals labels -> InstrSeq (Val I32 : stack) locals globals labels
|
I32Const :: InstrSeq stack ctx -> InstrSeq (Val I32 : stack) ctx
|
||||||
I32UnOp :: (MatchStack '[Val I32] stack ~ True) =>
|
I32UnOp :: (MatchStack '[Val I32] stack ~ True) =>
|
||||||
IUnOp ->
|
IUnOp ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[Val I32] stack '[Val I32]) locals globals labels
|
InstrSeq (Consume '[Val I32] stack '[Val I32]) ctx
|
||||||
I32BinOp :: (MatchStack '[Val I32, Val I32] stack ~ True) =>
|
I32BinOp :: (MatchStack '[Val I32, Val I32] stack ~ True) =>
|
||||||
IBinOp ->
|
IBinOp ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[Val I32, Val I32] stack '[Val I32]) locals globals labels
|
InstrSeq (Consume '[Val I32, Val I32] stack '[Val I32]) ctx
|
||||||
I32RelOp :: (MatchStack '[Val I32, Val I32] stack ~ True) =>
|
I32RelOp :: (MatchStack '[Val I32, Val I32] stack ~ True) =>
|
||||||
IRelOp ->
|
IRelOp ->
|
||||||
InstrSeq stack locals globals labels ->
|
InstrSeq stack ctx ->
|
||||||
InstrSeq (Consume '[Val I32, Val I32] stack '[Val I32]) locals globals labels
|
InstrSeq (Consume '[Val I32, Val I32] stack '[Val I32]) ctx
|
||||||
Reference in New Issue
Block a user