summaryrefslogtreecommitdiff
path: root/AST.hs
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2018-04-15 00:12:01 +0200
committerTom Smeding <tom.smeding@gmail.com>2018-04-15 00:12:01 +0200
commit873c294497c74e85eae5310cbf19269807c75e6d (patch)
treebc8558a62559b449ff702593cdc40314359ae2db /AST.hs
parent6489f93d146d7b6a381fc2815158240d26b5febc (diff)
Build with stack
Diffstat (limited to 'AST.hs')
-rw-r--r--AST.hs73
1 files changed, 73 insertions, 0 deletions
diff --git a/AST.hs b/AST.hs
new file mode 100644
index 0000000..cd7fed2
--- /dev/null
+++ b/AST.hs
@@ -0,0 +1,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