diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..8392d159f --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b3ad53f28 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "haskell.formattingProvider": "fourmolu" +} \ No newline at end of file diff --git a/cabal.project b/cabal.project new file mode 100644 index 000000000..cc727a8ba --- /dev/null +++ b/cabal.project @@ -0,0 +1 @@ +packages: eo-phi-normalizer diff --git a/eo-phi-normalizer/eo-phi-normalizer.cabal b/eo-phi-normalizer/eo-phi-normalizer.cabal index f342af145..7949d9e9c 100644 --- a/eo-phi-normalizer/eo-phi-normalizer.cabal +++ b/eo-phi-normalizer/eo-phi-normalizer.cabal @@ -1,4 +1,4 @@ -cabal-version: 2.2 +cabal-version: 1.24 -- This file has been generated from package.yaml by hpack version 0.36.0. -- @@ -12,7 +12,7 @@ bug-reports: https://github.com/objectionary/eo-phi-normalizer/issues author: EO/Polystat Development Team maintainer: nickolay.kudasov@gmail.com copyright: 2023 EO/Polystat Development Team -license: BSD-3-Clause +license: BSD3 license-file: LICENSE build-type: Custom extra-source-files: @@ -40,8 +40,6 @@ library Language.EO.Phi.Syntax.Print other-modules: Paths_eo_phi_normalizer - autogen-modules: - Paths_eo_phi_normalizer hs-source-dirs: src ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -Wno-missing-export-lists @@ -63,8 +61,6 @@ executable normalize-phi main-is: Main.hs other-modules: Paths_eo_phi_normalizer - autogen-modules: - Paths_eo_phi_normalizer hs-source-dirs: app ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -Wno-missing-export-lists -threaded -rtsopts -with-rtsopts=-N @@ -90,8 +86,6 @@ test-suite eo-phi-normalizer-test Language.EO.PhiSpec Test.EO.Phi Paths_eo_phi_normalizer - autogen-modules: - Paths_eo_phi_normalizer hs-source-dirs: test ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -Wno-missing-export-lists -threaded -rtsopts -with-rtsopts=-N diff --git a/eo-phi-normalizer/package.yaml b/eo-phi-normalizer/package.yaml index ebd89229c..420d19164 100644 --- a/eo-phi-normalizer/package.yaml +++ b/eo-phi-normalizer/package.yaml @@ -1,7 +1,7 @@ name: eo-phi-normalizer version: 0.1.0 github: "objectionary/eo-phi-normalizer" -license: BSD-3-Clause +license: BSD3 author: "EO/Polystat Development Team" maintainer: "nickolay.kudasov@gmail.com" copyright: "2023 EO/Polystat Development Team" @@ -11,6 +11,9 @@ extra-source-files: - CHANGELOG.md - grammar/EO/Phi/Syntax.cf +verbatim: + cabal-version: 1.24 + # Metadata used when publishing your package # synopsis: Short description of your package # category: Web diff --git a/eo-phi-normalizer/src/Language/EO/Phi.hs b/eo-phi-normalizer/src/Language/EO/Phi.hs index a849182c2..b824c217e 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi.hs @@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-} + module Language.EO.Phi ( defaultMain, normalize, @@ -8,22 +9,21 @@ module Language.EO.Phi ( module Language.EO.Phi.Syntax.Abs, ) where - import Data.Char (isSpace) import System.Exit (exitFailure) -import qualified Language.EO.Phi.Syntax.Par as Phi -import qualified Language.EO.Phi.Syntax.Print as Phi import Language.EO.Phi.Syntax.Abs import qualified Language.EO.Phi.Syntax.Abs as Phi +import qualified Language.EO.Phi.Syntax.Par as Phi +import qualified Language.EO.Phi.Syntax.Print as Phi import Language.EO.Phi.Normalize -- | Parse a 'Program' or return a parsing error. parseProgram :: String -> Either String Phi.Program parseProgram input = Phi.pProgram tokens - where - tokens = Phi.myLexer input + where + tokens = Phi.myLexer input -- | Parse a 'Program' from a 'String'. -- May throw an 'error` if input has a syntactical or lexical errors. @@ -38,7 +38,7 @@ unsafeParseProgram input = -- then pretty-prints the result to standard output. defaultMain :: IO () defaultMain = do - input <- getContents -- read entire standard input + input <- getContents -- read entire standard input let tokens = Phi.myLexer input case Phi.pProgram tokens of Left parseError -> do @@ -50,7 +50,7 @@ defaultMain = do -- * Overriding generated pretty-printer -- | Like 'Phi.printTree', but without spaces around dots and no indentation for curly braces. -printTree :: Phi.Print a => a -> String +printTree :: (Phi.Print a) => a -> String printTree = shrinkDots . render . Phi.prt 0 -- | Remove spaces around dots. @@ -59,31 +59,34 @@ printTree = shrinkDots . render . Phi.prt 0 -- a ↦ ξ.a shrinkDots :: String -> String shrinkDots [] = [] -shrinkDots (' ':'.':' ':cs) = '.':shrinkDots cs -shrinkDots (c:cs) = c : shrinkDots cs +shrinkDots (' ' : '.' : ' ' : cs) = '.' : shrinkDots cs +shrinkDots (c : cs) = c : shrinkDots cs -- | Copy of 'Phi.render', except no indentation is made for curly braces. render :: Phi.Doc -> String render d = rend 0 False (map ($ "") $ d []) "" - where - rend - :: Int -- ^ Indentation level. - -> Bool -- ^ Pending indentation to be output before next character? - -> [String] - -> ShowS + where + rend :: + Int -> + -- \^ Indentation level. + Bool -> + -- \^ Pending indentation to be output before next character? + [String] -> + ShowS rend i p = \case - "[" :ts -> char '[' . rend i False ts - "(" :ts -> char '(' . rend i False ts - -- "{" :ts -> onNewLine i p . showChar '{' . new (i+1) ts - -- "}" : ";":ts -> onNewLine (i-1) p . showString "};" . new (i-1) ts - -- "}" :ts -> onNewLine (i-1) p . showChar '}' . new (i-1) ts - [";"] -> char ';' - ";" :ts -> char ';' . new i ts - t : ts@(s:_) | closingOrPunctuation s - -> pending . showString t . rend i False ts - t :ts -> pending . space t . rend i False ts - [] -> id - where + "[" : ts -> char '[' . rend i False ts + "(" : ts -> char '(' . rend i False ts + -- "{" :ts -> onNewLine i p . showChar '{' . new (i+1) ts + -- "}" : ";":ts -> onNewLine (i-1) p . showString "};" . new (i-1) ts + -- "}" :ts -> onNewLine (i-1) p . showChar '}' . new (i-1) ts + [";"] -> char ';' + ";" : ts -> char ';' . new i ts + t : ts@(s : _) + | closingOrPunctuation s -> + pending . showString t . rend i False ts + t : ts -> pending . space t . rend i False ts + [] -> id + where -- Output character after pending indentation. char :: Char -> ShowS char c = pending . showChar c @@ -94,7 +97,7 @@ render d = rend 0 False (map ($ "") $ d []) "" -- Indentation (spaces) for given indentation level. indent :: Int -> ShowS - indent i = Phi.replicateS (2*i) (showChar ' ') + indent i = Phi.replicateS (2 * i) (showChar ' ') -- Continue rendering in new line with new indentation. new :: Int -> [String] -> ShowS @@ -104,16 +107,16 @@ render d = rend 0 False (map ($ "") $ d []) "" space :: String -> ShowS space t s = case (all isSpace t, null spc, null rest) of - (True , _ , True ) -> [] -- remove trailing space - (False, _ , True ) -> t -- remove trailing space - (False, True, False) -> t ++ ' ' : s -- add space if none - _ -> t ++ s - where - (spc, rest) = span isSpace s + (True, _, True) -> [] -- remove trailing space + (False, _, True) -> t -- remove trailing space + (False, True, False) -> t ++ ' ' : s -- add space if none + _ -> t ++ s + where + (spc, rest) = span isSpace s closingOrPunctuation :: String -> Bool closingOrPunctuation [c] = c `elem` closerOrPunct - closingOrPunctuation _ = False + closingOrPunctuation _ = False closerOrPunct :: String closerOrPunct = ")],;" diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Normalize.hs b/eo-phi-normalizer/src/Language/EO/Phi/Normalize.hs index ffeb943be..817a409db 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi/Normalize.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi/Normalize.hs @@ -1,13 +1,14 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} + module Language.EO.Phi.Normalize where -import Language.EO.Phi.Syntax.Abs import Data.Maybe (fromMaybe) +import Language.EO.Phi.Syntax.Abs data Context = Context { globalObject :: [Binding] - , thisObject :: [Binding] + , thisObject :: [Binding] } lookupBinding :: Attribute -> [Binding] -> Maybe Object @@ -20,8 +21,9 @@ lookupBinding _ _ = Nothing -- | Normalize an input 𝜑-program. normalize :: Program -> Program normalize (Program bindings) = Program (map (normalizeBindingWith context) bindings) - where - context = Context + where + context = + Context { globalObject = bindings , thisObject = bindings } @@ -47,8 +49,8 @@ peelObject = \case GlobalDispatch attr -> PeeledObject HeadGlobal [ActionDispatch attr] ThisDispatch attr -> PeeledObject HeadThis [ActionDispatch attr] Termination -> PeeledObject HeadTermination [] - where - followedBy (PeeledObject object actions) action = PeeledObject object (actions ++ [action]) + where + followedBy (PeeledObject object actions) action = PeeledObject object (actions ++ [action]) unpeelObject :: PeeledObject -> Object unpeelObject (PeeledObject head_ actions) = @@ -63,8 +65,8 @@ unpeelObject (PeeledObject head_ actions) = ActionDispatch a : as -> go (ThisDispatch a) as _ -> error "impossible: this object without dispatch!" HeadTermination -> go Termination actions - where - go = foldl applyAction - applyAction object = \case - ActionDispatch attr -> ObjectDispatch object attr - ActionApplication bindings -> Application object bindings + where + go = foldl applyAction + applyAction object = \case + ActionDispatch attr -> ObjectDispatch object attr + ActionApplication bindings -> Application object bindings diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Abs.hs b/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Abs.hs index ae634d48b..4ae129573 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Abs.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Abs.hs @@ -1,52 +1,59 @@ -- File generated by the BNF Converter (bnfc 2.9.5). - {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | The abstract syntax of language Syntax. - module Language.EO.Phi.Syntax.Abs where -import Prelude (String) -import qualified Prelude as C (Eq, Ord, Show, Read) import qualified Data.String +import Prelude (String) +import qualified Prelude as C (Eq, Ord, Read, Show) -import qualified Data.Data as C (Data, Typeable) +import qualified Data.Data as C (Data, Typeable) import qualified GHC.Generics as C (Generic) data Program = Program [Binding] deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data Object - = Formation [Binding] - | Application Object [Binding] - | ObjectDispatch Object Attribute - | GlobalDispatch Attribute - | ThisDispatch Attribute - | Termination + = Formation [Binding] + | Application Object [Binding] + | ObjectDispatch Object Attribute + | GlobalDispatch Attribute + | ThisDispatch Attribute + | Termination deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data Binding - = AlphaBinding Attribute Object - | EmptyBinding Attribute - | DeltaBinding Bytes - | LambdaBinding Function + = AlphaBinding Attribute Object + | EmptyBinding Attribute + | DeltaBinding Bytes + | LambdaBinding Function deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data Attribute - = Phi | Rho | Sigma | VTX | Label LabelId | Alpha AlphaIndex + = Phi + | Rho + | Sigma + | VTX + | Label LabelId + | Alpha AlphaIndex deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data PeeledObject = PeeledObject ObjectHead [ObjectAction] deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data ObjectHead - = HeadFormation [Binding] | HeadGlobal | HeadThis | HeadTermination + = HeadFormation [Binding] + | HeadGlobal + | HeadThis + | HeadTermination deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) data ObjectAction - = ActionApplication [Binding] | ActionDispatch Attribute + = ActionApplication [Binding] + | ActionDispatch Attribute deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) newtype Bytes = Bytes String @@ -60,4 +67,3 @@ newtype LabelId = LabelId String newtype AlphaIndex = AlphaIndex String deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) - diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Print.hs b/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Print.hs index 9156fd24e..835a64076 100644 --- a/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Print.hs +++ b/eo-phi-normalizer/src/Language/EO/Phi/Syntax/Print.hs @@ -1,5 +1,4 @@ -- File generated by the BNF Converter (bnfc 2.9.5). - {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} @@ -8,23 +7,40 @@ #endif -- | Pretty-printer for Language. - module Language.EO.Phi.Syntax.Print where -import Prelude - ( ($), (.) - , Bool(..), (==), (<) - , Int, Integer, Double, (+), (-), (*) - , String, (++) - , ShowS, showChar, showString - , all, elem, foldr, id, map, null, replicate, shows, span - ) -import Data.Char ( Char, isSpace ) +import Data.Char (Char, isSpace) import qualified Language.EO.Phi.Syntax.Abs +import Prelude ( + Bool (..), + Double, + Int, + Integer, + ShowS, + String, + all, + elem, + foldr, + id, + map, + null, + replicate, + showChar, + showString, + shows, + span, + ($), + (*), + (+), + (++), + (-), + (.), + (<), + (==), + ) -- | The top-level printing method. - -printTree :: Print a => a -> String +printTree :: (Print a) => a -> String printTree = render . prt 0 type Doc = [ShowS] -> [ShowS] @@ -34,25 +50,28 @@ doc = (:) render :: Doc -> String render d = rend 0 False (map ($ "") $ d []) "" - where - rend - :: Int -- ^ Indentation level. - -> Bool -- ^ Pending indentation to be output before next character? - -> [String] - -> ShowS + where + rend :: + Int -> + -- \^ Indentation level. + Bool -> + -- \^ Pending indentation to be output before next character? + [String] -> + ShowS rend i p = \case - "[" :ts -> char '[' . rend i False ts - "(" :ts -> char '(' . rend i False ts - "{" :ts -> onNewLine i p . showChar '{' . new (i+1) ts - "}" : ";":ts -> onNewLine (i-1) p . showString "};" . new (i-1) ts - "}" :ts -> onNewLine (i-1) p . showChar '}' . new (i-1) ts - [";"] -> char ';' - ";" :ts -> char ';' . new i ts - t : ts@(s:_) | closingOrPunctuation s - -> pending . showString t . rend i False ts - t :ts -> pending . space t . rend i False ts - [] -> id - where + "[" : ts -> char '[' . rend i False ts + "(" : ts -> char '(' . rend i False ts + "{" : ts -> onNewLine i p . showChar '{' . new (i + 1) ts + "}" : ";" : ts -> onNewLine (i - 1) p . showString "};" . new (i - 1) ts + "}" : ts -> onNewLine (i - 1) p . showChar '}' . new (i - 1) ts + [";"] -> char ';' + ";" : ts -> char ';' . new i ts + t : ts@(s : _) + | closingOrPunctuation s -> + pending . showString t . rend i False ts + t : ts -> pending . space t . rend i False ts + [] -> id + where -- Output character after pending indentation. char :: Char -> ShowS char c = pending . showChar c @@ -63,7 +82,7 @@ render d = rend 0 False (map ($ "") $ d []) "" -- Indentation (spaces) for given indentation level. indent :: Int -> ShowS - indent i = replicateS (2*i) (showChar ' ') + indent i = replicateS (2 * i) (showChar ' ') -- Continue rendering in new line with new indentation. new :: Int -> [String] -> ShowS @@ -77,16 +96,16 @@ render d = rend 0 False (map ($ "") $ d []) "" space :: String -> ShowS space t s = case (all isSpace t, null spc, null rest) of - (True , _ , True ) -> [] -- remove trailing space - (False, _ , True ) -> t -- remove trailing space - (False, True, False) -> t ++ ' ' : s -- add space if none - _ -> t ++ s - where - (spc, rest) = span isSpace s + (True, _, True) -> [] -- remove trailing space + (False, _, True) -> t -- remove trailing space + (False, True, False) -> t ++ ' ' : s -- add space if none + _ -> t ++ s + where + (spc, rest) = span isSpace s closingOrPunctuation :: String -> Bool closingOrPunctuation [c] = c `elem` closerOrPunct - closingOrPunctuation _ = False + closingOrPunctuation _ = False closerOrPunct :: String closerOrPunct = ")],;" @@ -104,11 +123,10 @@ replicateS :: Int -> ShowS -> ShowS replicateS n f = concatS (replicate n f) -- | The printer class does the job. - class Print a where prt :: Int -> a -> Doc -instance {-# OVERLAPPABLE #-} Print a => Print [a] where +instance {-# OVERLAPPABLE #-} (Print a) => Print [a] where prt i = concatD . map (prt i) instance Print Char where @@ -168,7 +186,7 @@ instance Print Language.EO.Phi.Syntax.Abs.Binding where instance Print [Language.EO.Phi.Syntax.Abs.Binding] where prt _ [] = concatD [] prt _ [x] = concatD [prt 0 x] - prt _ (x:xs) = concatD [prt 0 x, doc (showString ","), prt 0 xs] + prt _ (x : xs) = concatD [prt 0 x, doc (showString ","), prt 0 xs] instance Print Language.EO.Phi.Syntax.Abs.Attribute where prt i = \case @@ -197,4 +215,4 @@ instance Print Language.EO.Phi.Syntax.Abs.ObjectAction where instance Print [Language.EO.Phi.Syntax.Abs.ObjectAction] where prt _ [] = concatD [] - prt _ (x:xs) = concatD [prt 0 x, prt 0 xs] + prt _ (x : xs) = concatD [prt 0 x, prt 0 xs] diff --git a/eo-phi-normalizer/test/Language/EO/PhiSpec.hs b/eo-phi-normalizer/test/Language/EO/PhiSpec.hs index 32516b737..195d02d05 100644 --- a/eo-phi-normalizer/test/Language/EO/PhiSpec.hs +++ b/eo-phi-normalizer/test/Language/EO/PhiSpec.hs @@ -1,10 +1,11 @@ {-# LANGUAGE RecordWildCards #-} + module Language.EO.PhiSpec where -import Test.Hspec import Control.Monad (forM_) -import Data.List (dropWhileEnd) import Data.Char (isSpace) +import Data.List (dropWhileEnd) +import Test.Hspec import qualified Language.EO.Phi as Phi import Test.EO.Phi diff --git a/eo-phi-normalizer/test/Test/EO/Phi.hs b/eo-phi-normalizer/test/Test/EO/Phi.hs index 0fa874462..b4f9f16ff 100644 --- a/eo-phi-normalizer/test/Test/EO/Phi.hs +++ b/eo-phi-normalizer/test/Test/EO/Phi.hs @@ -1,26 +1,28 @@ -{-# OPTIONS_GHC -Wno-orphans #-} {-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleInstances #-} +{-# OPTIONS_GHC -Wno-orphans #-} + module Test.EO.Phi where -import Data.Aeson (FromJSON(..)) +import Control.Monad (forM) +import Data.Aeson (FromJSON (..)) import qualified Data.Yaml as Yaml +import GHC.Generics (Generic) import System.Directory (listDirectory) import System.FilePath (()) -import GHC.Generics (Generic) -import Control.Monad (forM) -import qualified Language.EO.Phi as Phi -import Language.EO.Phi (unsafeParseProgram) import Data.List (sort) +import Language.EO.Phi (unsafeParseProgram) +import qualified Language.EO.Phi as Phi data PhiTest = PhiTest - { name :: String - , input :: Phi.Program + { name :: String + , input :: Phi.Program , normalized :: Phi.Program , prettified :: String - } deriving (Generic, FromJSON) + } + deriving (Generic, FromJSON) allPhiTests :: FilePath -> IO [PhiTest] allPhiTests dir = do diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..9669d63dd --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "flakes": { + "locked": { + "lastModified": 1703248027, + "narHash": "sha256-kq2J/wLaUL3KY/OwgZEAZ7/QZ5alrol9ERBWqxJshiA=", + "owner": "deemp", + "repo": "flakes", + "rev": "8b4c8ae507d591ad41e239e70a9c2d226b7eaa45", + "type": "github" + }, + "original": { + "owner": "deemp", + "repo": "flakes", + "type": "github" + } + }, + "root": { + "inputs": { + "flakes": "flakes" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..c4b3fa919 --- /dev/null +++ b/flake.nix @@ -0,0 +1,142 @@ +{ + inputs.flakes.url = "github:deemp/flakes"; + outputs = inputs: inputs.flakes.makeFlake { + inputs = { + inherit (inputs.flakes.all) + haskell-tools codium drv-tools devshell + flakes-tools nixpkgs formatter workflows lima; + }; + perSystem = { inputs, system }: + let + # We're going to make some dev tools for our Haskell package + # The NixOS wiki has more info - https://nixos.wiki/wiki/Haskell + + # --- Imports --- + + pkgs = inputs.nixpkgs.legacyPackages.${system}; + inherit (inputs.devshell.lib.${system}) mkCommands mkRunCommands mkShell; + inherit (inputs.drv-tools.lib.${system}) withAttrs withMan withDescription mkShellApp man; + inherit (inputs.flakes-tools.lib.${system}) mkFlakesTools; + inherit (inputs.haskell-tools.lib.${system}) toolsGHC; + + # --- Parameters --- + + # The desired GHC version + ghcVersion = "963"; + + packageName = "eo-phi-normalizer"; + + # --- Override --- + + # We need to prepare an attrset of Haskell packages and include our packages into it, + # so we define an override - https://nixos.wiki/wiki/Haskell#Overrides. + # We'll supply the necessary dependencies to our packages. + # Sometimes, we need to fix the broken packages - https://gutier.io/post/development-fixing-broken-haskell-packages-nixpkgs/. + # For doing that, we use several helper functions. + # Overriding the packages may trigger multiple rebuilds, + # so we override as few packages as possible. + + inherit (pkgs.haskell.lib) + # override deps of a package + overrideCabal + ; + + # Here's our override + # Haskell overrides are described here: https://nixos.org/manual/nixpkgs/unstable/#haskell + override = { + overrides = self: super: { + "${packageName}" = overrideCabal (super.callCabal2nix packageName ./${packageName} { }) (x: { + librarySystemDepends = [ ] ++ (x.librarySystemDepends or [ ]); + executableSystemDepends = [ ] ++ (x.executableSystemDepends or [ ]); + }); + }; + }; + + # --- Haskell tools --- + + # We call a helper function that will give us tools for Haskell + inherit (toolsGHC { + version = ghcVersion; + inherit override; + + # If we work on multiple packages, we need to supply all of them + # so that their dependencies can be correctrly filtered. + + # Suppose we develop packages A and B, where B is in dependencies of A. + # GHC will be given dependencies of both A and B. + # However, we don't want B to be in the list of dependencies of GHC + # because build of GHC may fail due to errors in B. + packages = ps: [ ps.${packageName} ]; + }) + hls cabal fourmolu justStaticExecutable + ghcid haskellPackages hpack stack; + + # --- Tools --- + + # We list the tools that we'd like to use + tools = [ + ghcid + hpack + fourmolu + cabal + stack + # `cabal` already has a `ghc` on its `PATH`, + # so you may remove `ghc` from this list. + # Then, you can access `ghc` like `cabal exec -- ghc --version`. + + # However, sometimes, HLS wants a GHC. + # In this case, write it before `HLS` - see https://github.com/NixOS/nixpkgs/issues/225895 + # ghc + + hls + ]; + + # --- Packages --- + + packages = { + # --- Haskell package --- + + # This is a static executable with given runtime dependencies. + # In this case, its name is the same as the package name. + default = justStaticExecutable { + package = haskellPackages.${packageName}; + description = "A Haskell `hello-world` script"; + }; + + "${packageName}" = haskellPackages."${packageName}"; + }; + + # --- Devshells --- + + devShells = { + default = mkShell { + packages = tools; + # sometimes necessary for programs that work with files + bash.extra = "export LANG=C.utf8"; + commands = + mkCommands "tools" tools + ++ mkRunCommands "packages" { inherit (packages) default; } + ; + }; + }; + + in + { + inherit packages devShells; + formatter = inputs.formatter.${system}; + }; + }; + + nixConfig = { + extra-substituters = [ + "https://nix-community.cachix.org" + "https://cache.iog.io" + "https://deemp.cachix.org" + ]; + extra-trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" + "deemp.cachix.org-1:9shDxyR2ANqEPQEEYDL/xIOnoPwxHot21L5fiZnFL18=" + ]; + }; +} diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 000000000..72654acf9 --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,51 @@ +# Number of spaces per indentation step +indentation: 2 + +# Max line length for automatic line breaking +column-limit: none + +# Styling of arrows in type signatures (choices: trailing, leading, or leading-args) +function-arrows: trailing + +# How to place commas in multi-line lists, records, etc. (choices: leading or trailing) +comma-style: leading + +# Styling of import/export lists (choices: leading, trailing, or diff-friendly) +import-export-style: diff-friendly + +# Whether to full-indent or half-indent 'where' bindings past the preceding body +indent-wheres: false + +# Whether to leave a space before an opening record brace +record-brace-space: false + +# Number of spaces between top-level declarations +newlines-between-decls: 1 + +# How to print Haddock comments (choices: single-line, multi-line, or multi-line-compact) +haddock-style: single-line + +# How to print module docstring +haddock-style-module: null + +# Styling of let blocks (choices: auto, inline, newline, or mixed) +let-style: auto + +# How to align the 'in' keyword with respect to the 'let' keyword (choices: left-align, right-align, or no-space) +in-style: right-align + +# Whether to put parentheses around a single constraint (choices: auto, always, or never) +single-constraint-parens: always + +# Output Unicode syntax (choices: detect, always, or never) +unicode: never + +# Give the programmer more choice on where to insert blank lines +respectful: true + +# Fixity information for operators +fixities: [] + +# Module reexports Fourmolu should know about +reexports: [] +