aboutsummaryrefslogtreecommitdiff
path: root/Sil/Util/Printer.icl
diff options
context:
space:
mode:
authorCamil Staps2017-07-19 11:46:32 +0000
committerCamil Staps2017-07-19 11:46:32 +0000
commitd722a77077e89504191728cf42f7d15ddfa209a7 (patch)
treef3f70e055e9a76dba7eecde01146c697b452f064 /Sil/Util/Printer.icl
parentWorking fibonacci (diff)
Reorganise
Diffstat (limited to 'Sil/Util/Printer.icl')
-rw-r--r--Sil/Util/Printer.icl105
1 files changed, 105 insertions, 0 deletions
diff --git a/Sil/Util/Printer.icl b/Sil/Util/Printer.icl
new file mode 100644
index 0000000..2252ee4
--- /dev/null
+++ b/Sil/Util/Printer.icl
@@ -0,0 +1,105 @@
+implementation module Sil.Util.Printer
+
+import _SystemArray
+import StdEnum
+from StdFunc import id
+import StdInt
+import StdList
+import StdOverloaded
+import StdString
+
+from Data.Func import $
+import Data.List
+import Data.Maybe
+import Text
+
+import Sil.Parse
+import Sil.Syntax
+
+:: PrintState =
+ { indent :: Int
+ }
+
+instance zero PrintState where zero = {indent=0}
+
+incIndent :: PrintState -> PrintState
+incIndent ps = {ps & indent=inc ps.indent}
+
+decIndent :: PrintState -> PrintState
+decIndent ps = {ps & indent=dec ps.indent}
+
+instance toString PrintState where toString st = {'\t' \\ _ <- [1..st.indent]}
+
+instance PrettyPrinter [Token]
+where
+ print st [] = ""
+ print st [t] = toString t
+ print st [t:ts=:[t`:_]] = toString t +++ spaceBetween t t` +++ print st` ts
+ where
+ st` = {st & indent=indent`}
+ indent` = newIndent t t` st.indent
+
+ spaceBetween :: Token Token -> String
+ spaceBetween _ TBraceClose = newline
+ spaceBetween TParenOpen _ = ""
+ spaceBetween TParenClose TBraceOpen = space
+ spaceBetween TParenClose _ = ""
+ spaceBetween TBraceOpen _ = newline
+ spaceBetween TBraceClose _ = newline
+ spaceBetween TComma _ = space
+ spaceBetween TSemicolon _ = newline
+ spaceBetween TAssign _ = space
+ spaceBetween (TLit _) _ = space
+ spaceBetween TIf _ = space
+ spaceBetween TWhile _ = space
+ spaceBetween TReturn _ = space
+ spaceBetween (TName _) TParenClose = ""
+ spaceBetween (TName _) TSemicolon = ""
+ spaceBetween (TName _) _ = space
+
+ newline = "\r\n" +++ {'\t' \\ _ <- [1..indent`]}
+ space = " "
+
+ newIndent :: Token Token -> Int -> Int
+ newIndent TBraceOpen _ = inc
+ newIndent _ TBraceClose = dec
+ newIndent _ _ = id
+
+instance PrettyPrinter Program
+where
+ print st prog = p st prog.p_funs
+ where
+ p :: PrintState [Function] -> String
+ p _ [] = ""
+ p st [f] = print st f
+ p st [f:fs] = print st f <+ "\r\n\r\n" <+ p st fs
+
+instance PrettyPrinter Function
+where
+ print st f = st <+ f.f_type <+ " " <+ f.f_name
+ <+ "(" <+ printersperse ", " f.f_args <+ ") {\r\n"
+ <+ print {st & indent=st.indent+1} f.f_code <+ "\r\n" <+ st <+ "}"
+
+instance PrettyPrinter CodeBlock
+where
+ print st cb = concat $ intersperse "\r\n" $
+ [print st x \\ x <- cb.cb_init] ++ [print st x \\ x <- cb.cb_content]
+
+instance PrettyPrinter Initialisation
+where
+ print st init = st <+ init.init_type <+ " " <+ init.init_name <+ ";"
+
+instance PrettyPrinter Statement
+where
+ print st (If c t Nothing) = st <+ "if (" <+ c <+ ") {\r\n" <+
+ print (incIndent st) t <+ "\r\n" <+ st <+ "}"
+ print st (If c t (Just e)) = st <+ "if (" <+ c <+ ") {\r\n" <+
+ print st` t <+ "\r\n" <+ st <+ "} else {\r\n" <+
+ print st` e <+ "\r\n" <+ st <+ "}"
+ where st` = incIndent st
+ print st stm = st <+ stm
+
+printersperse :: a [b] -> String | toString a & toString b
+printersperse _ [] = ""
+printersperse _ [x] = toString x
+printersperse g [x:xs] = x <+ g <+ printersperse g xs