aboutsummaryrefslogtreecommitdiffstats
path: root/src/GSA/Printer.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/GSA/Printer.hs')
-rw-r--r--src/GSA/Printer.hs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/GSA/Printer.hs b/src/GSA/Printer.hs
new file mode 100644
index 0000000..aca04e1
--- /dev/null
+++ b/src/GSA/Printer.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module GSA.Printer
+ (regPrinter, operationPrinter, instructionPrinter, codePrinter, functionPrinter, programPrinter)
+where
+
+import Data.IntMap.Strict (IntMap)
+import qualified Data.IntMap.Strict as IMap
+import Data.Map.Strict (Map)
+import qualified Data.Map.Strict as Map
+import Data.Text (Text)
+import qualified Data.Text as T
+
+import GSA.Types
+
+tshow :: Show a => a -> Text
+tshow = T.pack . show
+
+parens :: Text -> Text
+parens t = "(" <> t <> ")"
+
+braces :: Text -> Text
+braces t = "{" <> t <> "}"
+
+sep :: Text -> [Text] -> Text
+sep = T.intercalate
+
+commaSep :: [Text] -> Text
+commaSep = sep ", "
+
+regPrinter :: Reg -> Text
+regPrinter (Reg i) = "x" <> tshow i
+
+operationPrinter :: Operation -> [Reg] -> Text
+operationPrinter Omove [r1] = regPrinter r1
+operationPrinter p _ = error $ "Operation printing not implemented: " <> show p
+
+instructionPrinter :: Int -> Instruction -> Text
+instructionPrinter i (Inop (Node n))
+ | i - 1 == n = " " <> tshow i <> ":\tnop"
+ | otherwise = " " <> tshow i <> ":\tgoto " <> tshow n
+instructionPrinter i (Iop op args dest (Node n)) =
+ " " <> tshow i <> ":\t" <> regPrinter dest <> " = " <> operationPrinter op args <>
+ if i - 1 == n then "" else "goto " <> tshow n
+instructionPrinter _ op = error $ "Instruction printing not implemented: " <> show op
+
+codePrinter :: Code -> Text
+codePrinter (Code c) = IMap.foldrWithKey f "" c
+ where
+ f k a b = b <> instructionPrinter k a <> "\n"
+
+functionPrinter :: Text -> Function -> Text
+functionPrinter n f = n
+ <> parens (commaSep $ regPrinter <$> fnParams f) <> " "
+ <> braces ("\n" <> codePrinter (fnCode f))
+
+programPrinter :: Program -> Text
+programPrinter (Program p) = Map.foldrWithKey f "" p
+ where
+ f k a b = b <> functionPrinter k a <> "\n\n"