SCRIPTWriter-1.0: lib/Bitcoin/Script/Parser/AST.hs
{-# LANGUAGE GADTs #-}
module Bitcoin.Script.Parser.AST where
import Data.Bitcoin.Script.Types
import qualified Data.ByteString as BS
import Bitcoin.Script.Parser.Standard
type Label = Int
data ScriptAST where
-- |'ScriptITE': Location OP_IF -> True branch -> Location OP_ELSE -> False branch -> Location OP_ENDIF -> Continuation
ScriptITE :: Label -> ScriptAST -> Label -> ScriptAST -> Label -> ScriptAST -> ScriptAST
-- |'ScriptOp': Location op -> op -> Continuation
ScriptOp :: Label -> ScriptOp -> ScriptAST -> ScriptAST
ScriptTail :: ScriptAST
instance Show ScriptAST where
show (ScriptOp l (OP_PUSHDATA bs _) cont) = show l ++ ":\tBS_" ++ show (BS.length bs) ++ " " ++ printBSInHex bs ++ ";\n" ++ show cont
show (ScriptOp l op cont) = show l ++ ":\t" ++ show op ++ ";\n" ++ show cont
show (ScriptITE ifLbl b0 elseLbl b1 fiLbl cont) =
show ifLbl ++ ":\tIF {\n" ++
show b0 ++
show elseLbl ++ ":\t} ELSE {\n" ++
show b1 ++
show fiLbl ++ ":\t}\n" ++
show cont
show ScriptTail = ""
runFillLabels :: ScriptAST -> ScriptAST
runFillLabels scrpt = evalCounter (fillLabels scrpt)
fillLabels :: ScriptAST -> CounterState ScriptAST
fillLabels (ScriptITE _ b0 _ b1 _ cont) = do
ifLbl <- tickCounter
b0' <- fillLabels b0
elseLbl <- tickCounter
b1' <- fillLabels b1
fiLbl <- tickCounter
cont' <- fillLabels cont
return $ ScriptITE ifLbl b0' elseLbl b1' fiLbl cont'
fillLabels (ScriptOp _ op cont) = do
lblOp <- tickCounter
cont' <- fillLabels cont
return $ ScriptOp lblOp op cont'
fillLabels ScriptTail = return ScriptTail