From d722a77077e89504191728cf42f7d15ddfa209a7 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 19 Jul 2017 11:46:32 +0000 Subject: Reorganise --- Sil/Compile.icl | 2 +- Sil/Parse.dcl | 2 +- Sil/Parse.icl | 4 +- Sil/Parse/Parser.dcl | 33 ----------- Sil/Parse/Parser.icl | 93 ------------------------------- Sil/Syntax.dcl | 10 ++++ Sil/Syntax.icl | 52 ++++++++++++++++++ Sil/Util.dcl | 27 --------- Sil/Util.icl | 151 --------------------------------------------------- Sil/Util/Parser.dcl | 33 +++++++++++ Sil/Util/Parser.icl | 93 +++++++++++++++++++++++++++++++ Sil/Util/Printer.dcl | 23 ++++++++ Sil/Util/Printer.icl | 105 +++++++++++++++++++++++++++++++++++ sil.icl | 4 +- 14 files changed, 322 insertions(+), 310 deletions(-) delete mode 100644 Sil/Parse/Parser.dcl delete mode 100644 Sil/Parse/Parser.icl delete mode 100644 Sil/Util.dcl delete mode 100644 Sil/Util.icl create mode 100644 Sil/Util/Parser.dcl create mode 100644 Sil/Util/Parser.icl create mode 100644 Sil/Util/Printer.dcl create mode 100644 Sil/Util/Printer.icl diff --git a/Sil/Compile.icl b/Sil/Compile.icl index 4c0d02d..42fa162 100644 --- a/Sil/Compile.icl +++ b/Sil/Compile.icl @@ -19,7 +19,7 @@ from Text import <+ import qualified ABC.Assembler as ABC import Sil.Syntax -import Sil.Util +import Sil.Util.Printer instance toString CompileError where diff --git a/Sil/Parse.dcl b/Sil/Parse.dcl index 0d00969..73f9ad3 100644 --- a/Sil/Parse.dcl +++ b/Sil/Parse.dcl @@ -4,8 +4,8 @@ from StdOverloaded import class ==, class toString from Data.Error import :: MaybeError -from Sil.Parse.Parser import class name from Sil.Syntax import :: Program, :: Literal +from Sil.Util.Parser import class name :: Token = TParenOpen //* ( diff --git a/Sil/Parse.icl b/Sil/Parse.icl index 092d3da..3a11622 100644 --- a/Sil/Parse.icl +++ b/Sil/Parse.icl @@ -20,9 +20,9 @@ from Text import <+, class Text, instance Text String import GenEq -import Sil.Parse.Parser import Sil.Syntax -import Sil.Util +import Sil.Util.Parser +import Sil.Util.Printer derive gEq Token, Literal instance == Token where == a b = gEq{|*|} a b diff --git a/Sil/Parse/Parser.dcl b/Sil/Parse/Parser.dcl deleted file mode 100644 index cdeaf49..0000000 --- a/Sil/Parse/Parser.dcl +++ /dev/null @@ -1,33 +0,0 @@ -definition module Sil.Parse.Parser - -from StdOverloaded import class == - -from Control.Applicative import class Applicative, class Alternative -from Control.Monad import class Monad -from Data.Error import :: MaybeError -from Data.Functor import class Functor - -from Sil.Parse import :: ParseError - -:: Parser a b = Parser ([a] -> (MaybeError ParseError b, [a])) - -instance Functor (Parser a) -instance Applicative (Parser a) -instance Monad (Parser a) -instance Alternative (Parser a) - -class name a :: a -> String -instance name String - -runParser :: (Parser a b) [a] -> (MaybeError ParseError b, [a]) -() :: (Parser a b) ParseError -> Parser a b -fail :: Parser a b -top :: Parser a a -peek :: Parser a a -satisfy :: (a -> Bool) -> Parser a a -check :: (a -> Bool) -> Parser a a -(until) infix 2 :: (Parser a b) (Parser a c) -> Parser a [b] -item :: a -> Parser a a | ==, name a -list :: [a] -> Parser a [a] | ==, name a -seplist :: a (Parser a b) -> Parser a [b] | ==, name a -eof :: Parser a () diff --git a/Sil/Parse/Parser.icl b/Sil/Parse/Parser.icl deleted file mode 100644 index 52956a3..0000000 --- a/Sil/Parse/Parser.icl +++ /dev/null @@ -1,93 +0,0 @@ -implementation module Sil.Parse.Parser - -import StdList -import StdOverloaded - -import Control.Applicative -import Control.Monad -import Data.Error -from Data.Func import $ -import Data.Functor -import Data.List - -import Sil.Parse - -instance Functor (Parser a) where - fmap f m = liftM f m - -instance Applicative (Parser a) where - pure a = Parser \i -> (Ok a, i) - (<*>) sf p = ap sf p - -instance Monad (Parser a) where - bind p f = Parser \i -> case runParser p i of - (Ok r, rest) -> runParser (f r) rest - (Error e, _) -> (Error e, i) - -instance Alternative (Parser a) where - empty = Parser \i -> (Error UnknownError, i) - (<|>) p1 p2 = Parser \i -> case runParser p1 i of - (Ok r, rest) -> (Ok r, rest) - (Error e1, rest) -> case runParser p2 i of - (Error e2, rest) -> (Error e2, i) - (Ok r, rest) -> (Ok r, rest) - -instance name String where name s = s - -runParser :: (Parser a b) [a] -> (MaybeError ParseError b, [a]) -runParser (Parser f) i = f i - -() :: (Parser a b) ParseError -> Parser a b -() p e = Parser \i -> case runParser p i of - (Error _, rest) -> (Error e, rest) - o -> o - -fail :: Parser a b -fail = empty - -top :: Parser a a -top = Parser \i -> case i of - [] = (Error UnknownError, []) - [x:xs] = (Ok x, xs) - -peek :: Parser a a -peek = Parser \i -> case i of - [] = (Error UnknownError, []) - [x:xs] = (Ok x, [x:xs]) - -satisfy :: (a -> Bool) -> Parser a a -satisfy f = top >>= \r -> if (f r) (pure r) fail - -check :: (a -> Bool) -> Parser a a -check f = peek >>= \r -> if (f r) (pure r) fail - -(until) infix 2 :: (Parser a b) (Parser a c) -> Parser a [b] -(until) p guard = try $ until` p guard [] -where - until` :: (Parser a b) (Parser a c) [b] -> Parser a [b] - until` p guard acc = Parser \i -> case runParser guard i of - (Ok _, rest) -> (Ok acc, rest) - (Error _, _) -> case runParser p i of - (Ok r, rest) -> runParser (until` p guard [r:acc]) rest - (Error e, _) -> (Error e, i) - - try :: (Parser a b) -> Parser a b - try p = Parser \i -> case runParser p i of - (Error e, _) -> (Error e, i) - (Ok r, rest) -> (Ok r, rest) - -item :: a -> Parser a a | ==, name a -item a = satisfy ((==) a) Expected (name a) - -list :: [a] -> Parser a [a] | ==, name a -list as = mapM item as - -seplist :: a (Parser a b) -> Parser a [b] | ==, name a -seplist sep p = liftM2 (\es e-> es ++ [e]) (some (p <* item sep)) p - <|> liftM pure p - <|> pure empty - -eof :: Parser a () -eof = Parser \i -> case i of - [] = (Ok (), []) - _ = (Error $ Expected "eof", i) diff --git a/Sil/Syntax.dcl b/Sil/Syntax.dcl index 6df64a3..5c91dc6 100644 --- a/Sil/Syntax.dcl +++ b/Sil/Syntax.dcl @@ -1,5 +1,7 @@ definition module Sil.Syntax +from StdOverloaded import class toString + from Data.Maybe import :: Maybe :: Program = @@ -66,3 +68,11 @@ from Data.Maybe import :: Maybe | ILit Int :: Name :== String + +instance toString Statement +instance toString Type +instance toString Arg +instance toString Application +instance toString Op1 +instance toString Op2 +instance toString Literal diff --git a/Sil/Syntax.icl b/Sil/Syntax.icl index 522412b..934a300 100644 --- a/Sil/Syntax.icl +++ b/Sil/Syntax.icl @@ -1,3 +1,55 @@ implementation module Sil.Syntax +import StdOverloaded +import StdString +import Data.Maybe +import Text + +import Sil.Util.Printer + +instance toString Statement +where + toString (Declaration n a) = n <+ " := " <+ a <+ ";" + toString (Application app) = toString app <+ ";" + toString (Return Nothing) = "return;" + toString (Return (Just a)) = "return " <+ a <+ ";" + toString (If c t e) = "if (" <+ c <+ ") ..." + toString (MachineStm s) = "|~" <+ s + toString _ = "<>" + +instance toString Type +where + toString TBool = "Bool" + toString TInt = "Int" + toString TVoid = "Void" + +instance toString Arg where toString arg = arg.arg_type <+ " " <+ arg.arg_name + +instance toString Application +where + toString (Name n) = n + toString (Literal lit) = toString lit + toString (App n args) = n <+ "(" <+ printersperse ", " args <+ ")" + toString (BuiltinApp op e) = op <+ "(" <+ e <+ ")" + toString (BuiltinApp2 e1 op e2) = "(" <+ e1 <+ ") " <+ op <+ " (" <+ e2 <+ ")" + +instance toString Op1 +where + toString Neg = "~" + +instance toString Op2 +where + toString Add = "+" + toString Sub = "-" + toString Mul = "*" + toString Div = "/" + toString Rem = "%" + toString Equals = "==" + toString LogOr = "||" + toString LogAnd = "&&" + +instance toString Literal +where + toString (BLit b) = toString b + toString (ILit i) = toString i diff --git a/Sil/Util.dcl b/Sil/Util.dcl deleted file mode 100644 index 54617ce..0000000 --- a/Sil/Util.dcl +++ /dev/null @@ -1,27 +0,0 @@ -definition module Sil.Util - -from StdOverloaded import class toString, class zero - -from Sil.Parse import :: Token -from Sil.Syntax import :: Program, :: Function, :: CodeBlock, - :: Initialisation, :: Statement, :: Type, :: Application, :: Literal - -:: PrintState - -instance zero PrintState - -class PrettyPrinter t where - print :: PrintState t -> String - -instance PrettyPrinter [Token] - -instance PrettyPrinter Program -instance PrettyPrinter Function -instance PrettyPrinter CodeBlock -instance PrettyPrinter Initialisation -instance PrettyPrinter Statement - -instance toString Statement -instance toString Type -instance toString Application -instance toString Literal diff --git a/Sil/Util.icl b/Sil/Util.icl deleted file mode 100644 index 35b8522..0000000 --- a/Sil/Util.icl +++ /dev/null @@ -1,151 +0,0 @@ -implementation module Sil.Util - -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 - -instance toString Statement -where - toString (Declaration n a) = n <+ " " <+ TAssign <+ " " <+ a <+ ";" - toString (Application app) = toString app <+ ";" - toString (Return Nothing) = "return;" - toString (Return (Just a)) = "return " <+ a <+ ";" - toString (If c t e) = "if (" <+ c <+ ") ..." - toString (MachineStm s) = "|~" <+ s - toString _ = "<>" - -instance toString Type -where - toString TBool = "Bool" - toString TInt = "Int" - toString TVoid = "Void" - -instance toString Arg where toString arg = arg.arg_type <+ " " <+ arg.arg_name - -instance toString Application -where - toString (Name n) = n - toString (Literal lit) = toString lit - toString (App n args) = n <+ "(" <+ printersperse ", " args <+ ")" - toString (BuiltinApp op e) = op <+ "(" <+ e <+ ")" - toString (BuiltinApp2 e1 op e2) = "(" <+ e1 <+ ") " <+ op <+ " (" <+ e2 <+ ")" - -instance toString Op1 -where - toString Neg = "~" - -instance toString Op2 -where - toString Add = "+" - toString Sub = "-" - toString Mul = "*" - toString Div = "/" - toString Rem = "%" - toString Equals = "==" - toString LogOr = "||" - toString LogAnd = "&&" - -instance toString Literal -where - toString (BLit b) = toString b - toString (ILit i) = toString i - -printersperse :: a [b] -> String | toString a & toString b -printersperse _ [] = "" -printersperse _ [x] = toString x -printersperse g [x:xs] = x <+ g <+ printersperse g xs diff --git a/Sil/Util/Parser.dcl b/Sil/Util/Parser.dcl new file mode 100644 index 0000000..361fa83 --- /dev/null +++ b/Sil/Util/Parser.dcl @@ -0,0 +1,33 @@ +definition module Sil.Util.Parser + +from StdOverloaded import class == + +from Control.Applicative import class Applicative, class Alternative +from Control.Monad import class Monad +from Data.Error import :: MaybeError +from Data.Functor import class Functor + +from Sil.Parse import :: ParseError + +:: Parser a b = Parser ([a] -> (MaybeError ParseError b, [a])) + +instance Functor (Parser a) +instance Applicative (Parser a) +instance Monad (Parser a) +instance Alternative (Parser a) + +class name a :: a -> String +instance name String + +runParser :: (Parser a b) [a] -> (MaybeError ParseError b, [a]) +() :: (Parser a b) ParseError -> Parser a b +fail :: Parser a b +top :: Parser a a +peek :: Parser a a +satisfy :: (a -> Bool) -> Parser a a +check :: (a -> Bool) -> Parser a a +(until) infix 2 :: (Parser a b) (Parser a c) -> Parser a [b] +item :: a -> Parser a a | ==, name a +list :: [a] -> Parser a [a] | ==, name a +seplist :: a (Parser a b) -> Parser a [b] | ==, name a +eof :: Parser a () diff --git a/Sil/Util/Parser.icl b/Sil/Util/Parser.icl new file mode 100644 index 0000000..f0895fe --- /dev/null +++ b/Sil/Util/Parser.icl @@ -0,0 +1,93 @@ +implementation module Sil.Util.Parser + +import StdList +import StdOverloaded + +import Control.Applicative +import Control.Monad +import Data.Error +from Data.Func import $ +import Data.Functor +import Data.List + +import Sil.Parse + +instance Functor (Parser a) where + fmap f m = liftM f m + +instance Applicative (Parser a) where + pure a = Parser \i -> (Ok a, i) + (<*>) sf p = ap sf p + +instance Monad (Parser a) where + bind p f = Parser \i -> case runParser p i of + (Ok r, rest) -> runParser (f r) rest + (Error e, _) -> (Error e, i) + +instance Alternative (Parser a) where + empty = Parser \i -> (Error UnknownError, i) + (<|>) p1 p2 = Parser \i -> case runParser p1 i of + (Ok r, rest) -> (Ok r, rest) + (Error e1, rest) -> case runParser p2 i of + (Error e2, rest) -> (Error e2, i) + (Ok r, rest) -> (Ok r, rest) + +instance name String where name s = s + +runParser :: (Parser a b) [a] -> (MaybeError ParseError b, [a]) +runParser (Parser f) i = f i + +() :: (Parser a b) ParseError -> Parser a b +() p e = Parser \i -> case runParser p i of + (Error _, rest) -> (Error e, rest) + o -> o + +fail :: Parser a b +fail = empty + +top :: Parser a a +top = Parser \i -> case i of + [] = (Error UnknownError, []) + [x:xs] = (Ok x, xs) + +peek :: Parser a a +peek = Parser \i -> case i of + [] = (Error UnknownError, []) + [x:xs] = (Ok x, [x:xs]) + +satisfy :: (a -> Bool) -> Parser a a +satisfy f = top >>= \r -> if (f r) (pure r) fail + +check :: (a -> Bool) -> Parser a a +check f = peek >>= \r -> if (f r) (pure r) fail + +(until) infix 2 :: (Parser a b) (Parser a c) -> Parser a [b] +(until) p guard = try $ until` p guard [] +where + until` :: (Parser a b) (Parser a c) [b] -> Parser a [b] + until` p guard acc = Parser \i -> case runParser guard i of + (Ok _, rest) -> (Ok acc, rest) + (Error _, _) -> case runParser p i of + (Ok r, rest) -> runParser (until` p guard [r:acc]) rest + (Error e, _) -> (Error e, i) + + try :: (Parser a b) -> Parser a b + try p = Parser \i -> case runParser p i of + (Error e, _) -> (Error e, i) + (Ok r, rest) -> (Ok r, rest) + +item :: a -> Parser a a | ==, name a +item a = satisfy ((==) a) Expected (name a) + +list :: [a] -> Parser a [a] | ==, name a +list as = mapM item as + +seplist :: a (Parser a b) -> Parser a [b] | ==, name a +seplist sep p = liftM2 (\es e-> es ++ [e]) (some (p <* item sep)) p + <|> liftM pure p + <|> pure empty + +eof :: Parser a () +eof = Parser \i -> case i of + [] = (Ok (), []) + _ = (Error $ Expected "eof", i) diff --git a/Sil/Util/Printer.dcl b/Sil/Util/Printer.dcl new file mode 100644 index 0000000..1d8fc5c --- /dev/null +++ b/Sil/Util/Printer.dcl @@ -0,0 +1,23 @@ +definition module Sil.Util.Printer + +from StdOverloaded import class toString, class zero + +from Sil.Parse import :: Token +from Sil.Syntax import :: Program, :: Function, :: CodeBlock, + :: Initialisation, :: Statement, :: Type, :: Application, :: Literal + +:: PrintState + +instance zero PrintState + +class PrettyPrinter t where + print :: PrintState t -> String + +instance PrettyPrinter [Token] +instance PrettyPrinter Program +instance PrettyPrinter Function +instance PrettyPrinter CodeBlock +instance PrettyPrinter Initialisation +instance PrettyPrinter Statement + +printersperse :: a [b] -> String | toString a & toString b 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 diff --git a/sil.icl b/sil.icl index 77b5322..8bfe037 100644 --- a/sil.icl +++ b/sil.icl @@ -23,9 +23,9 @@ import ABC.Assembler import qualified Sil.Compile as SC from Sil.Compile import :: CompileError, instance toString CompileError import Sil.Parse -import Sil.Parse.Parser from Sil.Syntax import :: Program -from Sil.Util import :: PrintState, instance zero PrintState, +import Sil.Util.Parser +from Sil.Util.Printer import :: PrintState, instance zero PrintState, class PrettyPrinter(..), instance PrettyPrinter Program :: CLI = -- cgit v1.2.3