diff --git a/.github/workflows/build-binary-packages.yml b/.github/workflows/build-binary-packages.yml index d476aa161..40f10c8bb 100644 --- a/.github/workflows/build-binary-packages.yml +++ b/.github/workflows/build-binary-packages.yml @@ -2,7 +2,7 @@ name: Build Binary Packages on: workflow_dispatch: - release: + release: types: ["created"] jobs: @@ -13,9 +13,9 @@ jobs: name: Build Ubuntu package strategy: matrix: - os: - - ubuntu-20.04 - - ubuntu-22.04 + ghc: ["9.6"] + cabal: ["3.10"] + os: ["ubuntu-24.04"] runs-on: ${{ matrix.os }} @@ -25,12 +25,13 @@ jobs: # Note: `haskell-platform` is listed as requirement in debian/control, # which is why it's installed using apt instead of the Setup Haskell action. - # - name: Setup Haskell - # uses: actions/setup-haskell@v1 - # id: setup-haskell-cabal - # with: - # ghc-version: ${{ matrix.ghc }} - # cabal-version: ${{ matrix.cabal }} + - name: Setup Haskell + uses: haskell-actions/setup@v2 + id: setup-haskell-cabal + with: + ghc-version: ${{ matrix.ghc }} + cabal-version: ${{ matrix.cabal }} + if: matrix.os == 'ubuntu-24.04' - name: Install build tools run: | @@ -39,14 +40,15 @@ jobs: make \ dpkg-dev \ debhelper \ - haskell-platform \ libghc-json-dev \ - python-dev \ default-jdk \ - libtool-bin - + python-dev-is-python3 \ + libtool-bin + cabal install alex happy + - name: Build package run: | + export PYTHONPATH="/home/runner/work/gf-core/gf-core/debian/gf/usr/local/lib/python3.12/dist-packages/" make deb - name: Copy package @@ -54,7 +56,7 @@ jobs: cp ../gf_*.deb dist/ - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb path: dist/gf_*.deb @@ -79,16 +81,16 @@ jobs: name: Build macOS package strategy: matrix: - ghc: ["8.6.5"] - cabal: ["2.4"] - os: ["macos-10.15"] + ghc: ["9.6"] + cabal: ["3.10"] + os: ["macos-latest", "macos-13"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - name: Setup Haskell - uses: actions/setup-haskell@v1 + uses: haskell-actions/setup@v2 id: setup-haskell-cabal with: ghc-version: ${{ matrix.ghc }} @@ -97,8 +99,10 @@ jobs: - name: Install build tools run: | brew install \ - automake + automake \ + libtool cabal v1-install alex happy + pip install setuptools - name: Build package run: | @@ -107,12 +111,12 @@ jobs: make pkg - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: - name: gf-${{ github.event.release.tag_name }}-macos + name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }} path: dist/gf-*.pkg if-no-files-found: error - + - name: Rename package run: | mv dist/gf-*.pkg dist/gf-${{ github.event.release.tag_name }}-macos.pkg @@ -132,9 +136,9 @@ jobs: name: Build Windows package strategy: matrix: - ghc: ["8.6.5"] - cabal: ["2.4"] - os: ["windows-2019"] + ghc: ["9.6.7"] + cabal: ["3.10"] + os: ["windows-2022"] runs-on: ${{ matrix.os }} steps: @@ -147,6 +151,7 @@ jobs: base-devel gcc python-devel + autotools - name: Prepare dist folder shell: msys2 {0} @@ -171,7 +176,8 @@ jobs: - name: Build Java bindings shell: msys2 {0} run: | - export JDKPATH=/c/hostedtoolcache/windows/Java_Adopt_jdk/8.0.292-10/x64 + echo $JAVA_HOME_8_X64 + export JDKPATH="$(cygpath -u "${JAVA_HOME_8_X64}")" export PATH="${PATH}:${JDKPATH}/bin" cd src/runtime/java make \ @@ -180,6 +186,9 @@ jobs: make install cp .libs/msys-jpgf-0.dll /c/tmp-dist/java/jpgf.dll cp jpgf.jar /c/tmp-dist/java + if: false + + # - uses: actions/setup-python@v5 - name: Build Python bindings shell: msys2 {0} @@ -188,12 +197,13 @@ jobs: EXTRA_LIB_DIRS: /mingw64/lib run: | cd src/runtime/python + pacman --noconfirm -S python-setuptools python setup.py build python setup.py install - cp /usr/lib/python3.9/site-packages/pgf* /c/tmp-dist/python + cp -r /usr/lib/python3.12/site-packages/pgf* /c/tmp-dist/python - name: Setup Haskell - uses: actions/setup-haskell@v1 + uses: haskell-actions/setup@v2 id: setup-haskell-cabal with: ghc-version: ${{ matrix.ghc }} @@ -205,13 +215,13 @@ jobs: - name: Build GF run: | - cabal install --only-dependencies -fserver + cabal install -fserver --only-dependencies cabal configure -fserver cabal build - copy dist\build\gf\gf.exe C:\tmp-dist + copy dist-newstyle/build/x86_64-windows/ghc-${{matrix.ghc}}/*/x/gf/build/gf/gf.exe C:/tmp-dist - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: gf-${{ github.event.release.tag_name }}-windows path: C:\tmp-dist\* diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index d7d8ac94a..b2565eb05 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -13,10 +13,10 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, macos-13] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - uses: actions/setup-python@v5 name: Install Python @@ -25,7 +25,7 @@ jobs: - name: Install cibuildwheel run: | - python -m pip install git+https://github.com/joerick/cibuildwheel.git@main + python -m pip install cibuildwheel - name: Install build tools for OSX if: startsWith(matrix.os, 'macos') @@ -56,9 +56,9 @@ jobs: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 name: Install Python with: python-version: '3.10' @@ -78,7 +78,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.event_name == 'push' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 @@ -97,6 +97,6 @@ jobs: - name: Publish env: TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.pypi_password }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - (cd ./src/runtime/python && curl -I --fail https://pypi.org/project/$(python setup.py --name)/$(python setup.py --version)/) || twine upload dist/* + twine upload --verbose --non-interactive --skip-existing dist/* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ac209f1af..c27fa1c61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -### New since 3.11 (WIP) +### New since 3.12 (WIP) -- Added a changelog! +### 3.12 +See ### 3.11 diff --git a/Makefile b/Makefile index fc2a38808..2b78f7be2 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ html:: # number to the top of debian/changelog. # (Tested on Ubuntu 15.04. You need to install dpkg-dev & debhelper.) deb: - dpkg-buildpackage -b -uc + dpkg-buildpackage -b -uc -d # Make a macOS installer package pkg: diff --git a/bin/build-binary-dist.sh b/bin/build-binary-dist.sh index 4ea1c31a3..4dad03c8b 100755 --- a/bin/build-binary-dist.sh +++ b/bin/build-binary-dist.sh @@ -32,7 +32,7 @@ set -x # print commands before executing them pushd src/runtime/c bash setup.sh configure --prefix="$prefix" bash setup.sh build -bash setup.sh install prefix="$prefix" # hack required for GF build on macOS +# bash setup.sh install prefix="$prefix" # hack required for GF build on macOS bash setup.sh install prefix="$destdir$prefix" popd @@ -46,7 +46,7 @@ if which >/dev/null python; then pyver=$(ls "$destdir$prefix/lib" | sed -n 's/^python//p') pydest="$destdir/Library/Python/$pyver/site-packages" mkdir -p "$pydest" - ln "$destdir$prefix/lib/python$pyver/site-packages"/pgf* "$pydest" + ln "$destdir$prefix/lib/python$pyver/site-packages"/pgf*.so "$pydest" fi popd else diff --git a/debian/changelog b/debian/changelog index e91bf28fb..6c4018287 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,8 @@ +gf (3.12) noble; urgency=low + + * GF 3.12 + + -- Inari Listenmaa Fri, 8 Aug 2025 18:29:29 +0100 gf (3.11) bionic focal; urgency=low * GF 3.11 diff --git a/debian/control b/debian/control index 12eb6b9d9..729d81382 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: devel Priority: optional Maintainer: Thomas Hallgren Standards-Version: 3.9.2 -Build-Depends: debhelper (>= 5), haskell-platform (>= 2011.2.0.1), libghc-haskeline-dev, libghc-mtl-dev, libghc-json-dev, autoconf, automake, libtool-bin, python-dev, java-sdk +Build-Depends: debhelper (>= 5), libghc-haskeline-dev, libghc-mtl-dev, libghc-json-dev, autoconf, automake, libtool-bin, python-dev-is-python3, java-sdk Homepage: http://www.grammaticalframework.org/ Package: gf diff --git a/debian/rules b/debian/rules index 7ec04b4e2..9969fe56e 100755 --- a/debian/rules +++ b/debian/rules @@ -16,7 +16,7 @@ override_dh_shlibdeps: override_dh_auto_configure: cd src/runtime/c && bash setup.sh configure --prefix=/usr cd src/runtime/c && bash setup.sh build - cabal v1-update + cabal update cabal v1-install --only-dependencies cabal v1-configure --prefix=/usr -fserver -fc-runtime --extra-lib-dirs=$(CURDIR)/src/runtime/c/.libs --extra-include-dirs=$(CURDIR)/src/runtime/c @@ -24,7 +24,7 @@ SET_LDL=LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs override_dh_auto_build: cd src/runtime/python && EXTRA_INCLUDE_DIRS=$(CURDIR)/src/runtime/c EXTRA_LIB_DIRS=$(CURDIR)/src/runtime/c/.libs python setup.py build - cd src/runtime/java && make CFLAGS="-I$(CURDIR)/src/runtime/c -L$(CURDIR)/src/runtime/c/.libs" INSTALL_PATH=/usr + # cd src/runtime/java && make CFLAGS="-I$(CURDIR)/src/runtime/c -L$(CURDIR)/src/runtime/c/.libs" INSTALL_PATH=/usr echo $(SET_LDL) -$(SET_LDL) cabal v1-build @@ -32,13 +32,15 @@ override_dh_auto_install: $(SET_LDL) cabal v1-copy --destdir=$(CURDIR)/debian/gf cd src/runtime/c && bash setup.sh copy prefix=$(CURDIR)/debian/gf/usr cd src/runtime/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr - cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr install - D="`find debian/gf -name site-packages`" && [ -n "$$D" ] && cd $$D && cd .. && mv site-packages dist-packages + # cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr install + # D="`find debian/gf -name dist-packages`" && [ -n "$$D" ] && cd $$D && cd .. && mv dist-packages dist-packages + +override_dh_usrlocal: override_dh_auto_clean: rm -fr dist/build -cd src/runtime/python && rm -fr build - -cd src/runtime/java && make clean + # -cd src/runtime/java && make clean -cd src/runtime/c && make clean override_dh_auto_test: diff --git a/doc/gf-help-full.txt b/doc/gf-help-full.txt index 1b9c31705..3444a1c1a 100644 --- a/doc/gf-help-full.txt +++ b/doc/gf-help-full.txt @@ -46,7 +46,7 @@ #TINY The command has one argument which is either function, expression or -a category defined in the abstract syntax of the current grammar. +a category defined in the abstract syntax of the current grammar. If the argument is a function then ?its type is printed out. If it is a category then the category definition is printed. If a whole expression is given it prints the expression with refined @@ -303,7 +303,7 @@ but the resulting .gf file must be imported separately. #TINY -Generates a list of random trees, by default one tree. +Generates a list of random trees, by default one tree up to depth 5. If a tree argument is given, the command completes the Tree with values to all metavariables in the tree. The generation can be biased by probabilities, given in a file in the -probs flag. @@ -315,13 +315,14 @@ given in a file in the -probs flag. | ``-cat`` | generation category | ``-lang`` | uses only functions that have linearizations in all these languages | ``-number`` | number of trees generated - | ``-depth`` | the maximum generation depth + | ``-depth`` | the maximum generation depth (default: 5) | ``-probs`` | file with biased probabilities (format 'f 0.4' one by line) - Examples: | ``gr`` | one tree in the startcat of the current grammar | ``gr -cat=NP -number=16`` | 16 trees in the category NP + | ``gr -cat=NP -depth=2`` | one tree in the category NP, up to depth 2 | ``gr -lang=LangHin,LangTha -cat=Cl`` | Cl, both in LangHin and LangTha | ``gr -probs=FILE`` | generate with bias | ``gr (AdjCN ? (UseN ?))`` | generate trees of form (AdjCN ? (UseN ?)) @@ -338,8 +339,8 @@ given in a file in the -probs flag. #TINY -Generates all trees of a given category. By default, -the depth is limited to 4, but this can be changed by a flag. +Generates all trees of a given category. By default, +the depth is limited to 5, but this can be changed by a flag. If a Tree argument is given, the command completes the Tree with values to all metavariables in the tree. @@ -353,7 +354,7 @@ to all metavariables in the tree. - Examples: - | ``gt`` | all trees in the startcat, to depth 4 + | ``gt`` | all trees in the startcat, to depth 5 | ``gt -cat=NP -number=16`` | 16 trees in the category NP | ``gt -cat=NP -depth=2`` | trees in the category NP to depth 2 | ``gt (AdjCN ? (UseN ?))`` | trees of form (AdjCN ? (UseN ?)) @@ -582,7 +583,7 @@ trees where a function node is a metavariable. - Examples: - | ``l -lang=LangSwe,LangNor -chunks ? a b (? c d)`` | + | ``l -lang=LangSwe,LangNor -chunks ? a b (? c d)`` | #NORMAL @@ -647,7 +648,7 @@ The -lang flag can be used to restrict this to fewer languages. The default start category can be overridden by the -cat flag. See also the ps command for lexing and character encoding. -The -openclass flag is experimental and allows some robustness in +The -openclass flag is experimental and allows some robustness in the parser. For example if -openclass="A,N,V" is given, the parser will accept unknown adjectives, nouns and verbs with the resource grammar. diff --git a/doc/tutorial/gf-tutorial.t2t b/doc/tutorial/gf-tutorial.t2t index c4ccb6aab..d58b93f16 100644 --- a/doc/tutorial/gf-tutorial.t2t +++ b/doc/tutorial/gf-tutorial.t2t @@ -1188,7 +1188,7 @@ use ``generate_trees = gt``. this wine is fresh this wine is warm ``` -The default **depth** is 3; the depth can be +The default **depth** is 5; the depth can be set by using the ``depth`` flag: ``` > generate_trees -depth=2 | l @@ -1739,9 +1739,9 @@ A new module can **extend** an old one: Pizza : Kind ; } ``` -Note that the extended grammar doesn't inherit the start -category from the grammar it extends, so if you want to -generate sentences with this grammar, you'll have to either +Note that the extended grammar doesn't inherit the start +category from the grammar it extends, so if you want to +generate sentences with this grammar, you'll have to either add a startcat (e.g. ``flags startcat = Question ;``), or in the GF shell, specify the category to ``generate_random`` or ``geneate_trees`` (e.g. ``gr -cat=Comment`` or ``gt -cat=Question``). @@ -3746,7 +3746,7 @@ However, type-incorrect commands are rejected by the typecheck: The parsing is successful but the type checking failed with error(s): Couldn't match expected type Device light against the interred type Device fan - In the expression: DKindOne fan + In the expression: DKindOne fan ``` #NEW @@ -4184,7 +4184,7 @@ division of integers. ``` abstract Calculator = { flags startcat = Exp ; - + cat Exp ; fun diff --git a/download/index-3.12.md b/download/index-3.12.md new file mode 100644 index 000000000..bb9c11cb5 --- /dev/null +++ b/download/index-3.12.md @@ -0,0 +1,195 @@ +--- +title: Grammatical Framework Download and Installation +date: 3 August 2025 +--- + +**GF 3.12** was released on 3 August 2025. + +What's new? See the [release notes](release-3.12.html). + +#### Note: GF core and the RGL + +The following instructions explain how to install **GF core**, i.e. the compiler, shell and run-time systems. +Obtaining the **Resource Grammar Library (RGL)** is done separately; see the section at the bottom of this page. + +--- + +## Installing from a binary package + +Binary packages are available for Debian/Ubuntu, macOS, and Windows and include: + +- GF shell and grammar compiler +- `gf -server` mode +- C run-time system +- Java & Python bindings to the C run-time system + +Unlike in previous versions, the binaries **do not** include the RGL. + +[Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/3.12) + +#### Debian/Ubuntu + +There are two versions: `gf-3.12-ubuntu-18.04.deb` for Ubuntu 18.04 (Cosmic), and `gf-3.12-ubuntu-20.04.deb` for Ubuntu 20.04 (Focal). + +To install the package use: + +``` +sudo apt-get install ./gf-3.12-ubuntu-*.deb +``` + + + +#### macOS + +To install the package, just double-click it and follow the installer instructions. + +The packages should work on at least Catalina and Big Sur. + +#### Windows + +To install the package, unpack it anywhere. + +You will probably need to update the `PATH` environment variable to include your chosen install location. + +For more information, see [Using GF on Windows](https://www.grammaticalframework.org/~inari/gf-windows.html) (latest updated for Windows 10). + +## Installing from Hackage + +_Instructions applicable for macOS, Linux, and WSL2 on Windows._ + +[GF is on Hackage](http://hackage.haskell.org/package/gf), so under +normal circumstances the procedure is fairly simple: + +``` +cabal update +cabal install gf-3.12 +``` + +### Notes + +**GHC version** + +The GF source code is known to be compilable with GHC versions 7.10 through to 8.10. + +**Obtaining Haskell** + +There are various ways of obtaining Haskell, including: + +- ghcup + 1. Install from https://www.haskell.org/ghcup/ + 2. `ghcup install ghc 8.10.4` + 3. `ghcup set ghc 8.10.4` +- Haskell Platform https://www.haskell.org/platform/ +- Stack https://haskellstack.org/ + + +**Installation location** + +The above steps install GF for a single user. +The executables are put in `$HOME/.cabal/bin` (or on macOS in `$HOME/Library/Haskell/bin`), +so you might want to add this directory to your path (in `.bash_profile` or similar): + +``` +PATH=$HOME/.cabal/bin:$PATH +``` + +**Haskeline** + +GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which +on Linux depends on some non-Haskell libraries that won't be installed +automatically by Cabal, and therefore need to be installed manually. +Here is one way to do this: + +- On Ubuntu: `sudo apt-get install libghc-haskeline-dev` +- On Fedora: `sudo dnf install ghc-haskeline-devel` + +## Installing from source code + +**Obtaining** + +To obtain the source code for the **release**, +download it from [GitHub](https://github.com/GrammaticalFramework/gf-core/releases). + +Alternatively, to obtain the **latest version** of the source code: + +1. If you haven't already, clone the repository with: +``` +git clone https://github.com/GrammaticalFramework/gf-core.git +``` +2. If you've already cloned the repository previously, update with: +``` +git pull +``` + + +**Installing** + +You can then install with: +``` +cabal install +``` + +or, if you're a Stack user: + +``` +stack install +``` + + +For more info on working with the GF source code, see the +[GF Developers Guide](../doc/gf-developers.html). + +For macOS Sequoia, you need to downgrade the LLVM package, see instructions [here](https://github.com/GrammaticalFramework/gf-core/issues/172#issuecomment-2599365457). + +## Installing the Python bindings from PyPI + +The Python library is available on PyPI as `pgf`, so it can be installed using: + +``` +pip install pgf +``` + +We provide binary wheels for Linux and macOS, which include the C runtime and are ready-to-go. +If there is no binary distribution for your platform, this will install the source tarball, +which will attempt to build the binding during installation, +and requires the GF C runtime to be installed on your system. + +--- + +## Installing the RGL from a binary release + +Binary releases of the RGL are made available on [GitHub](https://github.com/GrammaticalFramework/gf-rgl/releases). +In general the steps to follow are: + +1. Download a binary release and extract it somewhere on your system. +2. Set the environment variable `GF_LIB_PATH` to point to wherever you extracted the RGL. + +## Installing the RGL from source + +To compile the RGL, you will need to have GF already installed and in your path. + +1. Obtain the RGL source code, either by: + - cloning with `git clone https://github.com/GrammaticalFramework/gf-rgl.git` + - downloading a source archive [here](https://github.com/GrammaticalFramework/gf-rgl/archive/master.zip) +2. Run `make` in the source code folder. + +For more options, see the [RGL README](https://github.com/GrammaticalFramework/gf-rgl/blob/master/README.md). + +--- + +## Older releases + +- [GF 3.11](index-3.11.html) (July 2021) +- [GF 3.10](index-3.10.html) (December 2018) +- [GF 3.9](index-3.9.html) (August 2017) +- [GF 3.8](index-3.8.html) (June 2016) +- [GF 3.7.1](index-3.7.1.html) (October 2015) +- [GF 3.7](index-3.7.html) (June 2015) +- [GF 3.6](index-3.6.html) (June 2014) +- [GF 3.5](index-3.5.html) (August 2013) +- [GF 3.4](index-3.4.html) (January 2013) +- [GF 3.3.3](index-3.3.3.html) (March 2012) +- [GF 3.3](index-3.3.html) (October 2011) +- [GF 3.2.9](index-3.2.9.html) source-only snapshot (September 2011) +- [GF 3.2](index-3.2.html) (December 2010) +- [GF 3.1.6](index-3.1.6.html) (April 2010) diff --git a/download/index.html b/download/index.html index 810537bd8..8167b818b 100644 --- a/download/index.html +++ b/download/index.html @@ -3,6 +3,6 @@ - You are being redirected to the current version of this page. + You are being redirected to the current version of this page. diff --git a/download/release-3.12.md b/download/release-3.12.md new file mode 100644 index 000000000..7380fb541 --- /dev/null +++ b/download/release-3.12.md @@ -0,0 +1,37 @@ +--- +title: GF 3.12 Release Notes +date: 03 August 2025 +--- + +## Installation + +See the [download page](index-3.12.html). + +## What's new +This release adds support for Apple Silicon M1 Mac computers and newer versions of GHC, along with various improvements and bug fixes. + +Over 70 commits have been merged to gf-core since the release of GF 3.11 in July 2021. + +## General +- Support for ARM, allowing to run GF on Mac computers with Apple Silicon M1 +- Support for newer versions of GHC (8.10.7, 9.0.2, 9.2.4, 9.4, 9.6.7) +- Support compiling with Nix +- Better error messages +- Improvements to several GF shell commands +- Several bug fixes and performance improvements +- Temporarily dropped support for Java bindings + +## GF compiler and run-time library +- Syntactic sugar for table update: `table {cases ; vvv => t \! vvv}.t` can now be written as `t ** { cases }` +- Adjust the `-view` command depending on the OS +- Improve output of the `visualize_dependencies` (`vd`) command for large dependency trees +- Reintroduce syntactic transfer with `pt -transfer` and fix a bug in `pt -compute` +- Bug fix: apply `gt` to all arguments when piped +- Fix many "Invalid character" messages by always encoding GF files in UTF-8 +- Improve performance with long extend-lists +- Improve syntax error messages +- Add support for BIND tokens in the Python bindings +- Allow compilation with emscripten + +## Other +- Add support for Visual Studio Code \ No newline at end of file diff --git a/gf.cabal b/gf.cabal index ce0682d46..4586436f8 100644 --- a/gf.cabal +++ b/gf.cabal @@ -1,5 +1,5 @@ name: gf -version: 3.11.0-git +version: 3.12.0 cabal-version: 1.22 build-type: Simple @@ -158,7 +158,8 @@ library json >= 0.9.1 && <= 0.11, parallel >= 3.2.1.1 && < 3.3, process >= 1.4.3 && < 1.7, - time >= 1.6.0 && <= 1.12.2 + time >= 1.6.0 && <= 1.12.2, + template-haskell >= 2.13.0.0 hs-source-dirs: src/compiler exposed-modules: diff --git a/index.html b/index.html index 214d8c66f..dd6e535b1 100644 --- a/index.html +++ b/index.html @@ -245,6 +245,11 @@ least one, it may help you to get a first idea of what GF is.

