diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml new file mode 100644 index 0000000..5438079 --- /dev/null +++ b/.github/workflows/haskell-ci.yml @@ -0,0 +1,269 @@ +# This GitHub workflow config has been generated by a script via +# +# haskell-ci 'github' 'cabal.project' +# +# To regenerate the script (for example after adjusting tested-with) run +# +# haskell-ci regenerate +# +# For more information, see https://github.com/haskell-CI/haskell-ci +# +# version: 0.15.20230321 +# +# REGENDATA ("0.15.20230321",["github","cabal.project"]) +# +name: Haskell-CI +on: + push: + branches: + - master + - ci-* + pull_request: + branches: + - master + - ci-* +jobs: + linux: + name: Haskell-CI - Linux - ${{ matrix.compiler }} + runs-on: ubuntu-20.04 + timeout-minutes: + 60 + container: + image: buildpack-deps:bionic + continue-on-error: ${{ matrix.allow-failure }} + strategy: + matrix: + include: + - compiler: ghc-9.6.1 + compilerKind: ghc + compilerVersion: 9.6.1 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.4.4 + compilerKind: ghc + compilerVersion: 9.4.4 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.2.7 + compilerKind: ghc + compilerVersion: 9.2.7 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.0.2 + compilerKind: ghc + compilerVersion: 9.0.2 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.10.7 + compilerKind: ghc + compilerVersion: 8.10.7 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.8.4 + compilerKind: ghc + compilerVersion: 8.8.4 + setup-method: hvr-ppa + allow-failure: false + - compiler: ghc-8.6.5 + compilerKind: ghc + compilerVersion: 8.6.5 + setup-method: hvr-ppa + allow-failure: false + - compiler: ghc-8.4.4 + compilerKind: ghc + compilerVersion: 8.4.4 + setup-method: hvr-ppa + allow-failure: false + - compiler: ghc-8.2.2 + compilerKind: ghc + compilerVersion: 8.2.2 + setup-method: hvr-ppa + allow-failure: false + - compiler: ghc-8.0.2 + compilerKind: ghc + compilerVersion: 8.0.2 + setup-method: hvr-ppa + allow-failure: false + - compiler: ghc-7.10.3 + compilerKind: ghc + compilerVersion: 7.10.3 + setup-method: hvr-ppa + allow-failure: false + fail-fast: false + steps: + - name: apt + run: | + apt-get update + apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 + if [ "${{ matrix.setup-method }}" = ghcup ]; then + mkdir -p "$HOME/.ghcup/bin" + curl -sL https://downloads.haskell.org/ghcup/0.1.19.2/x86_64-linux-ghcup-0.1.19.2 > "$HOME/.ghcup/bin/ghcup" + chmod a+x "$HOME/.ghcup/bin/ghcup" + "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) + "$HOME/.ghcup/bin/ghcup" install cabal 3.10.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + else + apt-add-repository -y 'ppa:hvr/ghc' + apt-get update + apt-get install -y "$HCNAME" + mkdir -p "$HOME/.ghcup/bin" + curl -sL https://downloads.haskell.org/ghcup/0.1.19.2/x86_64-linux-ghcup-0.1.19.2 > "$HOME/.ghcup/bin/ghcup" + chmod a+x "$HOME/.ghcup/bin/ghcup" + "$HOME/.ghcup/bin/ghcup" install cabal 3.10.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + fi + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: Set PATH and environment variables + run: | + echo "$HOME/.cabal/bin" >> $GITHUB_PATH + echo "LANG=C.UTF-8" >> "$GITHUB_ENV" + echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV" + echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV" + HCDIR=/opt/$HCKIND/$HCVER + if [ "${{ matrix.setup-method }}" = ghcup ]; then + HC=$HOME/.ghcup/bin/$HCKIND-$HCVER + echo "HC=$HC" >> "$GITHUB_ENV" + echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV" + echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV" + echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.1.0 -vnormal+nowrap" >> "$GITHUB_ENV" + else + HC=$HCDIR/bin/$HCKIND + echo "HC=$HC" >> "$GITHUB_ENV" + echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV" + echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV" + echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.1.0 -vnormal+nowrap" >> "$GITHUB_ENV" + fi + + HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') + echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" + echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" + echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" + echo "HEADHACKAGE=false" >> "$GITHUB_ENV" + echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" + echo "GHCJSARITH=0" >> "$GITHUB_ENV" + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: env + run: | + env + - name: write cabal config + run: | + mkdir -p $CABAL_DIR + cat >> $CABAL_CONFIG <> $CABAL_CONFIG < cabal-plan.xz + echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c - + xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan + rm -f cabal-plan.xz + chmod a+x $HOME/.cabal/bin/cabal-plan + cabal-plan --version + - name: checkout + uses: actions/checkout@v3 + with: + path: source + - name: initial cabal.project for sdist + run: | + touch cabal.project + echo "packages: $GITHUB_WORKSPACE/source/language-python" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/language-python-test" >> cabal.project + cat cabal.project + - name: sdist + run: | + mkdir -p sdist + $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist + - name: unpack + run: | + mkdir -p unpacked + find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \; + - name: generate cabal.project + run: | + PKGDIR_language_python="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/language-python-[0-9.]*')" + echo "PKGDIR_language_python=${PKGDIR_language_python}" >> "$GITHUB_ENV" + PKGDIR_language_python_test="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/language-python-test-[0-9.]*')" + echo "PKGDIR_language_python_test=${PKGDIR_language_python_test}" >> "$GITHUB_ENV" + rm -f cabal.project cabal.project.local + touch cabal.project + touch cabal.project.local + echo "packages: ${PKGDIR_language_python}" >> cabal.project + echo "packages: ${PKGDIR_language_python_test}" >> cabal.project + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package language-python" >> cabal.project ; fi + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package language-python-test" >> cabal.project ; fi + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi + cat >> cabal.project <> cabal.project.local + cat cabal.project + cat cabal.project.local + - name: dump install plan + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all + cabal-plan + - name: restore cache + uses: actions/cache/restore@v3 + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store + restore-keys: ${{ runner.os }}-${{ matrix.compiler }}- + - name: install dependencies + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all + - name: build w/o tests + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: build + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always + - name: cabal check + run: | + cd ${PKGDIR_language_python} || false + ${CABAL} -vnormal check + cd ${PKGDIR_language_python_test} || false + ${CABAL} -vnormal check + - name: haddock + run: | + $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all + - name: unconstrained build + run: | + rm -f cabal.project.local + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: save cache + uses: actions/cache/save@v3 + if: always() + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store diff --git a/README.md b/README.md index c9f093f..c67046f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ Introduction A lexer, parser and pretty printing library for Python 2 and 3. +Intended use case +----------------- + +Generally speaking this library was written with the intention of parsing Python for the purposes of program transformation and compilation. It can also be used for Python code generation, but that is not the primary goal. As a consequence the "Abstract Syntax Tree" is not particularly abstract, and might be better described as a "Concrete Syntax Tree". + License ------- @@ -23,6 +28,7 @@ Testing Test cases are provided in a language-python-test. Test binaries can be built and run as below (cabal version 3.0.0.0 onwards): ``` +cabal install shelltestrunner cabal install --overwrite-policy=always language-python-test cd language-python-test/ PATH=$HOME/.cabal/bin/:$PATH make test @@ -31,9 +37,9 @@ PATH=$HOME/.cabal/bin/:$PATH make test If all goes well you should see a long list of test cases and a summary at the end, that should look like the following: ``` Test Cases Total - Passed 517 517 + Passed 519 519 Failed 0 0 - Total 517 517 + Total 519 519 ``` Pull requests diff --git a/cabal.haskell-ci b/cabal.haskell-ci new file mode 100644 index 0000000..1dc307a --- /dev/null +++ b/cabal.haskell-ci @@ -0,0 +1,4 @@ +branches: master ci-* + +-- monads-tf does not like transformers-0.6 +installed: +all -transformers -mtl \ No newline at end of file diff --git a/language-python-test/language-python-test.cabal b/language-python-test/language-python-test.cabal index ea20cef..10d9c59 100644 --- a/language-python-test/language-python-test.cabal +++ b/language-python-test/language-python-test.cabal @@ -1,8 +1,8 @@ name: language-python-test -version: 0.5.8 -cabal-version: >= 1.6 +version: 0.6.0 +cabal-version: >= 1.8 synopsis: testing code for the language-python library -description: testing code for the language-python library +description: A few executables to test the language-python library. category: Language license: BSD3 license-file: LICENSE @@ -13,6 +13,19 @@ homepage: http://github.com/bjpop/language-python-test build-type: Simple stability: experimental +tested-with: + GHC == 9.6.1 + GHC == 9.4.4 + GHC == 9.2.7 + GHC == 9.0.2 + GHC == 8.10.7 + GHC == 8.8.4 + GHC == 8.6.5 + GHC == 8.4.4 + GHC == 8.2.2 + GHC == 8.0.2 + GHC == 7.10.3 + source-repository head type: git location: https://github.com/bjpop/language-python-test @@ -22,18 +35,18 @@ Executable language-python-roundtrip ./src main-is: RoundTrip.hs other-modules: - build-depends: base == 4.*, language-python == 0.5.8 + build-depends: base == 4.*, language-python == 0.6.0 Executable language-python-tokens hs-source-dirs: ./src main-is: Tokens.hs other-modules: - build-depends: base == 4.*, language-python == 0.5.8 + build-depends: base == 4.*, language-python == 0.6.0 Executable language-python-parse-pretty hs-source-dirs: ./src main-is: ParsePretty.hs other-modules: - build-depends: base == 4.*, language-python == 0.5.8 + build-depends: base == 4.*, language-python == 0.6.0 diff --git a/language-python-test/src/RoundTrip.hs b/language-python-test/src/RoundTrip.hs index 88f23be..bbc8546 100644 --- a/language-python-test/src/RoundTrip.hs +++ b/language-python-test/src/RoundTrip.hs @@ -27,7 +27,7 @@ main = do if test then exitWith ExitSuccess else exitSuccess _other -> putStrLn "Incorrect command line. Expected: <2|3|n> inputFileName" -check :: [Comparison] -> IO Bool +check :: [Comparison] -> IO Bool check [] = return True -- must have all been equal check (Equal:rest) = check rest check (NotEqual s1 s2:_rest) = do diff --git a/language-python-test/test/features/floats/underscores.py b/language-python-test/test/features/floats/underscores.py new file mode 100644 index 0000000..915db7d --- /dev/null +++ b/language-python-test/test/features/floats/underscores.py @@ -0,0 +1,2 @@ +1_0.0_3 +-1_0.0_3 diff --git a/language-python-test/test/features/floats/underscores.test b/language-python-test/test/features/floats/underscores.test new file mode 100644 index 0000000..6056d84 --- /dev/null +++ b/language-python-test/test/features/floats/underscores.test @@ -0,0 +1,5 @@ +language-python-roundtrip 3 underscores.py +<<< +>>> +>>>2 +>>>=0 diff --git a/language-python-test/test/features/integers/underscores.py b/language-python-test/test/features/integers/underscores.py new file mode 100644 index 0000000..21eb6b8 --- /dev/null +++ b/language-python-test/test/features/integers/underscores.py @@ -0,0 +1,2 @@ +1_000 +-1_000 diff --git a/language-python-test/test/features/integers/underscores.test b/language-python-test/test/features/integers/underscores.test new file mode 100644 index 0000000..6056d84 --- /dev/null +++ b/language-python-test/test/features/integers/underscores.test @@ -0,0 +1,5 @@ +language-python-roundtrip 3 underscores.py +<<< +>>> +>>>2 +>>>=0 diff --git a/language-python/Changelog.md b/language-python/Changelog.md new file mode 100644 index 0000000..bf6fc68 --- /dev/null +++ b/language-python/Changelog.md @@ -0,0 +1,3 @@ +0.6 + +* add Foldable, Traversable instances to Common.AST types diff --git a/language-python/language-python.cabal b/language-python/language-python.cabal index 72d7409..1ecde97 100644 --- a/language-python/language-python.cabal +++ b/language-python/language-python.cabal @@ -1,37 +1,46 @@ name: language-python -version: 0.5.8 -cabal-version: >= 1.6 -synopsis: Parsing and pretty printing of Python code. -description: language-python is a Haskell library for lexical analysis, parsing - and pretty printing Python code. It supports versions 2.x and 3.x of Python. +version: 0.6.0 +cabal-version: >= 1.8 +synopsis: Parsing and pretty printing of Python code. +description: language-python is a Haskell library for lexical analysis, parsing + and pretty printing Python code. It supports versions 2.x and 3.x of Python. category: Language license: BSD3 license-file: LICENSE copyright: (c) 2008-2019 Bernard James Pope author: Bernard James Pope (Bernie Pope) maintainer: florbitous@gmail.com -homepage: http://github.com/bjpop/language-python +homepage: http://github.com/bjpop/language-python build-type: Simple stability: experimental -extra-source-files: src/Language/Python/Version3/Parser/Parser.y - src/Language/Python/Version3/Parser/Lexer.x - src/Language/Python/Version2/Parser/Parser.y - src/Language/Python/Version2/Parser/Lexer.x -tested-with: GHC ==7.8.4, GHC ==7.10.3, GHC ==8.0.2, GHC ==8.2.1, GHC ==8.6.3 +extra-source-files: Changelog.md + +tested-with: + GHC == 9.6.1 + GHC == 9.4.4 + GHC == 9.2.7 + GHC == 9.0.2 + GHC == 8.10.7 + GHC == 8.8.4 + GHC == 8.6.5 + GHC == 8.4.4 + GHC == 8.2.2 + GHC == 8.0.2 + GHC == 7.10.3 source-repository head type: git location: https://github.com/bjpop/language-python Library - hs-source-dirs: src + hs-source-dirs: src ghc-options: -fwarn-incomplete-patterns -fwarn-unused-imports -fwarn-warnings-deprecations build-depends: - base == 4.*, + base >= 4.8 && < 5, containers >= 0.5 && < 0.7, pretty == 1.1.*, array >= 0.4 && < 0.6, - transformers >= 0.3 && < 0.6, + transformers >= 0.3 && < 0.7, monads-tf == 0.1.*, utf8-string >= 1 && < 2 build-tools: happy, alex diff --git a/language-python/src/Language/Python/Common/AST.hs b/language-python/src/Language/Python/Common/AST.hs index 1f4129c..5ccc64a 100644 --- a/language-python/src/Language/Python/Common/AST.hs +++ b/language-python/src/Language/Python/Common/AST.hs @@ -1,15 +1,17 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE FlexibleInstances, TypeSynonymInstances, CPP, DeriveDataTypeable, DeriveFunctor #-} ----------------------------------------------------------------------------- -- | --- Module : Language.Python.Version2.Syntax.AST --- Copyright : (c) 2009 Bernie Pope +-- Module : Language.Python.Version2.Syntax.AST +-- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Maintainer : bjpop@csse.unimelb.edu.au -- Stability : experimental -- Portability : ghc -- -- Representation of the Python abstract syntax tree (AST). The representation is --- a superset of versions 2.x and 3.x of Python. In many cases they are +-- a superset of versions 2.x and 3.x of Python. In many cases they are -- identical. The documentation in this module indicates where they are -- different. -- @@ -21,10 +23,10 @@ -- -- Note: there are cases where the AST is more liberal than the formal grammar -- of the language. Therefore some care must be taken when constructing --- Python programs using the raw AST. +-- Python programs using the raw AST. ----------------------------------------------------------------------------- -module Language.Python.Common.AST ( +module Language.Python.Common.AST ( -- * Annotation projection Annotated (..) -- * Modules @@ -64,136 +66,136 @@ module Language.Python.Common.AST ( ) where -import Language.Python.Common.SrcLocation ( Span (getSpan), SrcSpan (..), spanning ) +import Language.Python.Common.SrcLocation ( Span (getSpan), SrcSpan (..), spanning ) import Data.Data -------------------------------------------------------------------------------- --- | Convenient access to annotations in annotated types. +-- | Convenient access to annotations in annotated types. class Annotated t where -- | Given an annotated type, project out its annotation value. annot :: t annot -> annot -- | Identifier. data Ident annot = Ident { ident_string :: !String, ident_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor, Foldable, Traversable) type IdentSpan = Ident SrcSpan instance Span IdentSpan where - getSpan = annot + getSpan = annot instance Annotated Ident where annot = ident_annot --- | A module (Python source file). +-- | A module (Python source file). -- -- * Version 2.6 --- --- * Version 3.1 --- +-- +-- * Version 3.1 +-- newtype Module annot = Module [Statement annot] -- ^ A module is just a sequence of top-level statements. - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ModuleSpan = Module SrcSpan --- | A block of statements. A suite is a group of statements controlled by a clause, --- for example, the body of a loop. +-- | A block of statements. A suite is a group of statements controlled by a clause, +-- for example, the body of a loop. -- -- * Version 2.6 --- +-- -- * Version 3.1 -- -type Suite annot = [Statement annot] +type Suite annot = [Statement annot] type SuiteSpan = Suite SrcSpan -- | A compound name constructed with the dot operator. type DottedName annot = [Ident annot] -type DottedNameSpan = DottedName SrcSpan +type DottedNameSpan = DottedName SrcSpan -- | An entity imported using the \'import\' keyword. --- +-- -- * Version 2.6 -- --- * Version 3.1 +-- * Version 3.1 -- -data ImportItem annot = - ImportItem +data ImportItem annot = + ImportItem { import_item_name :: DottedName annot -- ^ The name of module to import. - , import_as_name :: Maybe (Ident annot) -- ^ An optional name to refer to the entity (the \'as\' name). + , import_as_name :: Maybe (Ident annot) -- ^ An optional name to refer to the entity (the \'as\' name). , import_item_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ImportItemSpan = ImportItem SrcSpan instance Span ImportItemSpan where - getSpan = annot + getSpan = annot instance Annotated ImportItem where - annot = import_item_annot + annot = import_item_annot -- | An entity imported using the \'from ... import\' construct. -- -- * Version 2.6 --- +-- -- * Version 3.1 -- -data FromItem annot = - FromItem - { from_item_name :: Ident annot -- ^ The name of the entity imported. +data FromItem annot = + FromItem + { from_item_name :: Ident annot -- ^ The name of the entity imported. , from_as_name :: Maybe (Ident annot) -- ^ An optional name to refer to the entity (the \'as\' name). , from_item_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type FromItemSpan = FromItem SrcSpan instance Span FromItemSpan where - getSpan = annot + getSpan = annot instance Annotated FromItem where - annot = from_item_annot + annot = from_item_annot -- | Items imported using the \'from ... import\' construct. -data FromItems annot +data FromItems annot = ImportEverything { from_items_annot :: annot } -- ^ Import everything exported from the module. | FromItems { from_items_items :: [FromItem annot], from_items_annot :: annot } -- ^ Import a specific list of items from the module. - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type FromItemsSpan = FromItems SrcSpan instance Span FromItemsSpan where - getSpan = annot + getSpan = annot instance Annotated FromItems where - annot = from_items_annot + annot = from_items_annot -- | A reference to the module to import from using the \'from ... import\' construct. -data ImportRelative annot - = ImportRelative +data ImportRelative annot + = ImportRelative { import_relative_dots :: Int - , import_relative_module :: Maybe (DottedName annot) - , import_relative_annot :: annot + , import_relative_module :: Maybe (DottedName annot) + , import_relative_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ImportRelativeSpan = ImportRelative SrcSpan instance Span ImportRelativeSpan where - getSpan = annot + getSpan = annot instance Annotated ImportRelative where - annot = import_relative_annot + annot = import_relative_annot -- | Statements. -- -- * Simple statements: -- -- * Version 2.6 --- +-- -- * Version 3.1 -- -- * Compound statements: @@ -202,29 +204,29 @@ instance Annotated ImportRelative where -- -- * Version 3.1 -- -data Statement annot +data Statement annot -- | Import statement. - = Import + = Import { import_items :: [ImportItem annot] -- ^ Items to import. - , stmt_annot :: annot - } + , stmt_annot :: annot + } -- | From ... import statement. - | FromImport + | FromImport { from_module :: ImportRelative annot -- ^ Module to import from. , from_items :: FromItems annot -- ^ Items to import. , stmt_annot :: annot } - -- | While loop. - | While + -- | While loop. + | While { while_cond :: Expr annot -- ^ Loop condition. , while_body :: Suite annot -- ^ Loop body. , while_else :: Suite annot -- ^ Else clause. , stmt_annot :: annot } - -- | For loop. - | For + -- | For loop. + | For { for_targets :: [Expr annot] -- ^ Loop variables. - , for_generator :: Expr annot -- ^ Loop generator. + , for_generator :: Expr annot -- ^ Loop generator. , for_body :: Suite annot -- ^ Loop body , for_else :: Suite annot -- ^ Else clause. , stmt_annot :: annot @@ -233,39 +235,39 @@ data Statement annot { for_stmt :: Statement annot -- ^ For statement , stmt_annot :: annot } - -- | Function definition. - | Fun + -- | Function definition. + | Fun { fun_name :: Ident annot -- ^ Function name. , fun_args :: [Parameter annot] -- ^ Function parameter list. , fun_result_annotation :: Maybe (Expr annot) -- ^ Optional result annotation. , fun_body :: Suite annot -- ^ Function body. - , stmt_annot :: annot + , stmt_annot :: annot } | AsyncFun { fun_def :: Statement annot -- ^ Function definition (Fun) , stmt_annot :: annot } - -- | Class definition. - | Class + -- | Class definition. + | Class { class_name :: Ident annot -- ^ Class name. - , class_args :: [Argument annot] -- ^ Class argument list. In version 2.x this is only ArgExprs. + , class_args :: [Argument annot] -- ^ Class argument list. In version 2.x this is only ArgExprs. , class_body :: Suite annot -- ^ Class body. , stmt_annot :: annot } - -- | Conditional statement (if-elif-else). - | Conditional + -- | Conditional statement (if-elif-else). + | Conditional { cond_guards :: [(Expr annot, Suite annot)] -- ^ Sequence of if-elif conditional clauses. , cond_else :: Suite annot -- ^ Possibly empty unconditional else clause. , stmt_annot :: annot } - -- | Assignment statement. - | Assign - { assign_to :: [Expr annot] -- ^ Entity to assign to. + -- | Assignment statement. + | Assign + { assign_to :: [Expr annot] -- ^ Entity to assign to. , assign_expr :: Expr annot -- ^ Expression to evaluate. , stmt_annot :: annot } - -- | Augmented assignment statement. - | AugmentedAssign + -- | Augmented assignment statement. + | AugmentedAssign { aug_assign_to :: Expr annot -- ^ Entity to assign to. , aug_assign_op :: AssignOp annot -- ^ Assignment operator (for example \'+=\'). , aug_assign_expr :: Expr annot -- ^ Expression to evaluate. @@ -278,31 +280,31 @@ data Statement annot , stmt_annot :: annot } -- | Decorated definition of a function or class. - | Decorated + | Decorated { decorated_decorators :: [Decorator annot] -- ^ Decorators. , decorated_def :: Statement annot -- ^ Function or class definition to be decorated. - , stmt_annot :: annot + , stmt_annot :: annot } - -- | Return statement (may only occur syntactically nested in a function definition). - | Return + -- | Return statement (may only occur syntactically nested in a function definition). + | Return { return_expr :: Maybe (Expr annot) -- ^ Optional expression to evaluate and return to caller. - , stmt_annot :: annot + , stmt_annot :: annot } - -- | Try statement (exception handling). - | Try + -- | Try statement (exception handling). + | Try { try_body :: Suite annot -- ^ Try clause. , try_excepts :: [Handler annot] -- ^ Exception handlers. , try_else :: Suite annot -- ^ Possibly empty else clause, executed if and when control flows off the end of the try clause. , try_finally :: Suite annot -- ^ Possibly empty finally clause. , stmt_annot :: annot } - -- | Raise statement (exception throwing). - | Raise - { raise_expr :: RaiseExpr annot + -- | Raise statement (exception throwing). + | Raise + { raise_expr :: RaiseExpr annot , stmt_annot :: annot } - -- | With statement (context management). - | With + -- | With statement (context management). + | With { with_context :: [(Expr annot, Maybe (Expr annot))] -- ^ Context expression(s) (yields a context manager). , with_body :: Suite annot -- ^ Suite to be managed. , stmt_annot :: annot @@ -311,91 +313,91 @@ data Statement annot { with_stmt :: Statement annot -- ^ With statement , stmt_annot :: annot } - -- | Pass statement (null operation). + -- | Pass statement (null operation). | Pass { stmt_annot :: annot } - -- | Break statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition within that loop). + -- | Break statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition within that loop). | Break { stmt_annot :: annot } - -- | Continue statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition or finally clause within that loop). + -- | Continue statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition or finally clause within that loop). | Continue { stmt_annot :: annot } - -- | Del statement (delete). - | Delete + -- | Del statement (delete). + | Delete { del_exprs :: [Expr annot] -- ^ Items to delete. - , stmt_annot :: annot + , stmt_annot :: annot } - -- | Expression statement. + -- | Expression statement. | StmtExpr { stmt_expr :: Expr annot, stmt_annot :: annot } - -- | Global declaration. - | Global + -- | Global declaration. + | Global { global_vars :: [Ident annot] -- ^ Variables declared global in the current block. , stmt_annot :: annot } - -- | Nonlocal declaration. /Version 3.x only/. - | NonLocal + -- | Nonlocal declaration. /Version 3.x only/. + | NonLocal { nonLocal_vars :: [Ident annot] -- ^ Variables declared nonlocal in the current block (their binding comes from bound the nearest enclosing scope). , stmt_annot :: annot } - -- | Assertion. - | Assert + -- | Assertion. + | Assert { assert_exprs :: [Expr annot] -- ^ Expressions being asserted. , stmt_annot :: annot } - -- | Print statement. /Version 2 only/. - | Print + -- | Print statement. /Version 2 only/. + | Print { print_chevron :: Bool -- ^ Optional chevron (>>) , print_exprs :: [Expr annot] -- ^ Arguments to print , print_trailing_comma :: Bool -- ^ Does it end in a comma? - , stmt_annot :: annot + , stmt_annot :: annot } - -- | Exec statement. /Version 2 only/. + -- | Exec statement. /Version 2 only/. | Exec { exec_expr :: Expr annot -- ^ Expression to exec. , exec_globals_locals :: Maybe (Expr annot, Maybe (Expr annot)) -- ^ Global and local environments to evaluate the expression within. - , stmt_annot :: annot + , stmt_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type StatementSpan = Statement SrcSpan instance Span StatementSpan where - getSpan = annot + getSpan = annot instance Annotated Statement where - annot = stmt_annot + annot = stmt_annot -- | The argument for a @raise@ statement. data RaiseExpr annot = RaiseV3 (Maybe (Expr annot, Maybe (Expr annot))) -- ^ Optional expression to evaluate, and optional \'from\' clause. /Version 3 only/. | RaiseV2 (Maybe (Expr annot, (Maybe (Expr annot, Maybe (Expr annot))))) -- ^ /Version 2 only/. - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type RaiseExprSpan = RaiseExpr SrcSpan -- | Decorator. -data Decorator annot = - Decorator +data Decorator annot = + Decorator { decorator_name :: DottedName annot -- ^ Decorator name. , decorator_args :: [Argument annot] -- ^ Decorator arguments. - , decorator_annot :: annot + , decorator_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type DecoratorSpan = Decorator SrcSpan instance Span DecoratorSpan where - getSpan = annot + getSpan = annot instance Annotated Decorator where - annot = decorator_annot + annot = decorator_annot -- | Formal parameter of function definitions and lambda expressions. --- --- * Version 2.6: +-- +-- * Version 2.6: -- -- * -- -- * -- --- * Version 3.1: +-- * Version 3.1: -- -- * -- @@ -403,20 +405,20 @@ instance Annotated Decorator where -- data Parameter annot -- | Ordinary named parameter. - = Param + = Param { param_name :: Ident annot -- ^ Parameter name. , param_py_annotation :: Maybe (Expr annot) -- ^ Optional annotation. , param_default :: Maybe (Expr annot) -- ^ Optional default value. , param_annot :: annot } - -- | Excess positional parameter (single asterisk before its name in the concrete syntax). - | VarArgsPos + -- | Excess positional parameter (single asterisk before its name in the concrete syntax). + | VarArgsPos { param_name :: Ident annot -- ^ Parameter name. , param_py_annotation :: Maybe (Expr annot) -- ^ Optional annotation. , param_annot :: annot } -- | Excess keyword parameter (double asterisk before its name in the concrete syntax). - | VarArgsKeyword + | VarArgsKeyword { param_name :: Ident annot -- ^ Parameter name. , param_py_annotation :: Maybe (Expr annot) -- ^ Optional annotation. , param_annot :: annot @@ -424,26 +426,26 @@ data Parameter annot -- | Marker for the end of positional parameters (not a parameter itself). | EndPositional { param_annot :: annot } -- | Tuple unpack. /Version 2 only/. - | UnPackTuple + | UnPackTuple { param_unpack_tuple :: ParamTuple annot -- ^ The tuple to unpack. , param_default :: Maybe (Expr annot) -- ^ Optional default value. , param_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ParameterSpan = Parameter SrcSpan instance Span ParameterSpan where - getSpan = annot + getSpan = annot instance Annotated Parameter where - annot = param_annot + annot = param_annot -- | Tuple unpack parameter. /Version 2 only/. data ParamTuple annot = ParamTupleName { param_tuple_name :: Ident annot, param_tuple_annot :: annot } -- ^ A variable name. | ParamTuple { param_tuple :: [ParamTuple annot], param_tuple_annot :: annot } -- ^ A (possibly nested) tuple parameter. - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ParamTupleSpan = ParamTuple SrcSpan @@ -462,77 +464,77 @@ data Argument annot -- | Excess keyword argument. | ArgVarArgsKeyword { arg_expr :: Expr annot, arg_annot :: annot } -- | Keyword argument. - | ArgKeyword + | ArgKeyword { arg_keyword :: Ident annot -- ^ Keyword name. , arg_expr :: Expr annot -- ^ Argument expression. , arg_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ArgumentSpan = Argument SrcSpan instance Span ArgumentSpan where - getSpan = annot + getSpan = annot instance Annotated Argument where - annot = arg_annot + annot = arg_annot --- | Exception handler. +-- | Exception handler. data Handler annot - = Handler + = Handler { handler_clause :: ExceptClause annot , handler_suite :: Suite annot - , handler_annot :: annot + , handler_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type HandlerSpan = Handler SrcSpan instance Span HandlerSpan where - getSpan = annot + getSpan = annot instance Annotated Handler where - annot = handler_annot + annot = handler_annot --- | Exception clause. +-- | Exception clause. data ExceptClause annot - = ExceptClause + = ExceptClause -- NB: difference with version 3 (has NAME as target, but looks like bug in grammar) { except_clause :: Maybe (Expr annot, Maybe (Expr annot)) - , except_clause_annot :: annot + , except_clause_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ExceptClauseSpan = ExceptClause SrcSpan instance Span ExceptClauseSpan where - getSpan = annot + getSpan = annot instance Annotated ExceptClause where - annot = except_clause_annot + annot = except_clause_annot --- | Comprehension. In version 3.x this can be used for lists, sets, dictionaries and generators. +-- | Comprehension. In version 3.x this can be used for lists, sets, dictionaries and generators. -- data Comprehension e annot data Comprehension annot - = Comprehension + = Comprehension { comprehension_expr :: ComprehensionExpr annot , comprehension_for :: CompFor annot - , comprehension_annot :: annot + , comprehension_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ComprehensionSpan = Comprehension SrcSpan instance Span ComprehensionSpan where - getSpan = annot + getSpan = annot instance Annotated Comprehension where - annot = comprehension_annot + annot = comprehension_annot data ComprehensionExpr annot = ComprehensionExpr (Expr annot) | ComprehensionDict (DictKeyDatumList annot) - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ComprehensionExprSpan = ComprehensionExpr SrcSpan @@ -540,62 +542,62 @@ instance Span ComprehensionExprSpan where getSpan (ComprehensionExpr e) = getSpan e getSpan (ComprehensionDict d) = getSpan d --- | Comprehension \'for\' component. -data CompFor annot = - CompFor +-- | Comprehension \'for\' component. +data CompFor annot = + CompFor { comp_for_async :: Bool , comp_for_exprs :: [Expr annot] , comp_in_expr :: Expr annot - , comp_for_iter :: Maybe (CompIter annot) + , comp_for_iter :: Maybe (CompIter annot) , comp_for_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type CompForSpan = CompFor SrcSpan instance Span CompForSpan where - getSpan = annot + getSpan = annot instance Annotated CompFor where - annot = comp_for_annot + annot = comp_for_annot --- | Comprehension guard. -data CompIf annot = - CompIf +-- | Comprehension guard. +data CompIf annot = + CompIf { comp_if :: Expr annot , comp_if_iter :: Maybe (CompIter annot) - , comp_if_annot :: annot + , comp_if_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type CompIfSpan = CompIf SrcSpan instance Span CompIfSpan where - getSpan = annot + getSpan = annot instance Annotated CompIf where - annot = comp_if_annot + annot = comp_if_annot --- | Comprehension iterator (either a \'for\' or an \'if\'). -data CompIter annot +-- | Comprehension iterator (either a \'for\' or an \'if\'). +data CompIter annot = IterFor { comp_iter_for :: CompFor annot, comp_iter_annot :: annot } | IterIf { comp_iter_if :: CompIf annot, comp_iter_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type CompIterSpan = CompIter SrcSpan instance Span CompIterSpan where - getSpan = annot + getSpan = annot instance Annotated CompIter where - annot = comp_iter_annot + annot = comp_iter_annot -- | Expressions. --- +-- -- * Version 2.6 . --- +-- -- * Version 3.1 . --- +-- data Expr annot -- | Variable. = Var { var_ident :: Ident annot, expr_annot :: annot } @@ -606,11 +608,11 @@ data Expr annot -- | Literal floating point number. | Float { float_value :: Double, expr_literal :: String, expr_annot :: annot } -- | Literal imaginary number. - | Imaginary { imaginary_value :: Double, expr_literal :: String, expr_annot :: annot } + | Imaginary { imaginary_value :: Double, expr_literal :: String, expr_annot :: annot } -- | Literal boolean. | Bool { bool_value :: Bool, expr_annot :: annot } -- | Literal \'None\' value. - | None { expr_annot :: annot } + | None { expr_annot :: annot } -- | Ellipsis \'...\'. | Ellipsis { expr_annot :: annot } -- | Literal byte string. @@ -619,18 +621,18 @@ data Expr annot | Strings { strings_strings :: [String], expr_annot :: annot } -- | Unicode literal strings (to be concatentated together). Version 2 only. | UnicodeStrings { unicodestrings_strings :: [String], expr_annot :: annot } - -- | Function call. - | Call + -- | Function call. + | Call { call_fun :: Expr annot -- ^ Expression yielding a callable object (such as a function). , call_args :: [Argument annot] -- ^ Call arguments. , expr_annot :: annot } - -- | Subscription, for example \'x [y]\'. + -- | Subscription, for example \'x [y]\'. | Subscript { subscriptee :: Expr annot, subscript_expr :: Expr annot, expr_annot :: annot } - -- | Slicing, for example \'w [x:y:z]\'. - | SlicedExpr { slicee :: Expr annot, slices :: [Slice annot], expr_annot :: annot } - -- | Conditional expresison. - | CondExpr + -- | Slicing, for example \'w [x:y:z]\'. + | SlicedExpr { slicee :: Expr annot, slices :: [Slice annot], expr_annot :: annot } + -- | Conditional expresison. + | CondExpr { ce_true_branch :: Expr annot -- ^ Expression to evaluate if condition is True. , ce_condition :: Expr annot -- ^ Boolean condition. , ce_false_branch :: Expr annot -- ^ Expression to evaluate if condition is False. @@ -642,49 +644,49 @@ data Expr annot | UnaryOp { operator :: Op annot, op_arg :: Expr annot, expr_annot :: annot } -- Dot operator (attribute selection) | Dot { dot_expr :: Expr annot, dot_attribute :: Ident annot, expr_annot :: annot } - -- | Anonymous function definition (lambda). + -- | Anonymous function definition (lambda). | Lambda { lambda_args :: [Parameter annot], lambda_body :: Expr annot, expr_annot :: annot } - -- | Tuple. Can be empty. + -- | Tuple. Can be empty. | Tuple { tuple_exprs :: [Expr annot], expr_annot :: annot } - -- | Generator yield. - | Yield + -- | Generator yield. + | Yield -- { yield_expr :: Maybe (Expr annot) -- ^ Optional expression to yield. { yield_arg :: Maybe (YieldArg annot) -- ^ Optional Yield argument. , expr_annot :: annot } - -- | Generator. + -- | Generator. | Generator { gen_comprehension :: Comprehension annot, expr_annot :: annot } -- | Await | Await { await_expr :: Expr annot, expr_annot :: annot } - -- | List comprehension. + -- | List comprehension. | ListComp { list_comprehension :: Comprehension annot, expr_annot :: annot } - -- | List. + -- | List. | List { list_exprs :: [Expr annot], expr_annot :: annot } - -- | Dictionary. + -- | Dictionary. | Dictionary { dict_mappings :: [DictKeyDatumList annot], expr_annot :: annot } - -- | Dictionary comprehension. /Version 3 only/. + -- | Dictionary comprehension. /Version 3 only/. | DictComp { dict_comprehension :: Comprehension annot, expr_annot :: annot } - -- | Set. - | Set { set_exprs :: [Expr annot], expr_annot :: annot } - -- | Set comprehension. /Version 3 only/. + -- | Set. + | Set { set_exprs :: [Expr annot], expr_annot :: annot } + -- | Set comprehension. /Version 3 only/. | SetComp { set_comprehension :: Comprehension annot, expr_annot :: annot } -- | Starred expression. /Version 3 only/. | Starred { starred_expr :: Expr annot, expr_annot :: annot } -- | Parenthesised expression. | Paren { paren_expr :: Expr annot, expr_annot :: annot } - -- | String conversion (backquoted expression). Version 2 only. + -- | String conversion (backquoted expression). Version 2 only. | StringConversion { backquoted_expr :: Expr annot, expr_anot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type ExprSpan = Expr SrcSpan instance Span ExprSpan where - getSpan = annot + getSpan = annot data YieldArg annot = YieldFrom (Expr annot) annot -- ^ Yield from a generator (Version 3 only) | YieldExpr (Expr annot) -- ^ Yield value of an expression - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type YieldArgSpan = YieldArg SrcSpan @@ -693,12 +695,12 @@ instance Span YieldArgSpan where getSpan (YieldExpr e) = getSpan e instance Annotated Expr where - annot = expr_annot + annot = expr_annot data DictKeyDatumList annot = DictMappingPair (Expr annot) (Expr annot) | DictUnpacking (Expr annot) - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type DictKeyDatumListSpan = DictKeyDatumList SrcSpan @@ -708,26 +710,26 @@ instance Span DictKeyDatumListSpan where -- | Slice compenent. data Slice annot - = SliceProper + = SliceProper { slice_lower :: Maybe (Expr annot) , slice_upper :: Maybe (Expr annot) - , slice_stride :: Maybe (Maybe (Expr annot)) + , slice_stride :: Maybe (Maybe (Expr annot)) , slice_annot :: annot - } - | SliceExpr + } + | SliceExpr { slice_expr :: Expr annot - , slice_annot :: annot + , slice_annot :: annot } | SliceEllipsis { slice_annot :: annot } - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type SliceSpan = Slice SrcSpan instance Span SliceSpan where - getSpan = annot + getSpan = annot instance Annotated Slice where - annot = slice_annot + annot = slice_annot -- | Operators. data Op annot @@ -759,15 +761,15 @@ data Op annot | MatrixMult { op_annot :: annot } -- ^ \'@\' | Invert { op_annot :: annot } -- ^ \'~\' (bitwise inversion of its integer argument) | Modulo { op_annot :: annot } -- ^ \'%\' - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type OpSpan = Op SrcSpan instance Span OpSpan where - getSpan = annot + getSpan = annot instance Annotated Op where - annot = op_annot + annot = op_annot -- | Augmented assignment operators. data AssignOp annot @@ -779,17 +781,17 @@ data AssignOp annot | PowAssign { assignOp_annot :: annot } -- ^ \'*=\' | BinAndAssign { assignOp_annot :: annot } -- ^ \'&=\' | BinOrAssign { assignOp_annot :: annot } -- ^ \'|=\' - | BinXorAssign { assignOp_annot :: annot } -- ^ \'^=\' + | BinXorAssign { assignOp_annot :: annot } -- ^ \'^=\' | LeftShiftAssign { assignOp_annot :: annot } -- ^ \'<<=\' | RightShiftAssign { assignOp_annot :: annot } -- ^ \'>>=\' | FloorDivAssign { assignOp_annot :: annot } -- ^ \'\/\/=\' | MatrixMultAssign { assignOp_annot :: annot } -- ^ \'@=\' - deriving (Eq,Ord,Show,Typeable,Data,Functor) + deriving (Eq,Ord,Show,Typeable,Data,Functor,Foldable,Traversable) type AssignOpSpan = AssignOp SrcSpan instance Span AssignOpSpan where - getSpan = annot + getSpan = annot instance Annotated AssignOp where - annot = assignOp_annot + annot = assignOp_annot diff --git a/language-python/src/Language/Python/Common/LexerUtils.hs b/language-python/src/Language/Python/Common/LexerUtils.hs index 6936b88..59cf3aa 100644 --- a/language-python/src/Language/Python/Common/LexerUtils.hs +++ b/language-python/src/Language/Python/Common/LexerUtils.hs @@ -114,6 +114,11 @@ notEOF :: a -> AlexInput -> Int -> AlexInput -> Bool notEOF _user _inputBeforeToken _tokenLength (_loc, _bs, inputAfterToken) = not (null inputAfterToken) +delUnderscores :: String -> String +delUnderscores [] = [] +delUnderscores ('_':xs) = delUnderscores xs +delUnderscores (x :xs) = x : delUnderscores xs + readBinary :: String -> Integer readBinary = toBinary . drop 2 diff --git a/language-python/src/Language/Python/Version2.hs b/language-python/src/Language/Python/Version2.hs index 3bb215f..2e4e9ab 100644 --- a/language-python/src/Language/Python/Version2.hs +++ b/language-python/src/Language/Python/Version2.hs @@ -13,7 +13,7 @@ -- -- * for an overview of the language. -- - -- * for the full grammar. +-- * for the full grammar. -- -- * for a description of -- the various Python top-levels, which correspond to the parsers provided here. diff --git a/language-python/src/Language/Python/Version2/Parser/Parser.y b/language-python/src/Language/Python/Version2/Parser/Parser.y index b06d47e..b312349 100644 --- a/language-python/src/Language/Python/Version2/Parser/Parser.y +++ b/language-python/src/Language/Python/Version2/Parser/Parser.y @@ -1,8 +1,11 @@ { {-# LANGUAGE CPP #-} -#undef __GLASGOW_HASKELL__ +-- For legacy reasons +#if __GLASGOW_HASKELL__ < 901 +#undef __GLASGOW_HASKELL_ #define __GLASGOW_HASKELL__ 709 +#endif ----------------------------------------------------------------------------- -- | -- Module : Language.Python.Version2.Parser.Parser diff --git a/language-python/src/Language/Python/Version3/Parser/Lexer.x b/language-python/src/Language/Python/Version3/Parser/Lexer.x index c3a95e3..217f270 100644 --- a/language-python/src/Language/Python/Version3/Parser/Lexer.x +++ b/language-python/src/Language/Python/Version3/Parser/Lexer.x @@ -9,7 +9,7 @@ -- Portability : ghc -- -- Implementation of a lexer for Python version 3.x programs. Generated by --- alex. +-- alex. Edited by Curran McConnell to conform to PEP515. ----------------------------------------------------------------------------- module Language.Python.Version3.Parser.Lexer @@ -43,9 +43,9 @@ $not_single_quote = [. \n] # ' $not_double_quote = [. \n] # \" -- macro definitions -@exponent = (e | E) (\+ | \-)? $digit+ -@fraction = \. $digit+ -@int_part = $digit+ +@exponent = (e | E) (\+ | \-)? $digit(_?$digit+)* +@fraction = \. $digit(_?$digit+)* +@int_part = $digit(_?$digit+)* @point_float = (@int_part? @fraction) | @int_part \. @exponent_float = (@int_part | @point_float) @exponent @float_number = @point_float | @exponent_float @@ -85,13 +85,13 @@ $white_no_nl+ ; -- skip whitespace \\ @eol_pattern { lineJoin } -- line join <0> { - @float_number { token FloatToken readFloat } - $non_zero_digit $digit* { token IntegerToken read } + @float_number { token FloatToken (readFloat.delUnderscores) } + $non_zero_digit (_?$digit)* { token IntegerToken (read.delUnderscores) } (@float_number | @int_part) (j | J) { token ImaginaryToken (readFloat.init) } - 0+ { token IntegerToken read } - 0 (o | O) $oct_digit+ { token IntegerToken read } - 0 (x | X) $hex_digit+ { token IntegerToken read } - 0 (b | B) $bin_digit+ { token IntegerToken readBinary } + 0+(_?0+)* { token IntegerToken (read.delUnderscores) } + 0 (o | O) (_?$oct_digit+)+ { token IntegerToken (read.delUnderscores) } + 0 (x | X) (_?$hex_digit+)+ { token IntegerToken (read.delUnderscores) } + 0 (b | B) (_?$bin_digit+)+ { token IntegerToken (readBinary.delUnderscores) } } -- String literals diff --git a/language-python/src/Language/Python/Version3/Parser/Parser.y b/language-python/src/Language/Python/Version3/Parser/Parser.y index 214faeb..d473be4 100644 --- a/language-python/src/Language/Python/Version3/Parser/Parser.y +++ b/language-python/src/Language/Python/Version3/Parser/Parser.y @@ -1,8 +1,12 @@ { {-# LANGUAGE CPP #-} +-- For legacy reasons +#if __GLASGOW_HASKELL__ < 901 #undef __GLASGOW_HASKELL__ #define __GLASGOW_HASKELL__ 709 +#endif + ----------------------------------------------------------------------------- -- | -- Module : Language.Python.Version3.Parser.Parser diff --git a/language-python/stack.yaml b/language-python/stack.yaml index 1de6a19..3cf046e 100644 --- a/language-python/stack.yaml +++ b/language-python/stack.yaml @@ -1,45 +1,9 @@ -# This file was automatically generated by 'stack init' -# -# Some commonly used options have been documented as comments in this file. -# For advanced use and comprehensive documentation of the format, please see: -# https://docs.haskellstack.org/en/stable/yaml_configuration/ - -# Resolver to choose a 'specific' stackage snapshot or a compiler version. -# A snapshot resolver dictates the compiler version and the set of packages -# to be used for project dependencies. For example: -# -# resolver: lts-3.5 -# resolver: nightly-2015-09-21 -# resolver: ghc-7.10.2 -# resolver: ghcjs-0.1.0_ghc-7.10.2 -# resolver: -# name: custom-snapshot -# location: "./custom-snapshot.yaml" resolver: lts-10.2 -# User packages to be built. -# Various formats can be used as shown in the example below. -# -# packages: -# - some-directory -# - https://example.com/foo/bar/baz-0.0.2.tar.gz -# - location: -# git: https://github.com/commercialhaskell/stack.git -# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# extra-dep: true -# subdirs: -# - auto-update -# - wai -# -# A package marked 'extra-dep: true' will only be built if demanded by a -# non-dependency (i.e. a user package), and its test suites and benchmarks -# will not be run. This is useful for tweaking upstream packages. packages: - . -# Dependency packages to be pulled from upstream that are not in the resolver -# (e.g., acme-missiles-0.3) -# extra-deps: [] + +extra-deps: [] # Override default flag values for local packages and extra-deps # flags: {} @@ -63,4 +27,4 @@ packages: # extra-lib-dirs: [/path/to/dir] # # Allow a newer minor version of GHC than the snapshot specifies -# compiler-check: newer-minor \ No newline at end of file +# compiler-check: newer-minor