module AST where import Data.List import Data.Word type Byte = Word8 type Offset = Int newtype Program = Program [Instruction] deriving (Show, Eq) data Instruction = IAdd Byte Offset | ISet Byte Offset | ICopy Offset Offset Byte -- ICopy from to multiplier | ISlide Offset | ILoop [Instruction] Offset | IInput Offset | IOutput Offset | IStart deriving (Show, Eq) isIAdd :: Instruction -> Bool isIAdd (IAdd _ _) = True isIAdd _ = False isISet :: Instruction -> Bool isISet (ISet _ _) = True isISet _ = False isICopy :: Instruction -> Bool isICopy (ICopy _ _ _) = True isICopy _ = False isISlide :: Instruction -> Bool isISlide (ISlide _) = True isISlide _ = False isIStart :: Instruction -> Bool isIStart IStart = True isIStart _ = False offsetOf :: Instruction -> Offset offsetOf (IAdd _ o) = o offsetOf (ISet _ o) = o offsetOf (ICopy o _ _) = o offsetOf (ISlide _) = undefined offsetOf (ILoop _ _) = undefined offsetOf (IInput o) = o offsetOf (IOutput o) = o offsetOf IStart = 0 astSuccinct :: Program -> String astSuccinct (Program inss) = intercalate " " $ map insSuccinct inss where insSuccinct :: Instruction -> String insSuccinct (IAdd v o) = let sv = signedByte v in (if sv >= 0 then "+" else "") ++ show (signedByte v) ++ ',' : show o insSuccinct (ISet v o) = '=' : show (signedByte v) ++ ',' : show o insSuccinct (ICopy from to v) = 'C' : show from ++ ',' : show to ++ ',' : show v insSuccinct (ISlide o) = '>' : show o insSuccinct (ILoop inss' off) = "[(" ++ show off ++ ')' : intercalate " " (map insSuccinct inss') ++ "]" insSuccinct (IInput o) = ',' : show o insSuccinct (IOutput o) = '.' : show o insSuccinct IStart = "$" signedByte :: Byte -> Int signedByte v | v < 128 = fromIntegral v | otherwise = fromIntegral v - 256