blob: cd7fed23302288a642ea0ae5125b0fb3a52c8ceb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
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
|