Skip to content

Commit

Permalink
Link to GHC syntax from Cabal Package syntax
Browse files Browse the repository at this point in the history
- Split and rename the syntax
- Remove most GHC grammar except language
- Remove test-suite fields from GHC syntax
- Remove package description fields from GHC syntax
- Remove build info fields from GHC syntax
- Get rid of hs-string, put disable-extension first
-

Remove everything but language extensions

-
- Combine recipes with doc/%-syntax.rst pattern rules
- Make syntax its own section
- Partition build info fields
- Add lib to Cabal-syntax-docs
- Add GHC build info fields to ghc-syntax
- Show ghc-syntax as a list of links
- Update make recipe for build info and user guide
  • Loading branch information
philderbeast committed Jan 5, 2024
1 parent 84e1045 commit aa152cb
Show file tree
Hide file tree
Showing 14 changed files with 855 additions and 547 deletions.
6 changes: 5 additions & 1 deletion Cabal-described/src/Distribution/Described/Extension.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Distribution.Described.Extension
( reKnownExtension
( reEnableExtension
, reKnownExtension
, reDisableExtension
, reXs
-- * Extension groups
Expand Down Expand Up @@ -44,6 +45,9 @@ instance Described Extension where
reXs :: [KnownExtension] -> GrammarRegex a
reXs xs = REUnion (fromString . prettyShow <$> xs)

reEnableExtension :: GrammarRegex a
reEnableExtension = "enable-extension"

reKnownExtension :: GrammarRegex a
reKnownExtension = REUnion
[ RENamed "interactive-extension" $ reXs xGroupInteractive
Expand Down
44 changes: 44 additions & 0 deletions Cabal-syntax-docs/Cabal-syntax-docs.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
cabal-version: 2.2
name: Cabal-syntax-docs
version: 0

library
default-language: Haskell2010
hs-source-dirs: src
ghc-options: -Wall
build-depends:
, base >=4.11 && <4.20
, Cabal
, Cabal-described
, containers
, pretty
, zinza ^>=0.2
exposed-modules: Cabal.Syntax.Docs.ZFields

executable gen-cabal-package-syntax-docs
default-language: Haskell2010
hs-source-dirs: cabal-package
ghc-options: -Wall
main-is: Main.hs
build-depends:
, base >=4.11 && <4.20
, Cabal
, Cabal-described
, Cabal-syntax-docs
, containers
, pretty
, zinza ^>=0.2

executable gen-ghc-syntax-docs
default-language: Haskell2010
hs-source-dirs: ghc
ghc-options: -Wall
main-is: Main.hs
build-depends:
, base >=4.11 && <4.20
, Cabal
, Cabal-described
, Cabal-syntax-docs
, containers
, pretty
, zinza ^>=0.2
84 changes: 84 additions & 0 deletions Cabal-syntax-docs/cabal-package/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{-# LANGUAGE DeriveGeneric #-}
module Main (main) where

import Data.List (partition)
import Data.Proxy (Proxy (..))
import GHC.Generics (Generic)
import System.Environment (getArgs)
import System.Exit (exitFailure)

import Distribution.PackageDescription.FieldGrammar (buildInfoFieldGrammar, packageDescriptionFieldGrammar, testSuiteFieldGrammar)

import qualified Zinza as Z

import Distribution.Described
import Distribution.Described.Extension ()
import Distribution.Utils.GrammarRegex

import Distribution.ModuleName (ModuleName)
import Distribution.Types.Version (Version)
import Distribution.Types.VersionRange (VersionRange)
import Cabal.Syntax.Docs.ZFields

main :: IO ()
main = do
args <- getArgs
case args of
[tmpl] -> do
let (biGhc, biCabal) = partition isGhcBuildInfo $ fromReference buildInfoFieldGrammar
run <- Z.parseAndCompileTemplateIO tmpl
contents <- run $ Z
{ zGhcBuildInfoFields = biGhc
, zCabalBuildInfoFields = biCabal
, zPackageDescriptionFields = fromReference packageDescriptionFieldGrammar
, zTestSuiteFields = fromReference $ testSuiteFieldGrammar // buildInfoFieldGrammar
, zProductions =
[ zproduction "hs-string" reHsString
"String as in Haskell; it's recommended to avoid using Haskell-specific escapes."
, zproduction "unqual-name" reUnqualComponent $ unwords
[ "Unqualified component names are used for package names, component names etc. but not flag names."
, "Unqualified component name consist of components separated by dash, each component is non-empty alphanumeric string, with at least one alphabetic character."
, "In other words, component may not look like a number."
]

, zproduction "module-name" (describe (Proxy :: Proxy ModuleName))
"Haskell module name as recognized by Cabal parser."
, zproduction "version" (describe (Proxy :: Proxy Version))
"Version is to first approximation numbers separated by dots, where leading zero is not allowed and each version digit is consists at most of nine characters."
, zproduction "version-range" (describe (Proxy :: Proxy VersionRange))
"Version range syntax is recursive. Also note the set syntax added in ``cabal-version: 3.0``, set cannot be empty."
]
, zSpaceList = show $ regexDoc $
REMunch RESpaces1 (RENamed "element" RETodo)
, zCommaList = show $ regexDoc $
expandedCommaList (RENamed "element" RETodo)
, zOptCommaList = show $ regexDoc $
expandedOptCommaList (RENamed "element" RETodo)

, zNull = null
, zNotNull = not . null
}

putStrLn contents
_ -> do
putStrLn "Usage: generator <tmpl>"
exitFailure

data Z = Z
{ zGhcBuildInfoFields :: [ZField]
, zCabalBuildInfoFields :: [ZField]
, zPackageDescriptionFields :: [ZField]
, zTestSuiteFields :: [ZField]
, zProductions :: [ZProduction]
, zSpaceList :: String
, zCommaList :: String
, zOptCommaList :: String
, zNull :: String -> Bool
, zNotNull :: String -> Bool
}
deriving (Generic)

instance Z.Zinza Z where
toType = Z.genericToTypeSFP
toValue = Z.genericToValueSFP
fromValue = Z.genericFromValueSFP
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
.. _buildinfo-field-reference:
.. _cabal-package-syntax:

Field Syntax Reference
======================
Cabal Package Syntax
====================

GHC syntax
----------

Some elements of cabal package syntax are controlled by GHC. As such these are
effectively strings passed on to GHC and that may be as far as Cabal will check
their syntax. See the :ref:`ghc-syntax` for these elements of GHC syntax
embedded within cabal package descriptions.

- :ref:`ghc-enable-extension`
- :ref:`ghc-disable-extension`
{% for field in ghcBuildInfoFields %}
- :ref:`{{field.name}}<ghc-{{field.name}}>`
{% endfor %}

Notation
---------------
--------

Field syntax is described as they are in the latest cabal file format version.

Expand Down Expand Up @@ -142,7 +156,7 @@ In the syntax definitions below the following non-terminal symbols are used:
Build info fields
-----------------

{% for field in buildInfoFields %}
{% for field in cabalBuildInfoFields %}
{{ field.name }}
* {{field.format}}
{% if notNull field.default %}
Expand Down
106 changes: 106 additions & 0 deletions Cabal-syntax-docs/ghc/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{-# LANGUAGE DeriveGeneric #-}
module Main (main) where

import GHC.Generics (Generic)
import System.Environment (getArgs)
import System.Exit (exitFailure)

import Distribution.PackageDescription.FieldGrammar (buildInfoFieldGrammar)

import qualified Zinza as Z

import Distribution.Described
import Distribution.Described.Extension
import Distribution.Utils.GrammarRegex
import Cabal.Syntax.Docs.ZFields

main :: IO ()
main = do
args <- getArgs
case args of
[tmpl] -> do
let biGhc = filter isGhcBuildInfo $ fromReference buildInfoFieldGrammar
run <- Z.parseAndCompileTemplateIO tmpl
contents <- run $ Z
{ zGhcBuildInfoFields = biGhc
, zProductions =
[ zproduction "disable-extension" reDisableExtension
"Disable a language extension by prepending the extension with \"No\"."
, zproduction "enable-extension" reKnownExtension
"All GHC language extensions known to cabal. There may be more and some of these may be on by default."
, zproduction "interactive-extension" (reXs xGroupInteractive)
"Language Extensions related to GHC interactive."
, zproduction "phase-extension" (reXs xGroupPhase)
"Language Extensions related to a particular GHC phase."
, zproduction "syntax-extension" (reXs xGroupSyntax)
"Syntax Language Extensions."
, zproduction "import-export-extension" (reXs xGroupImportExport)
"Import and Export Language Extensions."
, zproduction "type-extension" (reXs xGroupTypes)
"Language Extensions for Types."
, zproduction "record-extension" (reXs xGroupRecords)
"Record Language Extensions."
, zproduction "deriving-extension" (reXs xGroupDeriving)
"Language Extensions for deriving mechanisms."
, zproduction "pattern-extension" (reXs xGroupPatterns)
"Patterns Language Extensions."
, zproduction "classes-instances-extension" (reXs xGroupClassesInstances)
"Language Extensions for class and instance declarations."
, zproduction "literal-extension" (reXs xGroupLiterals)
"Literals Language Extensions."
, zproduction "constraint-extension" (reXs xGroupConstraints)
"Constraint Language Extensions."
, zproduction "type-signature-extension" (reXs xGroupTypeSignatures)
"Type Signature Language Extensions."
, zproduction "binding-generalisation-extension" (reXs xGroupBindingsGeneralisation)
"Language Extensions for bindings and generalisation "
, zproduction "template-haskell-extension" (reXs xGroupTemplates)
"Template Haskell Language Extensions."
, zproduction "bang-strict-extension" (reXs xGroupBangStrict)
"Bang pattern and Strict Haskell Language Extensions."
, zproduction "parallel-concurrent-extension" (reXs xGroupParallelConcurrent)
"Parallel and Concurrent Language Extensions."
, zproduction "unboxed-primitive-extension" (reXs xGroupUnboxedPrimitive)
"Unboxed types and Primitive operations Language Extensions."
, zproduction "foreign-extension" (reXs xGroupForeign)
"Foreign function interface (FFI) Language Extensions."
, zproduction "safe-extension" (reXs xGroupSafe)
"Safe Haskell Language Extensions."
, zproduction "miscellaneous-extension" (reXs xGroupMiscellaneous)
"Miscellaneous Language Extensions."
, zproduction "bugs-extension" (reXs xGroupBugs)
"Language Extensions related to GHC bugs and infelicities."
, zproduction "ungrouped-extension" (reXs xUngrouped)
"Language Extensions not belonging to other extension groups, includes undocumented extensions."
]
, zSpaceList = show $ regexDoc $
REMunch RESpaces1 (RENamed "element" RETodo)
, zCommaList = show $ regexDoc $
expandedCommaList (RENamed "element" RETodo)
, zOptCommaList = show $ regexDoc $
expandedOptCommaList (RENamed "element" RETodo)

, zNull = null
, zNotNull = not . null
}

putStrLn contents
_ -> do
putStrLn "Usage: generator <tmpl>"
exitFailure

data Z = Z
{ zGhcBuildInfoFields :: [ZField]
, zProductions :: [ZProduction]
, zSpaceList :: String
, zCommaList :: String
, zOptCommaList :: String
, zNull :: String -> Bool
, zNotNull :: String -> Bool
}
deriving (Generic)

instance Z.Zinza Z where
toType = Z.genericToTypeSFP
toValue = Z.genericToValueSFP
fromValue = Z.genericFromValueSFP
63 changes: 63 additions & 0 deletions Cabal-syntax-docs/ghc/template.zinza
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.. _ghc-syntax:

GHC Syntax Reference
====================

Language Extensions
-------------------

The many GHC language extensions are divided into groups of extensions
corresponding to subsections of the GHC users' guide on language extensions.
Those of the :ref:`ungrouped-extension <ghc-ungrouped-extension>` group are
undocumented in the GHC users' guide.

{% for production in productions %}
.. _ghc-{{ production.name }}:

{{ production.name }}
{{ production.description }}

.. math::

{{ production.syntax }}

{% endfor %}

GHC build info fields
---------------------

These are cabal package build info fields that are more related to GHC, the
Haskell compiler, than they are to Cabal.

{% for field in ghcBuildInfoFields %}
.. _ghc-{{ field.name }}:

{{ field.name }}
* {{field.format}}
{% if notNull field.default %}
* Default: ``{{field.default}}``
{% endif %}
{% if notNull field.availableSince %}
* Available since ``cabal-version: {{field.availableSince}}``.
{% endif %}
{% if notNull field.deprecatedSince.fst %}
* Deprecated since ``cabal-version: {{field.deprecatedSince.fst}}``: {{field.deprecatedSince.snd}}
{% endif %}
{% if notNull field.removedIn.fst %}
* Removed in ``cabal-version: {{field.removedIn.fst}}``: {{field.removedIn.snd}}
{% endif %}
{# We show documentation link only for non deprecated fields #}
{% if null field.deprecatedSince.fst %}
{% if null field.removedIn.fst %}
* Documentation of :pkg-field:`library:{{field.name}}`
{% endif %}
{% endif %}
{% if notNull field.syntax %}

.. math::

{{field.syntax}}
{% endif %}

{% endfor %}

Loading

0 comments on commit aa152cb

Please sign in to comment.