News

+
2025-08-08
+
+ GF 3.12 released. + Release notes +
2025-01-18
9th GF Summer School, in Gothenburg, Sweden, 18 – 29 August 2025. diff --git a/src/compiler/GF/Command/Commands.hs b/src/compiler/GF/Command/Commands.hs index 7f27e8a45..876449136 100644 --- a/src/compiler/GF/Command/Commands.hs +++ b/src/compiler/GF/Command/Commands.hs @@ -22,6 +22,7 @@ import GF.Infra.SIO import GF.Command.Abstract import GF.Command.CommandInfo import GF.Command.CommonCommands +import qualified GF.Command.CommonCommands as Common import GF.Text.Clitics import GF.Quiz @@ -166,14 +167,15 @@ pgfCommands = Map.fromList [ synopsis = "generate random trees in the current abstract syntax", syntax = "gr [-cat=CAT] [-number=INT]", examples = [ - mkEx "gr -- one tree in the startcat of the current grammar", - mkEx "gr -cat=NP -number=16 -- 16 trees in the category NP", - mkEx "gr -lang=LangHin,LangTha -cat=Cl -- Cl, both in LangHin and LangTha", - mkEx "gr -probs=FILE -- generate with bias", - mkEx "gr (AdjCN ? (UseN ?)) -- generate trees of form (AdjCN ? (UseN ?))" + mkEx $ "gr -- one tree in the startcat of the current grammar, up to depth " ++ Common.default_depth_str, + mkEx "gr -cat=NP -number=16 -- 16 trees in the category NP", + mkEx "gr -cat=NP -depth=2 -- one tree in the category NP, up to depth 2", + mkEx "gr -lang=LangHin,LangTha -cat=Cl -- Cl, both in LangHin and LangTha", + mkEx "gr -probs=FILE -- generate with bias", + mkEx "gr (AdjCN ? (UseN ?)) -- generate trees of form (AdjCN ? (UseN ?))" ], explanation = unlines [ - "Generates a list of random trees, by default one tree.", + "Generates a list of random trees, by default one tree up to depth " ++ Common.default_depth_str ++ ".", "If a tree argument is given, the command completes the Tree with values to", "all metavariables in the tree. The generation can be biased by probabilities,", "given in a file in the -probs flag." @@ -182,13 +184,13 @@ pgfCommands = Map.fromList [ ("cat","generation category"), ("lang","uses only functions that have linearizations in all these languages"), ("number","number of trees generated"), - ("depth","the maximum generation depth"), + ("depth","the maximum generation depth (default: " ++ Common.default_depth_str ++ ")"), ("probs", "file with biased probabilities (format 'f 0.4' one by line)") ], exec = getEnv $ \ opts arg (Env pgf mos) -> do pgf <- optProbs opts (optRestricted opts pgf) gen <- newStdGen - let dp = valIntOpts "depth" 4 opts + let dp = valIntOpts "depth" Common.default_depth opts let ts = case mexp (toExprs arg) of Just ex -> generateRandomFromDepth gen pgf ex (Just dp) Nothing -> generateRandomDepth gen pgf (optType pgf opts) (Just dp) @@ -199,25 +201,25 @@ pgfCommands = Map.fromList [ synopsis = "generates a list of trees, by default exhaustive", explanation = unlines [ "Generates all trees of a given category. By default, ", - "the depth is limited to 4, but this can be changed by a flag.", + "the depth is limited to " ++ Common.default_depth_str ++ ", but this can be changed by a flag.", "If a Tree argument is given, the command completes the Tree with values", "to all metavariables in the tree." ], flags = [ ("cat","the generation category"), - ("depth","the maximum generation depth"), + ("depth","the maximum generation depth (default: " ++ Common.default_depth_str ++ ")"), ("lang","excludes functions that have no linearization in this language"), ("number","the number of trees generated") ], examples = [ - mkEx "gt -- all trees in the startcat, to depth 4", - mkEx "gt -cat=NP -number=16 -- 16 trees in the category NP", - mkEx "gt -cat=NP -depth=2 -- trees in the category NP to depth 2", - mkEx "gt (AdjCN ? (UseN ?)) -- trees of form (AdjCN ? (UseN ?))" + mkEx $ "gt -- all trees in the startcat, to depth " ++ Common.default_depth_str, + mkEx "gt -cat=NP -number=16 -- 16 trees in the category NP", + mkEx "gt -cat=NP -depth=2 -- trees in the category NP to depth 2", + mkEx "gt (AdjCN ? (UseN ?)) -- trees of form (AdjCN ? (UseN ?))" ], exec = getEnv $ \ opts arg (Env pgf mos) -> do let pgfr = optRestricted opts pgf - let dp = valIntOpts "depth" 4 opts + let dp = valIntOpts "depth" Common.default_depth opts let ts = case toExprs arg of [] -> generateAllDepth pgfr (optType pgf opts) (Just dp) es -> concat [generateFromDepth pgfr e (Just dp) | e <- es] @@ -547,7 +549,7 @@ pgfCommands = Map.fromList [ "which is processed by dot (graphviz) and displayed by the program indicated", "by the view flag. The target format is png, unless overridden by the", "flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).", - "See also 'vp -showdep' for another visualization of dependencies." + "See also 'vp -showdep' for another visualization of dependencies." ], exec = getEnv $ \ opts arg (Env pgf mos) -> do let absname = abstractName pgf @@ -760,7 +762,7 @@ pgfCommands = Map.fromList [ [] -> [parse_ pgf lang (optType pgf opts) (Just dp) s | lang <- optLangs pgf opts] open_typs -> [parseWithRecovery pgf lang (optType pgf opts) open_typs (Just dp) s | lang <- optLangs pgf opts] where - dp = valIntOpts "depth" 4 opts + dp = valIntOpts "depth" Common.default_depth opts fromParse opts = foldr (joinPiped . fromParse1 opts) void @@ -800,9 +802,9 @@ pgfCommands = Map.fromList [ _ | isOpt "tabtreebank" opts -> return $ concat $ intersperse "\t" $ (showExpr [] t) : [s | lang <- optLangs pgf opts, s <- linear pgf opts lang t] - _ | isOpt "chunks" opts -> map snd $ linChunks pgf opts t + _ | isOpt "chunks" opts -> map snd $ linChunks pgf opts t _ -> [s | lang <- optLangs pgf opts, s<-linear pgf opts lang t] - linChunks pgf opts t = + linChunks pgf opts t = [(lang, unwords (intersperse "<+>" (map (unlines . linear pgf opts lang) (treeChunks t)))) | lang <- optLangs pgf opts] linear :: PGF -> [Option] -> CId -> Expr -> [String] @@ -1006,13 +1008,13 @@ viewLatex view name grphs = do restrictedSystem $ "pdflatex " ++ texfile restrictedSystem $ view ++ " " ++ pdffile return void - + ---- copied from VisualizeTree ; not sure about proper place AR Nov 2015 latexDoc :: [String] -> String latexDoc body = unlines $ "\\batchmode" : "\\documentclass{article}" - : "\\usepackage[utf8]{inputenc}" + : "\\usepackage[utf8]{inputenc}" : "\\begin{document}" : spaces body ++ ["\\end{document}"] diff --git a/src/compiler/GF/Command/CommonCommands.hs b/src/compiler/GF/Command/CommonCommands.hs index c685fc525..f1faa258e 100644 --- a/src/compiler/GF/Command/CommonCommands.hs +++ b/src/compiler/GF/Command/CommonCommands.hs @@ -19,6 +19,12 @@ import Data.Char (isSpace) import qualified PGF as H(showCId,showExpr,toATree,toTrie,Trie(..)) +-- store default generation depth in a variable and use everywhere +default_depth :: Int +default_depth = 5 +default_depth_str = show default_depth + + extend old new = Map.union (Map.fromList new) old -- Map.union is left-biased commonCommands :: (Monad m,MonadSIO m) => Map.Map String (CommandInfo m) diff --git a/src/compiler/GF/Infra/BuildInfo.hs b/src/compiler/GF/Infra/BuildInfo.hs index f0230246b..1807b4031 100644 --- a/src/compiler/GF/Infra/BuildInfo.hs +++ b/src/compiler/GF/Infra/BuildInfo.hs @@ -1,13 +1,34 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE TemplateHaskell #-} + module GF.Infra.BuildInfo where import System.Info import Data.Version(showVersion) +import Language.Haskell.TH.Syntax +import Control.Monad.IO.Class +import Control.Exception +import Data.Time hiding (buildTime) +import System.Process + +-- Use Template Haskell to get compile time +buildTime :: String +buildTime = $(do + timeZone <- liftIO getCurrentTimeZone + time <- liftIO $ utcToLocalTime timeZone <$> getCurrentTime + return $ LitE $ StringL $ formatTime defaultTimeLocale "%F %T" time ) + +-- Use Template Haskell to get current Git information +gitInfo :: String +gitInfo = $(do + info <- liftIO $ try $ readProcess "git" ["log", "--format=commit %h tag %(describe:tags=true)", "-1"] "" :: Q (Either SomeException String) + return $ LitE $ StringL $ either (\_ -> "unavailable") id info ) + {-# NOINLINE buildInfo #-} buildInfo = "Built on "++os++"/"++arch - ++" with "++compilerName++"-"++showVersion compilerVersion - ++", flags:" + ++" with "++compilerName++"-"++showVersion compilerVersion ++ " at " ++ buildTime ++ "\nGit info: " ++ gitInfo + ++"\nFlags:" #ifdef USE_INTERRUPT ++" interrupt" #endif diff --git a/src/compiler/GF/Interactive2.hs b/src/compiler/GF/Interactive2.hs index d429b4530..f0c3f6043 100644 --- a/src/compiler/GF/Interactive2.hs +++ b/src/compiler/GF/Interactive2.hs @@ -12,7 +12,7 @@ import GF.Command.Abstract import GF.Command.Parse(readCommandLine,pCommand) import GF.Data.Operations (Err(..)) import GF.Data.Utilities(whenM,repeatM) - +import Control.Monad (join, when, (<=<)) import GF.Infra.UseIO(ioErrorText,putStrLnE) import GF.Infra.SIO import GF.Infra.Option diff --git a/src/runtime/c/gu/fun.h b/src/runtime/c/gu/fun.h index f4c1a5a38..5c14de6e9 100644 --- a/src/runtime/c/gu/fun.h +++ b/src/runtime/c/gu/fun.h @@ -12,17 +12,17 @@ typedef void (*GuFn2)(GuFn* clo, void* arg1, void* arg2); static inline void gu_apply0(GuFn* fn) { - (*fn)(fn); + ((GuFn0)(*fn))(fn); } static inline void gu_apply1(GuFn* fn, void* arg1) { - (*fn)(fn, arg1); + ((GuFn1)(*fn))(fn, arg1); } static inline void gu_apply2(GuFn* fn, void* arg1, void* arg2) { - (*fn)(fn, arg1, arg2); + ((GuFn2)(*fn))(fn, arg1, arg2); } #define gu_apply(fn_, ...) \ diff --git a/src/runtime/haskell-bind/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal index 83c990bf3..d7a98489e 100644 --- a/src/runtime/haskell-bind/pgf2.cabal +++ b/src/runtime/haskell-bind/pgf2.cabal @@ -15,7 +15,7 @@ homepage: https://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues author: Krasimir Angelov extra-source-files: CHANGELOG.md, README.md -tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4 +tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4, GHC=9.6.6 library exposed-modules: @@ -26,7 +26,7 @@ library PGF2.Expr, PGF2.Type build-depends: - base >= 4.9.1 && < 4.16, + base >= 4.9.1 && < 4.22, containers >= 0.5.7 && < 0.7, pretty >= 1.1.3 && < 1.2 default-language: Haskell2010 diff --git a/src/runtime/python/setup.py b/src/runtime/python/setup.py index fdc2fe8c5..3a1e6dc5c 100644 --- a/src/runtime/python/setup.py +++ b/src/runtime/python/setup.py @@ -1,4 +1,4 @@ -from distutils.core import setup, Extension +from setuptools import setup, Extension import os includes = os.getenv('EXTRA_INCLUDE_DIRS','').split(':') @@ -16,7 +16,7 @@ pgf_module = Extension('pgf', libraries = ['gu', 'pgf']) setup (name = 'pgf', - version = '1.0', + version = '1.1', description = 'Python bindings to the Grammatical Framework\'s PGF runtime', long_description="""\ Grammatical Framework (GF) is a programming language for multilingual grammar applications. diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs index bcf3d32f2..fda611fdc 100644 --- a/src/server/PGFService.hs +++ b/src/server/PGFService.hs @@ -159,13 +159,13 @@ cpgfMain qsem command (t,(pgf,pc)) = -> out t=<< bracketedLin # tree % to "c-linearizeAll"-> out t=<< linAll # tree % to "c-translate" -> withQSem qsem $ - out t=< out t=<< morpho # from1 % textInput "c-lookupcohorts"->out t=<< cohorts # from1 % getInput "filter" % textInput "c-flush" -> out t=<< flush "c-grammar" -> out t grammar "c-abstrtree" -> outputGraphviz=<< C.graphvizAbstractTree pgf C.graphvizDefaults # tree - "c-parsetree" -> outputGraphviz=<< (\cnc -> C.graphvizParseTree cnc C.graphvizDefaults) . snd # from1 %tree + "c-parsetree" -> outputGraphviz=<< (\cnc -> C.graphvizParseTree cnc C.graphvizDefaults) . snd # from1 % tree "c-wordforword" -> out t =<< wordforword # input % cat % to _ -> badRequest "Unknown command" command where @@ -571,6 +571,8 @@ limit, depth :: CGI (Maybe Int) limit = readInput "limit" depth = readInput "depth" +default_depth_server = 4 + start :: CGI Int start = maybe 0 id # readInput "start" @@ -781,7 +783,7 @@ doRandom pgf mcat mdepth mlimit to = | tree <- limit trees] where cat = fromMaybe (PGF.startCat pgf) mcat limit = take (fromMaybe 1 mlimit) - depth = fromMaybe 4 mdepth + depth = fromMaybe default_depth_server mdepth doGenerate :: PGF -> Maybe PGF.Type -> Maybe Int -> Maybe Int -> To -> JSValue doGenerate pgf mcat mdepth mlimit tos = @@ -794,7 +796,7 @@ doGenerate pgf mcat mdepth mlimit tos = trees = PGF.generateAllDepth pgf cat (Just depth) cat = fromMaybe (PGF.startCat pgf) mcat limit = take (fromMaybe 1 mlimit) - depth = fromMaybe 4 mdepth + depth = fromMaybe default_depth_server mdepth doGrammar :: (UTCTime,PGF) -> Either IOError (UTCTime,l) -> Maybe (Accept Language) -> CGI CGIResult doGrammar (t1,pgf) elbls macc = out t $ showJSON $ makeObj