<commit_before>{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns        #-}
{-# LANGUAGE OverloadedStrings     #-}
module Trans.HaskellToText (moduleToText) where

import Data.List                    (intersperse)
import Data.String                  (fromString)
import Text.PrettyPrint.Leijen.Text (hcat, vcat)

import qualified Text.PrettyPrint.Leijen.Text as PP

import qualified IR.Common  as C
import qualified IR.Haskell as Haskell
import qualified IR.Name    as Name

moduleToText :: Haskell.Module -> PP.Doc
moduleToText = format

-- | Types which can be rendered as haskell source code.
--
-- Note well: while format returns a Doc, it is not safe to render it using
-- wl-pprint's "compact" output; we rely on newline significance in some ways
-- without enforcing it.
--
-- It would be nice to fix this, but given that we don't currently expose this
-- via the library and only ever render it in the one place (in main), it isn't
-- a huge priority.
class Format a where
    format :: a -> PP.Doc

instance Format Haskell.Module where
    format Haskell.Module{modName, modDecls, modImports} = vcat
        [ hcat
            [ "module "
            , PP.textStrict $ mconcat $ intersperse "." $ map Name.renderUnQ modName
            , " where"
            ]
        , vcat $ map format modImports
        -- We import many things, including the prelude, qualified under the
        -- "Std_" namespace, so that they don't collide with names in the
        -- generated code; see issue #58.
        , vcat $ map format
            [ Haskell.Import { importAs = "Std_", parts = ["Prelude"] }
            , Haskell.Import { importAs = "Std_", parts = ["Data", "Word"] }
            , Haskell.Import { importAs = "Std_", parts = ["Data", "Int"] }
            ]
        , vcat $ map format modDecls
        ]

instance Format Haskell.Decl where
    format Haskell.DataDecl{dataName, dataVariants, derives} = vcat
        [ hcat [ "data ", format dataName ]
        , indent $ vcat
            [ case dataVariants of
                (d:ds) -> vcat $ ("= " <> format d) : map (("| " <>) . format) ds
                []     -> ""
            , formatDerives derives
            ]
        ]
    format Haskell.NewtypeDecl{dataName, typeArgs, dataVariant, derives} = vcat
        [ hcat
            [ "newtype "
            , format dataName
            , " "
            , mconcat $ intersperse " " $ map PP.textStrict typeArgs
            ]
        , indent $ vcat
            [ hcat [ "= ", format dataVariant ]
            , formatDerives derives
            ]
        ]
    format Haskell.ValueDecl{typ, def=def@Haskell.ValueDef{name}} = vcat
        [ hcat [ format name, " :: ", format typ ]
        , format def
        ]
    format Haskell.InstanceDecl{ctx, typ, defs} = vcat
        [ hcat
            [ "instance "
            , format (Haskell.CtxType ctx typ)
            , case defs of
                []  -> ""
                _:_ -> " where"
            ]
        , indent $ vcat $
            map format defs
        ]

instance Format Haskell.ValueDef where
    format Haskell.ValueDef{name, value, params} = hcat
        [ format name
        , " "
        , hcat $ intersperse " " $ map format params
        , " = "
        , format value
        ]

instance Format Haskell.Exp where
    format (Haskell.ExApp e es) =
        mconcat $ intersperse " " $ map format (e:es)
    format (Haskell.ExGlobalName e) = format e
    format (Haskell.ExLocalName e) = format e
    format (Haskell.ExInteger n) = fromString (show n)

instance Format Haskell.Pattern where
    format (Haskell.PVar v) = PP.textStrict v
    format (Haskell.PLocalCtor c ps) = hcat
        [ "("
        , mconcat $ intersperse " " (format c : map format ps)
        , ")"
        ]
    format (Haskell.PInteger n) = fromString (show n)

formatDerives :: [Name.UnQ] -> PP.Doc
formatDerives [] = ""
formatDerives ds = "deriving" <> PP.tupled (map format ds)

instance Format Haskell.DataVariant where
    format Haskell.DataVariant{dvCtorName, dvArgs} =
        hcat [ format dvCtorName, " ", format dvArgs ]

instance Format Haskell.DataArgs where<commit_msg>Add missing parens in output<commit_after>{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns        #-}
{-# LANGUAGE OverloadedStrings     #-}
module Trans.HaskellToText (moduleToText) where

import Data.List                    (intersperse)
import Data.String                  (fromString)
import Text.PrettyPrint.Leijen.Text (hcat, vcat)

import qualified Text.PrettyPrint.Leijen.Text as PP

import qualified IR.Common  as C
import qualified IR.Haskell as Haskell
import qualified IR.Name    as Name

moduleToText :: Haskell.Module -> PP.Doc
moduleToText = format

-- | Types which can be rendered as haskell source code.
--
-- Note well: while format returns a Doc, it is not safe to render it using
-- wl-pprint's "compact" output; we rely on newline significance in some ways
-- without enforcing it.
--
-- It would be nice to fix this, but given that we don't currently expose this
-- via the library and only ever render it in the one place (in main), it isn't
-- a huge priority.
class Format a where
    format :: a -> PP.Doc

instance Format Haskell.Module where
    format Haskell.Module{modName, modDecls, modImports} = vcat
        [ hcat
            [ "module "
            , PP.textStrict $ mconcat $ intersperse "." $ map Name.renderUnQ modName
            , " where"
            ]
        , vcat $ map format modImports
        -- We import many things, including the prelude, qualified under the
        -- "Std_" namespace, so that they don't collide with names in the
        -- generated code; see issue #58.
        , vcat $ map format
            [ Haskell.Import { importAs = "Std_", parts = ["Prelude"] }
            , Haskell.Import { importAs = "Std_", parts = ["Data", "Word"] }
            , Haskell.Import { importAs = "Std_", parts = ["Data", "Int"] }
            ]
        , vcat $ map format modDecls
        ]

instance Format Haskell.Decl where
    format Haskell.DataDecl{dataName, dataVariants, derives} = vcat
        [ hcat [ "data ", format dataName ]
        , indent $ vcat
            [ case dataVariants of
                (d:ds) -> vcat $ ("= " <> format d) : map (("| " <>) . format) ds
                []     -> ""
            , formatDerives derives
            ]
        ]
    format Haskell.NewtypeDecl{dataName, typeArgs, dataVariant, derives} = vcat
        [ hcat
            [ "newtype "
            , format dataName
            , " "
            , mconcat $ intersperse " " $ map PP.textStrict typeArgs
            ]
        , indent $ vcat
            [ hcat [ "= ", format dataVariant ]
            , formatDerives derives
            ]
        ]
    format Haskell.ValueDecl{typ, def=def@Haskell.ValueDef{name}} = vcat
        [ hcat [ format name, " :: ", format typ ]
        , format def
        ]
    format Haskell.InstanceDecl{ctx, typ, defs} = vcat
        [ hcat
            [ "instance "
            , format (Haskell.CtxType ctx typ)
            , case defs of
                []  -> ""
                _:_ -> " where"
            ]
        , indent $ vcat $
            map format defs
        ]

instance Format Haskell.ValueDef where
    format Haskell.ValueDef{name, value, params} = hcat
        [ format name
        , " "
        , hcat $ intersperse " " $ map format params
        , " = "
        , format value
        ]

instance Format Haskell.Exp where
    format (Haskell.ExApp e es) = hcat
        [ "("
        , hcat $ intersperse " " $ map format (e:es)
        , ")"
        ]
    format (Haskell.ExGlobalName e) = format e
    format (Haskell.ExLocalName e) = format e
    format (Haskell.ExInteger n) = fromString (show n)

instance Format Haskell.Pattern where
    format (Haskell.PVar v) = PP.textStrict v
    format (Haskell.PLocalCtor c ps) = hcat
        [ "("
        , mconcat $ intersperse " " (format c : map format ps)
        , ")"
        ]
    format (Haskell.PInteger n) = fromString (show n)

formatDerives :: [Name.UnQ] -> PP.Doc
formatDerives [] = ""
formatDerives ds = "deriving" <> PP.tupled (map format ds)

instance Format Haskell.DataVariant where
    format Haskell.DataVariant{dvCtorName, dvArgs} =
        hcat [ format dvCtorName, " ", format dvArgs ]

instance Format Haskell.DataArgs where
{'fraction_non_alphanumeric': 0.10370723566575277, 'fraction_numerical': 0.00047681487662415065, 'mean_word_length': 1.9857651245551602, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2243577', 'n_tokens_mistral': 2578, 'n_tokens_neox': 2421, 'n_words': 760}