1
0
forked from GitHub/gf-core

Compare commits

..

240 Commits

Author SHA1 Message Date
Inari Listenmaa
fa2826d29a Merge pull request #196 from GrammaticalFramework/fix-code-generation
`import Control.Monad` when generating .hs with GADTs
2025-08-13 14:02:53 +02:00
Inari Listenmaa
9325c8f9fb add import Control.Monad when generating .hs with GADTs 2025-08-13 13:38:23 +02:00
Inari Listenmaa
57dc5e9098 update developers' guide 2025-08-11 09:36:34 +02:00
Inari Listenmaa
b42b0caa34 add command to install GF with -cshell (commented out) 2025-08-11 09:36:34 +02:00
Arianna Masciolini
3ecb75d7d8 remove accidental file 2025-08-08 20:57:13 +02:00
Arianna Masciolini
2b876b1aac even more specific Mac install instruction 2025-08-08 20:51:48 +02:00
Arianna Masciolini
5935119050 more specific instructions for different macs 2025-08-08 20:43:15 +02:00
Inari Listenmaa
489424a1c6 add 9.6.7 in tested-with 2025-08-08 20:31:46 +02:00
Andreas Källberg
9c72994c2b Add upper bounds to base, unix and template-haskell 2025-08-08 20:23:18 +02:00
Arianna Masciolini
17ebcac84f Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core 2025-08-08 20:15:46 +02:00
Arianna Masciolini
7d018dde62 do not upload release assets 2025-08-08 20:15:37 +02:00
Andreas Källberg
4dba12c0ce Add a nix flake for building with nix (#185)
Also based on #165

---------

Co-authored-by: o1lo01ol1o <tim.pierson@gmail.com>
Co-authored-by: Tim Pierson <o1lo01ol1o@users.noreply.github.com>
2025-08-08 20:02:17 +02:00
Arianna Masciolini
5ca230dd2a remove info about specific versions of macOS for which binaries work 2025-08-08 19:55:33 +02:00
Arianna Masciolini
242cdcfa22 Update installation instructions (#195)
* update install instructions some dates

* change when to install c runtime manually
2025-08-08 19:44:48 +02:00
Arianna Masciolini
052916b454 try server mode on windows (#194) 2025-08-08 19:33:02 +02:00
Inari Listenmaa
d07646e753 Merge pull request #192 from GrammaticalFramework/build-timestamp
Add build timestamps to GF prompt
2025-08-08 19:32:52 +02:00
Inari Listenmaa
3b69a28dbd Delete src/runtime/python/pgf.egg-info directory
remove files that were committed by accident
2025-08-08 19:29:44 +02:00
Inari Listenmaa
aa004246d2 Merge pull request #190 from GrammaticalFramework/pgf-1.1
Publish PGF 1.1
2025-08-08 19:14:01 +02:00
Inari Listenmaa
7c6f53d003 add macos-13 to build for intel mac 2025-08-08 19:04:18 +02:00
Arianna Masciolini
a6d5d9a50c Merge pull request #193 from GrammaticalFramework/release3.12
Update version numbers, changelog etc. for 3.12 release
2025-08-08 18:34:26 +02:00
Arianna Masciolini
7792c3cc90 update debian changelog 2025-08-08 18:31:45 +02:00
Arianna Masciolini
a7d73a6861 link to changelog from CHANGELOG.md 2025-08-08 18:31:33 +02:00
Arianna Masciolini
646cfbea0c update cabal version number for 3.12 release 2025-08-08 18:31:17 +02:00
Arianna Masciolini
7ddb61eb48 update 3.12 release date in web news 2025-08-08 18:30:57 +02:00
Arianna Masciolini
dcae5f929e fix typo 2025-08-08 18:20:47 +02:00
Arianna Masciolini
638ed39fa4 readd changelog item on Java 2025-08-08 18:20:10 +02:00
Arianna Masciolini
726fb3467c Merge pull request #191 from GrammaticalFramework/minor-updates-binary-packages
Update release scripts for 3.12
2025-08-08 18:17:45 +02:00
Andreas Källberg
b02bb08532 Fix warnings for ghc-9.6 about multiplicity syntax 2025-08-08 18:12:39 +02:00
Inari Listenmaa
c7e26d7cd2 also add the 9.6 compatibility fixes to PGF2 2025-08-08 18:12:26 +02:00
Inari Listenmaa
4fea7cf37f Update release scripts for 3.12 2025-08-08 18:11:52 +02:00
Herbert Lange
9e5701b13c hide ambiguous function 2025-08-08 18:06:03 +02:00
Herbert Lange
78beac7598 change date/time formating 2025-08-08 18:02:59 +02:00
Herbert Lange
f96830f7de change template haskell required version 2025-08-08 17:50:33 +02:00
Herbert Lange
1c4cde7c66 updating formating for git info 2025-08-08 17:43:56 +02:00
Herbert Lange
e0ad7594dd add build time and git info to BuildInfo 2025-08-08 17:36:03 +02:00
Inari Listenmaa
a218903a2d use setuptools (so it works for 3.12+) + bump version to 1.1 2025-08-03 17:26:26 +02:00
Inari Listenmaa
f1c1d157b6 minor fixes in uploading to PyPI 2025-08-03 17:25:52 +02:00
Arianna Masciolini
e7c0b6dada add to what's new 2025-08-02 23:04:49 +02:00
Arianna Masciolini
8f4e8c73d2 Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core into release-3.12 2025-08-02 23:01:53 +02:00
Arianna Masciolini
d983255326 Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core 2025-08-02 23:01:29 +02:00
Arianna Masciolini
288984d243 fix compatibility with newer gcc versions 2025-08-02 23:01:20 +02:00
Inari Listenmaa
c23a03a2d1 Merge pull request #184 from inariksit/update-depth-documentation
Update default depth to 5 + less hardcoding in documentation
2025-08-02 22:05:29 +02:00
Inari Listenmaa
183e421a0f update default depth in tutorial and help text 2025-08-02 22:04:32 +02:00
Inari Listenmaa
3e0c0fa463 define default depths for shell and server only once 2025-08-02 21:46:13 +02:00
Arianna Masciolini
c2431e06b2 slightly less optimistic release date 2025-08-02 21:32:51 +02:00
Arianna Masciolini
eeab15bee1 redirect to 3.12 download page 2025-08-02 21:26:19 +02:00
Arianna Masciolini
b36b95c4d6 add news item about 3.12 release 2025-08-02 21:25:15 +02:00
Arianna Masciolini
2627e73b63 draft changelog for 3.12 2025-08-02 21:23:42 +02:00
Arianna Masciolini
e2ff43da0b init download page for 3.12 with 3.11 instructions with minor changes 2025-08-02 21:23:26 +02:00
Inari Listenmaa
af09351b66 Merge pull request #183 from inariksit/ghc-9.6.7
replace 9.6.6 with 9.6.7
2025-08-02 20:43:59 +02:00
Inari Listenmaa
8c89ba4e76 convert editor-modes into markdown 2025-08-02 20:36:03 +02:00
Inari Listenmaa
218c61b004 make 9.6.7 into default stack.yaml 2025-08-02 20:35:39 +02:00
Inari Listenmaa
52df0ed4fe replace 9.6.6 with 9.6.7 2025-08-02 20:35:22 +02:00
Arianna Masciolini
2324fe795c Merge pull request #181 from GrammaticalFramework/pr-174bis (also close #174)
PR #174bis
2025-08-02 20:26:36 +02:00
Arianna Masciolini
703b1e5d92 add eval.gfs to expected failures 2025-08-02 20:18:28 +02:00
Inari Listenmaa
f1a72a066f Merge pull request #182 from inariksit/fix-encoding
use UTF8 for several GF files
2025-08-02 19:26:06 +02:00
Inari Listenmaa
6f9f9642d7 use UTF8 for several GF files 2025-08-02 19:14:15 +02:00
Arianna Masciolini
f5752b345a fail slow 2025-08-02 19:14:09 +02:00
Arianna Masciolini
5170668ff2 Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core into hleiss/master 2025-08-02 19:02:30 +02:00
Inari Listenmaa
65e85c5a3c Merge pull request #175 from inariksit/new-ghc
Changes to make it work with newer stack/GHC:

- unix library changed API in 2.8
- Monad of no return & Semigroup as a superclass of Monoid
- import Control.Monad (join, when, (<=<))
- fixed CI issues
2025-08-02 18:59:07 +02:00
Inari Listenmaa
01c4f82e07 misc small fixes:
- update actions/cache to v4

- update haskell/actions/setup to haskell-actions/setup

- stack doesn't support ghc < 8.4, remove from CI

- don't fail immediately

- add -fpermissive flag to gcc

- only build 9.6.6 with macos and windows latest

- bump base upper bound
2025-08-02 18:46:00 +02:00
Inari Listenmaa
e81d668605 higher upper bound for base,mtl,ghc-prim,json,time 2025-08-02 16:39:31 +02:00
Inari Listenmaa
155b9da861 choose openFd based on version of unix 2025-08-02 16:39:31 +02:00
Inari Listenmaa
ab0f09e9f7 build-depends for unix depending on ghc version 2025-08-02 16:39:31 +02:00
Inari Listenmaa
9fa8ac934a add stack file for GHC 9.6.6 2025-08-02 16:39:31 +02:00
Inari Listenmaa
e84826ed2a explicitly import join, when, (<=<) from Control.Monad 2025-08-02 16:39:31 +02:00
Inari Listenmaa
bbf12458c7 use openFd from unix >= 2.8 2025-08-02 16:39:31 +02:00
Inari Listenmaa
b914a25de3 define return in terms of pure, >> as *>, mappend as <>
In preparation for deprecation, see https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/semigroup-monoid and https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/monad-of-no-return
2025-08-02 16:39:31 +02:00
Inari Listenmaa
1037b209ae add whitespace on list comprehensions, applications etc.
text editor interprets these things as errors (e.g. unterminated qq for list comprehension) and underlines red, even though there is no real error.
2025-08-02 16:39:31 +02:00
Inari Listenmaa
981d6b9bdd Specify that extending a grammar doesn't inherit the startcat 2025-02-20 20:52:21 +01:00
Hans Leiss
5776b567a2 Reactivate the gf-shell command 'pt -transfer' 2025-02-19 12:59:43 +01:00
Hans Leiss
643617ccc4 Bug fix for gf-shell command 'pt -compute' in Expr.hs by
tryMatch p (VConst _ _) env = match sig f eqs as0
2025-02-18 12:41:14 +01:00
Inari Listenmaa
41f45e572b Instruction to downgrade LLVM for macOS Sequoia 2025-01-18 07:27:46 +01:00
Inari Listenmaa
c7226cc11c add GFSS2025 + remove IRC channel 2025-01-18 07:13:24 +01:00
aarneranta
bc56b54dd1 random generation of literals now has ten different values for each built in type; maybe a better solution for most cases than just one value 2025-01-07 11:20:23 +01:00
Krasimir Angelov
aa061aff0c Update robots.txt 2024-11-26 12:15:41 +01:00
Inari Listenmaa
934afc9655 Merge pull request #169 from GrammaticalFramework/dependabot/github_actions/dot-github/workflows/actions/download-artifact-4.1.7
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
2024-11-01 10:29:45 +01:00
Andreas Källberg
33b0bab610 Use different artifact names as is required by upload-artifact@v4 2024-10-23 16:22:59 +02:00
Andreas Källberg
9492967fc6 add sudo to make install to fix CI failure 2024-10-23 16:08:09 +02:00
Andreas Källberg
5eab0a626d add glibtoolize dependency for mac CI 2024-10-23 15:47:14 +02:00
Andreas Källberg
fc614cd48e Bump more action versions 2024-10-23 15:40:29 +02:00
Andreas Källberg
eaec428a89 fix typo 2024-10-23 15:35:39 +02:00
Andreas Källberg
ed0a8ca0df Update setup-python github action
Let's see if this fixes CI
2024-10-23 15:34:01 +02:00
dependabot[bot]
c65dc70aaf Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 21:17:51 +00:00
Inari Listenmaa
2a654c085f be consistent in the use of quotes 2024-04-29 20:44:53 +08:00
Inari Listenmaa
b855a094f8 Clarify description for vt 2024-04-29 20:42:51 +08:00
Inari Listenmaa
2f31bbab23 Apply gt to all arguments when piped 2024-03-15 12:43:17 +01:00
aarneranta
7e707508a7 showExpr and linearize now refresh the printed variables if needed 2024-03-01 09:17:08 +01:00
Aarne Ranta
c2182274df visualize_dependencies (vd) now creates latex in landscape mode to show long trees better 2023-12-14 11:56:11 +01:00
Inari Listenmaa
e11017abc0 Merge pull request #166 from GrammaticalFramework/fix-python-ci
Fix CI for "Build & Publish Python Package": use python 3.10 instead of latest
2023-11-17 14:36:06 +01:00
Inari Listenmaa
b59fe24c11 use older python version to keep distutils 2023-11-17 14:11:59 +01:00
Inari Listenmaa
9204884463 Merge pull request #164 from BeFunctional/tp_pgf_support_ghc_94
Support GHC 9.4 for the PGF library
2023-11-17 14:02:06 +01:00
o1lo01ol1o
2c98075a0b support ghc9.4 2023-11-15 12:04:41 -06:00
Inari Listenmaa
7d9015e2e1 Merge pull request #161 from anka-213/indent-errors
Indent each line of error messages
2023-09-25 17:29:50 +02:00
Andreas Källberg
cf1ef40789 gh-actions: Bump the python version
cibuildwheel requires python >= 3.8
2023-09-25 12:55:15 +02:00
Andreas Källberg
37f06a4ae8 gh-actions: Don't use ubuntu-18 and macos-10.15
There are no longer any gihub actions runners available for these

Note that this means we can't build for ubuntu-18 anymore, but that
should hopefully no longer be relevant, since it's over 5 years old now.
2023-09-25 12:48:56 +02:00
Andreas Källberg
30c1376232 Don't build twice for tests in CI 2023-09-25 12:43:19 +02:00
Andreas Källberg
ea3cef46b0 Update test to match new error 2023-09-25 12:01:56 +02:00
Andreas Källberg
268a25f59c Indent each line of an error message
By indenting each line instead of just the first, we simplify
the work of the gf-lsp parser, so we can see which errors are the same
2023-09-25 09:55:02 +02:00
Inari Listenmaa
318b710a14 Merge pull request #160 from anka-213/prettier-syntax-errors
Improve syntax error messages
2023-09-13 08:24:07 +02:00
Andreas Källberg
b90666455e Fix typo 2023-09-11 13:17:19 +02:00
Andreas Källberg
88db715c3d Fix ghc-7.10.3 build in gh-actions
ghc-7.10.3 is not supported in the latest builder, so we
need an older version of ubuntu for it to work
2023-09-11 13:03:05 +02:00
Andreas Källberg
003ab57576 Bump version of haskell github action
The old one was failing
2023-09-11 18:43:14 +08:00
Andreas Källberg
ffd7b27abd Improve syntax error messages
Now you will get error messages like these:
example.gf:1:21:
   Syntax error:
     Unexpected token '}'.
     Expected one of:
     - '{'
     - 'open'
     - an identifier
2023-09-11 12:30:28 +02:00
Krasimir Angelov
096b36c21d Update jit.c 2023-09-07 17:37:25 +02:00
Krasimir Angelov
86af7b12b3 the jitter should still read the absfuns even for EMSCRIPTEN and aarch64 2023-08-11 10:47:29 +02:00
Krasimir Angelov
e2c2763d59 One more place with __aarch64__ 2023-08-09 10:59:53 +02:00
Krasimir Angelov
fae2fc4c6c Try with __aarch64__ 2023-08-09 10:58:50 +02:00
Krasimir Angelov
5131fadd1f lightning.h not included on aarch64 2023-08-08 16:18:49 +02:00
Krasimir Angelov
0e1cbfaa7e Disable the jit on aarch64 2023-08-04 15:01:31 +02:00
Krasimir Angelov
95e5976b03 Create funcs.h 2023-08-04 14:49:55 +02:00
Krasimir Angelov
9dee033e2c Create Create aarch64/fp.h 2023-08-04 14:49:22 +02:00
Krasimir Angelov
83a4a0525e Create aarch64/core.h 2023-08-04 14:48:58 +02:00
Krasimir Angelov
f58697f31f Create aarch64/asm.h 2023-08-04 14:48:01 +02:00
Krasimir Angelov
8f6dc916b6 added aarch64 configure.ac 2023-08-04 14:46:27 +02:00
Inari Listenmaa
6a36b486fa Update instructions for Geany 2023-03-03 01:17:28 +01:00
Krasimir Angelov
8190d9fe49 export BindType(..) 2023-03-01 09:57:48 +01:00
Inari Listenmaa
527a4451d3 update to System.Environment (getArgs) 2023-02-10 10:46:10 +08:00
Krasimir Angelov
2c13f529f9 Update INSTALL 2023-02-05 09:40:14 +01:00
Inari Listenmaa
8b82f1ab33 remove 2020-specific link 2023-01-24 16:33:28 +08:00
Inari Listenmaa
7bcc70e79d Summer school 2023 2023-01-24 16:19:22 +08:00
Inari Listenmaa
85038d0175 Merge pull request #149 from anka-213/ghc-9.2
Add support for ghc-9.2.4
2022-10-10 12:00:40 +02:00
Inari Listenmaa
6edd449d68 Merge pull request #147 from anka-213/extend-performance-issue
Improve performance with long extend-lists
2022-10-10 12:00:23 +02:00
Andreas Källberg
a58c6d49d4 Extract the previous optimization to its own function 2022-10-04 17:01:47 +02:00
Andreas Källberg
fef7b80d8e Use a Set in isInherited to speed up long extend lists
Now the time is O(log(n)*m) instead of O(n*m) where n is the number of
items in the extend list

e.g.
abstract FromWordNet = WordNet [
a_couple_Card,
a_la_carte_Adv,
a_la_mode_Adv,
a_little_Card,
...
];
2022-10-04 17:01:47 +02:00
Andreas Källberg
03df25bb7a Add support for ghc-9.2.4 2022-10-04 17:01:23 +02:00
Inari Listenmaa
3122590e35 Merge pull request #148 from anka-213/fix-ghc-7.10-build
Fix ghc-7.10 build
2022-10-04 16:59:53 +02:00
Andreas Källberg
0a16b76875 Only include transformers-compat for ghc < 8
Since that's the only place where it's needed
and we don't have to fight with versions elsewhere
2022-10-04 13:28:23 +02:00
Andreas Källberg
51b7117a3d Restore build with ghc-7.10.3 2022-10-04 13:07:07 +02:00
Andreas Källberg
fef03e755b Update some old unused code to support newer ghc 2022-10-04 13:07:07 +02:00
Aarne Ranta
223f92d4f6 using an unparsable variable name in the internal desugaring of table extension to avoid captures; captures with iterated table extensions might still be possible, which needs further analysis 2022-10-04 11:06:56 +02:00
aarneranta
83483b93ba New construct: table update. Syntax t ** { cases }. Syntactic sugar for table {cases ; vvv => t \! vvv}.t 2022-10-03 17:04:29 +02:00
Krasimir Angelov
dc8dce90a0 added a Setup script to compile without cabal-install 2022-08-24 14:00:22 +02:00
Krasimir Angelov
e9bbd38f68 gf --version now prints the shared folder to be used by the RGL 2022-08-24 12:02:10 +02:00
Krasimir Angelov
3fac8415ca forgot to mention sudo 2022-08-24 12:00:43 +02:00
Krasimir Angelov
1294269cd6 workaround for the Nix madness 2022-08-24 11:57:47 +02:00
krangelov
3acb7d2da4 silence harmless warnings 2022-08-12 10:54:43 +02:00
krangelov
08fb29e6b8 fix the reference counting for pgf.BIND 2022-08-12 10:51:56 +02:00
Inari Listenmaa
f69babef6d add link to Inari's blog 2022-07-27 14:53:58 +02:00
Krasimir Angelov
a42cec2107 support for BIND tokens in the Python bindings 2022-07-16 20:29:36 +02:00
Krasimir Angelov
4d446fcd3f Merge branch 'master' of github.com:GrammaticalFramework/gf-core 2022-07-04 10:42:59 +02:00
Krasimir Angelov
ae460e76b6 allow compilation with emscripten 2022-07-04 10:42:34 +02:00
John J. Camilleri
65308861bc Merge branch 'master' of github.com:GrammaticalFramework/gf-core 2022-06-18 21:09:23 +02:00
Krasimir Angelov
b7672b67a3 adjust the -view command depending on the OS 2022-05-31 10:15:50 +02:00
Krasimir Angelov
e33de168fd use a relative link to WordNet 2022-05-31 07:44:25 +02:00
Inari Listenmaa
fc5b3e9037 Merge pull request #141 from anka-213/hardcode-utf8
Always use UTF8 encoding in the gf executable
2022-05-18 09:46:03 +02:00
Andreas Källberg
9b9905c0b2 Always use UTF8 encoding in the gf executable
This fixes many of the "Invalid character" messages
you can get on different platforms.

This has helped both with a nix-installation that didn't have global
locale set and with a windows installation.
2022-05-18 14:42:01 +08:00
Inari Listenmaa
ec70e4a83e Merge pull request #136 from mengwong/ghc9
compiles with GHC 9.0.2
2022-05-06 03:26:00 +02:00
Inari Listenmaa
e6ade90679 update nightly to latest lts 2022-05-06 08:45:12 +08:00
Inari Listenmaa
6414bc8923 Merge pull request #140 from anka-213/no-profile-bind
Don't add automatic cost centres to Data.Binary.Get
2022-05-04 10:46:37 +02:00
Andreas Källberg
b0b2a06f3b Improve comment 2022-05-03 13:10:29 +08:00
Andreas Källberg
221597bd79 When profiling, don't add cost centres in Data.Binary.Get
This change speeds up profiling by an order of magnitude.
Without it, the >>= function for Get dominates runtime completely during profiling.
2022-05-03 13:08:35 +08:00
Inari Listenmaa
862aeb5d9b Update base <4.15 to <4.16 for tests + pgf*.cabal 2022-03-05 13:42:11 +08:00
Inari Listenmaa
25dd1354c7 Merge pull request #135 from mengwong/base-4-15
prepare for GHC 9, base 4.15, by using Buffer constructor interface
2022-03-05 06:28:17 +01:00
Inari Listenmaa
b762e24a82 Add ghc-9.0.2 to CI 2022-03-05 13:25:26 +08:00
Meng Weng Wong
20453193fe add compilation support for ghc 9.0.2 2022-03-05 13:15:40 +08:00
Meng Weng Wong
b53a102c98 if this PR is accepted we don't need these instructions 2022-03-05 12:59:25 +08:00
Meng Weng Wong
bc14a56f83 "now try this" instructions for people flailing with Apple Silicon M1 2022-03-05 12:59:25 +08:00
Meng Weng Wong
3a1213ab37 prepare for GHC 9, base 4.15, by using Buffer constructor interface 2022-03-05 12:59:25 +08:00
Inari Listenmaa
1b41e94f83 Merge pull request #138 from anka-213/patch-1
Fix stack ci
2022-03-05 05:49:43 +01:00
Andreas Källberg
308f4773dc Upgrade to ghc-8.10.7
This version has better support for m1 macbooks
2022-03-05 12:25:46 +08:00
Andreas Källberg
05fc093b5e Add restore key to cache 2022-03-05 12:25:46 +08:00
Andreas Källberg
4caf6d684e Another attempt at fixing linker errors 2022-03-05 12:25:46 +08:00
Andreas Källberg
bfd8f9c16d Upgrade haskell setup action 2022-03-05 12:24:38 +08:00
Andreas Källberg
aefac84670 Clear stack cache and make cache-key more fine-grained
Attempt at fixing #137
2022-03-05 12:24:10 +08:00
John J. Camilleri
9f2a3de7a3 Add simpler VSCode extension to editor modes page 2021-11-08 12:30:21 +01:00
krangelov
e4b2f281d9 Merge branch 'master' of github.com:GrammaticalFramework/gf-core 2021-09-22 14:11:27 +02:00
krangelov
063c517f3c more tests for variants 2021-09-22 14:11:11 +02:00
John J. Camilleri
bedb46527d Move Thomas from current to previous on maintainers page 2021-08-17 10:18:34 +02:00
John J. Camilleri
0258a87257 Add IRC, Discord, SO links to "contribute" section at top of homepage 2021-08-17 09:57:50 +02:00
John J. Camilleri
ef0e831c9e Update installation instructions from Hackage, source code 2021-08-17 09:38:20 +02:00
Inari Listenmaa
8ec13b1030 Uncomment installation instructions from Hackage 2021-08-16 09:07:59 +08:00
John J. Camilleri
058526ec5d Remove Travis CI workflow, we use GitHub actions now
Closes #123
2021-08-12 15:27:10 +02:00
John J. Camilleri
974e8b0835 Typos in homepage 2021-08-12 15:20:29 +02:00
John J. Camilleri
bbe4682c3d Update homepage
- Add Discord link
- Point to GitHub issues, Stack Overflow in "Getting help"
- Remove old news
2021-08-12 15:19:17 +02:00
John J. Camilleri
e477ce4b1f HTML fix on homepage 2021-08-12 10:05:45 +02:00
John J. Camilleri
7a63ba34b4 Add changelog
This will hopefully help us keep track of changes for the next release
2021-08-12 09:56:34 +02:00
John J. Camilleri
723bec1ba0 Changes made in order to get Hackage upload working 2021-08-09 13:41:25 +02:00
krangelov
265f08d6ee added link to vis-network.min.js 2021-07-26 16:57:05 +02:00
krangelov
e47042424e Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core 2021-07-26 16:52:11 +02:00
krangelov
ecf309a28e fix links to WordNet 2021-07-26 16:51:58 +02:00
Inari Listenmaa
d0a881f903 add VS code on the list of editor modes 2021-07-26 14:11:48 +08:00
Inari Listenmaa
810640822d Update documentation for release 3.11 2021-07-25 15:37:12 +08:00
Inari Listenmaa
ed79955931 Merge pull request #129 from anka-213/automate-release
Automatically upload release assets after building for release
2021-07-25 08:20:41 +02:00
Andreas Källberg
1867bfc8a1 Rename packages based on git tag 2021-07-25 11:08:21 +08:00
Andreas Källberg
6ef4f27d32 Upload release assets automatically as well 2021-07-25 10:43:36 +08:00
Inari Listenmaa
3ab07ec58f Update debian changelog for GF 3.11 2021-07-25 10:30:49 +08:00
Inari Listenmaa
b8324fe3e6 Merge pull request #116 from anka-213/fix-binary-package-build
Update scripts to use `cabal v1-...` so they work on newer cabal
2021-07-25 04:15:07 +02:00
Andreas Källberg
8814fde817 Only run the script once per release 2021-07-25 09:30:36 +08:00
Andreas Källberg
375b3cf285 Update release script to build for two ubuntu versions 2021-07-25 08:23:25 +08:00
Andreas Källberg
3c4f42db15 Build ubuntu packages on ubuntu-latest
Fixes #74
2021-07-25 08:23:25 +08:00
John J. Camilleri
0474a37af6 Make Makefile compatible with stack and old/new cabal (with v1- prefix when necessary) 2021-07-25 08:23:25 +08:00
Andreas Källberg
e3498d5ead Update to newest haskell github action
Also fix so the stack builds use the correct ghc versions
2021-07-25 08:23:25 +08:00
Andreas Källberg
4c5927c98c Update scripts to use cabal v1-... so they work on newer cabal
Fixes build failures like https://github.com/GrammaticalFramework/gf-core/runs/2949099280?check_suite_focus=true
2021-07-25 08:23:25 +08:00
John J. Camilleri
bb51224e8e IRC link pre-fills channel. Link to logs gives newest first. 2021-07-23 16:07:34 +02:00
John J. Camilleri
9533edc3ca Merge pull request #128 from GrammaticalFramework/windows-binary
Fixes to building Windows binary
2021-07-23 15:55:37 +02:00
John J. Camilleri
4df8999ed5 Change Python 3.8 to 3.9 2021-07-23 08:05:35 +02:00
John J. Camilleri
7fdbf3f400 Update path in main workflow for binaries 2021-07-22 23:11:01 +02:00
John J. Camilleri
0d6c67f6b1 Try without rewriting envvar 2021-07-22 23:02:22 +02:00
John J. Camilleri
2610219f6a Update path 2021-07-22 22:56:39 +02:00
John J. Camilleri
7674f078d6 Try another path 2021-07-22 22:49:44 +02:00
John J. Camilleri
c67fe05c08 Narrow search, print env var 2021-07-22 22:44:53 +02:00
John J. Camilleri
7b9bb780a2 Find Java stuff 2021-07-22 22:34:26 +02:00
John J. Camilleri
4f256447e2 Add separate Windows binary CI action for easier testing 2021-07-22 22:27:15 +02:00
Inari Listenmaa
dfa5b9276d #gf IRC channel has moved to Libera 2021-07-22 01:08:00 +02:00
Inari Listenmaa
667bfd30bd Merge pull request #87 from anka-213/make-it-fast
Remove the `Either Int` from value2term
2021-07-20 04:35:37 +02:00
Inari Listenmaa
66ae31e99e Merge pull request #126 from inariksit/developers-documentation
Update developers' documentation
2021-07-15 05:16:55 +02:00
Inari Listenmaa
a677f0373c General restructuring, various minor changes 2021-07-15 10:40:26 +08:00
Inari Listenmaa
13f845d127 Update C runtime instructions 2021-07-15 10:39:54 +08:00
Inari Listenmaa
aa530233fb Remove instructions to create binaries
Those are in github actions
2021-07-15 10:27:57 +08:00
Inari Listenmaa
45bc5595c0 Update C runtime install instructions 2021-07-15 09:54:15 +08:00
Inari Listenmaa
6d12754e4f Split the Cabal instructions to another page
and link from main instructions
2021-07-15 08:21:29 +08:00
1Regina
a09d9bd006 install and upgrade stack 2021-07-14 17:20:20 +08:00
Meowyam
fffe3161d4 updated docs to reflect binaries generated via github actions
fix merge conflicts

resolve merge conflict
2021-07-14 17:20:20 +08:00
Meowyam
743f5e55d4 add missing install.sh file for c runtime 2021-07-14 17:20:20 +08:00
Inari Listenmaa
9e209bbaba Changes in Git instructions 2021-07-14 17:20:07 +08:00
Inari Listenmaa
a1594e6a69 updated doc with instructions for C runtime for ubuntu and fedora 2021-07-14 16:44:44 +08:00
Inari Listenmaa
06e0a986d1 Changes in Git instructions 2021-07-14 16:12:11 +08:00
Meowyam
6f2a4bcd2c update doc for linux installation 2021-07-14 15:32:02 +08:00
Inari Listenmaa
f345f615f4 Update information about test suite
Co-Authored-By: 1Regina <46968488+1Regina@users.noreply.github.com>
2021-07-14 15:16:23 +08:00
Inari Listenmaa
80d16fcf94 Update instructions about C runtime 2021-07-14 15:03:59 +08:00
Andreas Källberg
7faf8c9dad Clean up redundant case expressions 2021-07-12 16:38:29 +08:00
Andreas Källberg
c2ffa6763b Github actions: Fix build for stack 2021-07-12 15:53:49 +08:00
Andreas Källberg
b3881570c7 Remove last traces of the Either in value2term 2021-07-12 15:53:49 +08:00
Andreas Källberg
bd270b05ff Remove the Either Int from value2term
This prevents HUGE space leak and makes compiling a PGF a LOT faster

For example, an application grammar moved from taking over 50GB
of ram and taking 5 minutes (most of which is spent on garbage colelction)
to taking 1.2 seconds and using 42mb of memory

The price we pay is that the "variable #n is out of scope" error is now
lazy and will happen when we try to evaluate the term instead of
happening when the function returns and allowing the caller to chose how
to handle the error.
I don't think this should matter in practice, since it's very rare;
at least Inari has never encountered it.
2021-07-12 15:50:43 +08:00
John J. Camilleri
a1fd3ea142 Fix bug introduced in cdbe73eb47
Apparently I don't understand how pattern-matching works in Haskell
2021-07-08 13:56:58 +02:00
John J. Camilleri
cdbe73eb47 Remove two missing-methods warnings 2021-07-08 12:10:41 +02:00
John J. Camilleri
6077d5dd5b Merge pull request #124 from GrammaticalFramework/cabal-cleanup
More cabal file cleanup
2021-07-08 08:56:31 +02:00
John J. Camilleri
0954b4cbab More cabal file cleanup. Remove some more tabs from Haskell source. 2021-07-07 13:04:09 +02:00
John J. Camilleri
f2e52d6f2c Replace tabs for whitespace in source code 2021-07-07 09:40:41 +02:00
John J. Camilleri
a2b23d5897 Make whitespace uniform in Cabal files, add a few more dependency bounds 2021-07-07 09:11:46 +02:00
John J. Camilleri
0886eb520d Update 3.11 release notes 2021-07-06 15:45:21 +02:00
John J. Camilleri
ef42216415 Add import from command line invocation to command history
Closes #64
2021-07-06 15:35:03 +02:00
John J. Camilleri
0c3ca3d79a Add note in PGF2 documentation about risk for integer overflow.
Closes #109
2021-07-06 14:43:21 +02:00
John J. Camilleri
e2e5033075 Merge pull request #122 from 2jacobtan/master
specify version bounds in *.cabal files
2021-07-06 14:31:29 +02:00
John J. Camilleri
84b4b6fab9 Some more cabal file cleanup. Add stack files for pgf, pgf2. 2021-07-06 14:11:30 +02:00
Inari Listenmaa
5e052ff499 Merge pull request #119 from GrammaticalFramework/concrete-new
Clean up Compute.ConcreteNew and TypeCheck.RConcrete
2021-07-06 14:05:00 +02:00
2jacobtan
e1a40640cd specify version bounds in pgf.cabal and pgf2.cabal 2021-07-06 05:42:34 +08:00
2jacobtan
be231584f6 set stack.yaml to lts-18.0 2021-07-06 05:20:09 +08:00
2jacobtan
12c564f97c specify version bounds in gf.cabal 2021-07-06 05:08:00 +08:00
144 changed files with 3372 additions and 1931 deletions

View File

@@ -12,28 +12,34 @@ jobs:
name: ${{ matrix.os }} / ghc ${{ matrix.ghc }} name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
cabal: ["3.2"] cabal: ["latest"]
ghc: ghc:
- "8.6.5" - "8.6.5"
- "8.8.3" - "8.8.3"
- "8.10.1" - "8.10.7"
- "9.6.7"
exclude: exclude:
- os: macos-latest - os: macos-latest
ghc: 8.8.3 ghc: 8.8.3
- os: macos-latest - os: macos-latest
ghc: 8.6.5 ghc: 8.6.5
- os: macos-latest
ghc: 8.10.7
- os: windows-latest - os: windows-latest
ghc: 8.8.3 ghc: 8.8.3
- os: windows-latest - os: windows-latest
ghc: 8.6.5 ghc: 8.6.5
- os: windows-latest
ghc: 8.10.7
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- uses: actions/setup-haskell@v1.1.4 - uses: haskell-actions/setup@v2
id: setup-haskell-cabal id: setup-haskell-cabal
name: Setup Haskell name: Setup Haskell
with: with:
@@ -44,7 +50,7 @@ jobs:
run: | run: |
cabal freeze cabal freeze
- uses: actions/cache@v1 - uses: actions/cache@v4
name: Cache ~/.cabal/store name: Cache ~/.cabal/store
with: with:
path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }} path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
@@ -62,33 +68,40 @@ jobs:
stack: stack:
name: stack / ghc ${{ matrix.ghc }} name: stack / ghc ${{ matrix.ghc }}
runs-on: ubuntu-latest runs-on: ${{ matrix.ghc == '7.10.3' && 'ubuntu-20.04' || 'ubuntu-latest' }}
strategy: strategy:
fail-fast: false
matrix: matrix:
stack: ["2.3.3"] stack: ["latest"]
ghc: ["7.10.3","8.0.2", "8.2.2", "8.4.4", "8.6.5", "8.8.4"] ghc: ["8.4.4", "8.6.5", "8.8.4", "8.10.7", "9.0.2", "9.6.7"]
# ghc: ["8.8.3"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- uses: actions/setup-haskell@v1.1.4 - uses: haskell-actions/setup@v2
name: Setup Haskell Stack name: Setup Haskell Stack
with: with:
# ghc-version: ${{ matrix.ghc }} ghc-version: ${{ matrix.ghc }}
stack-version: ${{ matrix.stack }} stack-version: 'latest'
enable-stack: true
- uses: actions/cache@v1
# Fix linker errrors on ghc-7.10.3 for ubuntu (see https://github.com/commercialhaskell/stack/blob/255cd830627870cdef34b5e54d670ef07882523e/doc/faq.md#i-get-strange-ld-errors-about-recompiling-with--fpic)
- run: sed -i.bak 's/"C compiler link flags", "/&-no-pie /' /home/runner/.ghcup/ghc/7.10.3/lib/ghc-7.10.3/settings
if: matrix.ghc == '7.10.3'
- uses: actions/cache@v4
name: Cache ~/.stack name: Cache ~/.stack
with: with:
path: ~/.stack path: ~/.stack
key: ${{ runner.os }}-${{ matrix.ghc }}-stack key: ${{ runner.os }}-${{ matrix.ghc }}-stack--${{ hashFiles(format('stack-ghc{0}', matrix.ghc)) }}
restore-keys: |
${{ runner.os }}-${{ matrix.ghc }}-stack
- name: Build - name: Build
run: | run: |
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml stack build --test --no-run-tests --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml
# stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
- name: Test - name: Test
run: | run: |

View File

@@ -3,6 +3,7 @@ name: Build Binary Packages
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
types: ["created"]
jobs: jobs:
@@ -10,11 +11,13 @@ jobs:
ubuntu: ubuntu:
name: Build Ubuntu package name: Build Ubuntu package
runs-on: ubuntu-18.04 strategy:
# strategy: matrix:
# matrix: ghc: ["9.6"]
# ghc: ["8.6.5"] cabal: ["3.10"]
# cabal: ["2.4"] os: ["ubuntu-24.04"]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -22,12 +25,13 @@ jobs:
# Note: `haskell-platform` is listed as requirement in debian/control, # Note: `haskell-platform` is listed as requirement in debian/control,
# which is why it's installed using apt instead of the Setup Haskell action. # which is why it's installed using apt instead of the Setup Haskell action.
# - name: Setup Haskell - name: Setup Haskell
# uses: actions/setup-haskell@v1 uses: haskell-actions/setup@v2
# id: setup-haskell-cabal id: setup-haskell-cabal
# with: with:
# ghc-version: ${{ matrix.ghc }} ghc-version: ${{ matrix.ghc }}
# cabal-version: ${{ matrix.cabal }} cabal-version: ${{ matrix.cabal }}
if: matrix.os == 'ubuntu-24.04'
- name: Install build tools - name: Install build tools
run: | run: |
@@ -36,14 +40,15 @@ jobs:
make \ make \
dpkg-dev \ dpkg-dev \
debhelper \ debhelper \
haskell-platform \
libghc-json-dev \ libghc-json-dev \
python-dev \
default-jdk \ default-jdk \
libtool-bin python-dev-is-python3 \
libtool-bin
cabal install alex happy
- name: Build package - name: Build package
run: | run: |
export PYTHONPATH="/home/runner/work/gf-core/gf-core/debian/gf/usr/local/lib/python3.12/dist-packages/"
make deb make deb
- name: Copy package - name: Copy package
@@ -51,27 +56,41 @@ jobs:
cp ../gf_*.deb dist/ cp ../gf_*.deb dist/
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: gf-${{ github.sha }}-ubuntu name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
path: dist/gf_*.deb path: dist/gf_*.deb
if-no-files-found: error if-no-files-found: error
- name: Rename package for specific ubuntu version
run: |
mv dist/gf_*.deb dist/gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
#- uses: actions/upload-release-asset@v1.0.2
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ github.event.release.upload_url }}
# asset_path: dist/gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
# asset_name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
# asset_content_type: application/octet-stream
# --- # ---
macos: macos:
name: Build macOS package name: Build macOS package
runs-on: macos-10.15
strategy: strategy:
matrix: matrix:
ghc: ["8.6.5"] ghc: ["9.6"]
cabal: ["2.4"] cabal: ["3.10"]
os: ["macos-latest", "macos-13"]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup Haskell - name: Setup Haskell
uses: actions/setup-haskell@v1 uses: haskell-actions/setup@v2
id: setup-haskell-cabal id: setup-haskell-cabal
with: with:
ghc-version: ${{ matrix.ghc }} ghc-version: ${{ matrix.ghc }}
@@ -80,8 +99,10 @@ jobs:
- name: Install build tools - name: Install build tools
run: | run: |
brew install \ brew install \
automake automake \
libtool
cabal v1-install alex happy cabal v1-install alex happy
pip install setuptools
- name: Build package - name: Build package
run: | run: |
@@ -90,21 +111,35 @@ jobs:
make pkg make pkg
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: gf-${{ github.sha }}-macos name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}
path: dist/gf-*.pkg path: dist/gf-*.pkg
if-no-files-found: error if-no-files-found: error
- name: Rename package
run: |
mv dist/gf-*.pkg dist/gf-${{ github.event.release.tag_name }}-macos.pkg
#- uses: actions/upload-release-asset@v1.0.2
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ github.event.release.upload_url }}
# asset_path: dist/gf-${{ github.event.release.tag_name }}-macos.pkg
# asset_name: gf-${{ github.event.release.tag_name }}-macos.pkg
# asset_content_type: application/octet-stream
# --- # ---
windows: windows:
name: Build Windows package name: Build Windows package
runs-on: windows-2019
strategy: strategy:
matrix: matrix:
ghc: ["8.6.5"] ghc: ["9.6.7"]
cabal: ["2.4"] cabal: ["3.10"]
os: ["windows-2022"]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -116,6 +151,7 @@ jobs:
base-devel base-devel
gcc gcc
python-devel python-devel
autotools
- name: Prepare dist folder - name: Prepare dist folder
shell: msys2 {0} shell: msys2 {0}
@@ -136,17 +172,23 @@ jobs:
cp /mingw64/bin/libpgf-0.dll /c/tmp-dist/c cp /mingw64/bin/libpgf-0.dll /c/tmp-dist/c
cp /mingw64/bin/libgu-0.dll /c/tmp-dist/c cp /mingw64/bin/libgu-0.dll /c/tmp-dist/c
# JAVA_HOME_8_X64 = C:\hostedtoolcache\windows\Java_Adopt_jdk\8.0.292-10\x64
- name: Build Java bindings - name: Build Java bindings
shell: msys2 {0} shell: msys2 {0}
run: | run: |
export PATH="${PATH}:/c/Program Files/Java/jdk8u275-b01/bin" echo $JAVA_HOME_8_X64
export JDKPATH="$(cygpath -u "${JAVA_HOME_8_X64}")"
export PATH="${PATH}:${JDKPATH}/bin"
cd src/runtime/java cd src/runtime/java
make \ make \
JNI_INCLUDES="-I \"/c/Program Files/Java/jdk8u275-b01/include\" -I \"/c/Program Files/Java/jdk8u275-b01/include/win32\" -I \"/mingw64/include\" -D__int64=int64_t" \ JNI_INCLUDES="-I \"${JDKPATH}/include\" -I \"${JDKPATH}/include/win32\" -I \"/mingw64/include\" -D__int64=int64_t" \
WINDOWS_LDFLAGS="-L\"/mingw64/lib\" -no-undefined" WINDOWS_LDFLAGS="-L\"/mingw64/lib\" -no-undefined"
make install make install
cp .libs//msys-jpgf-0.dll /c/tmp-dist/java/jpgf.dll cp .libs/msys-jpgf-0.dll /c/tmp-dist/java/jpgf.dll
cp jpgf.jar /c/tmp-dist/java cp jpgf.jar /c/tmp-dist/java
if: false
# - uses: actions/setup-python@v5
- name: Build Python bindings - name: Build Python bindings
shell: msys2 {0} shell: msys2 {0}
@@ -155,12 +197,13 @@ jobs:
EXTRA_LIB_DIRS: /mingw64/lib EXTRA_LIB_DIRS: /mingw64/lib
run: | run: |
cd src/runtime/python cd src/runtime/python
pacman --noconfirm -S python-setuptools
python setup.py build python setup.py build
python setup.py install python setup.py install
cp /usr/lib/python3.8/site-packages/pgf* /c/tmp-dist/python cp -r /usr/lib/python3.12/site-packages/pgf* /c/tmp-dist/python
- name: Setup Haskell - name: Setup Haskell
uses: actions/setup-haskell@v1 uses: haskell-actions/setup@v2
id: setup-haskell-cabal id: setup-haskell-cabal
with: with:
ghc-version: ${{ matrix.ghc }} ghc-version: ${{ matrix.ghc }}
@@ -172,14 +215,26 @@ jobs:
- name: Build GF - name: Build GF
run: | run: |
cabal install --only-dependencies -fserver cabal install -fserver --only-dependencies
cabal configure -fserver cabal configure -fserver
cabal build 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 - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: gf-${{ github.sha }}-windows name: gf-${{ github.event.release.tag_name }}-windows
path: C:\tmp-dist\* path: C:\tmp-dist\*
if-no-files-found: error if-no-files-found: error
- name: Create archive
run: |
Compress-Archive C:\tmp-dist C:\gf-${{ github.event.release.tag_name }}-windows.zip
#- uses: actions/upload-release-asset@v1.0.2
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ github.event.release.upload_url }}
# asset_path: C:\gf-${{ github.event.release.tag_name }}-windows.zip
# asset_name: gf-${{ github.event.release.tag_name }}-windows.zip
# asset_content_type: application/zip

View File

@@ -13,24 +13,25 @@ jobs:
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
os: [ubuntu-18.04, macos-10.15] os: [ubuntu-latest, macos-latest, macos-13]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v4
- uses: actions/setup-python@v1 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.7' python-version: '3.x'
- name: Install cibuildwheel - name: Install cibuildwheel
run: | run: |
python -m pip install git+https://github.com/joerick/cibuildwheel.git@main python -m pip install cibuildwheel
- name: Install build tools for OSX - name: Install build tools for OSX
if: startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'macos')
run: | run: |
brew install automake brew install automake
brew install libtool
- name: Build wheels on Linux - name: Build wheels on Linux
if: startsWith(matrix.os, 'macos') != true if: startsWith(matrix.os, 'macos') != true
@@ -42,30 +43,32 @@ jobs:
- name: Build wheels on OSX - name: Build wheels on OSX
if: startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'macos')
env: env:
CIBW_BEFORE_BUILD: cd src/runtime/c && glibtoolize && autoreconf -i && ./configure && make && make install CIBW_BEFORE_BUILD: cd src/runtime/c && glibtoolize && autoreconf -i && ./configure && make && sudo make install
run: | run: |
python -m cibuildwheel src/runtime/python --output-dir wheelhouse python -m cibuildwheel src/runtime/python --output-dir wheelhouse
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v4
with: with:
name: wheel-${{ matrix.os }}
path: ./wheelhouse path: ./wheelhouse
build_sdist: build_sdist:
name: Build source distribution name: Build source distribution
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.7' python-version: '3.10'
- name: Build sdist - name: Build sdist
run: cd src/runtime/python && python setup.py sdist run: cd src/runtime/python && python setup.py sdist
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v4
with: with:
name: wheel-source
path: ./src/runtime/python/dist/*.tar.gz path: ./src/runtime/python/dist/*.tar.gz
upload_pypi: upload_pypi:
@@ -75,24 +78,25 @@ jobs:
if: github.ref == 'refs/heads/master' && github.event_name == 'push' if: github.ref == 'refs/heads/master' && github.event_name == 'push'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v5
with: with:
python-version: '3.x' python-version: '3.x'
- name: Install twine - name: Install twine
run: pip install twine run: pip install twine
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v4.1.7
with: with:
name: artifact pattern: wheel-*
merge-multiple: true
path: ./dist path: ./dist
- name: Publish - name: Publish
env: env:
TWINE_USERNAME: __token__ TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.pypi_password }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: | 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/*

6
.gitignore vendored
View File

@@ -73,3 +73,9 @@ doc/icfp-2012.html
download/*.html download/*.html
gf-book/index.html gf-book/index.html
src/www/gf-web-api.html src/www/gf-web-api.html
.devenv
.direnv
result
.vscode
.envrc
.pre-commit-config.yaml

View File

@@ -1,14 +0,0 @@
sudo: required
language: c
services:
- docker
before_install:
- docker pull odanoburu/gf-src:3.9
script:
- |
docker run --mount src="$(pwd)",target=/home/gfer,type=bind odanoburu/gf-src:3.9 /bin/bash -c "cd /home/gfer/src/runtime/c &&
autoreconf -i && ./configure && make && make install ; cd /home/gfer ; cabal install -fserver -fc-runtime --extra-lib-dirs='/usr/local/lib'"

12
CHANGELOG.md Normal file
View File

@@ -0,0 +1,12 @@
### New since 3.12 (WIP)
### 3.12
See <https://www.grammaticalframework.org/download/release-3.12.html>
### 3.11
See <https://www.grammaticalframework.org/download/release-3.11.html>
### 3.10
See <https://www.grammaticalframework.org/download/release-3.10.html>

View File

@@ -1,31 +1,48 @@
.PHONY: all build install doc clean gf html deb pkg bintar sdist .PHONY: all build install doc clean html deb pkg bintar sdist
# This gets the numeric part of the version from the cabal file # This gets the numeric part of the version from the cabal file
VERSION=$(shell sed -ne "s/^version: *\([0-9.]*\).*/\1/p" gf.cabal) VERSION=$(shell sed -ne "s/^version: *\([0-9.]*\).*/\1/p" gf.cabal)
# Check if stack is installed
STACK=$(shell if hash stack 2>/dev/null; then echo "1"; else echo "0"; fi)
# Check if cabal >= 2.4 is installed (with v1- and v2- commands)
CABAL_NEW=$(shell if cabal v1-repl --help >/dev/null 2>&1 ; then echo "1"; else echo "0"; fi)
ifeq ($(STACK),1)
CMD=stack
else
CMD=cabal
ifeq ($(CABAL_NEW),1)
CMD_PFX=v1-
endif
endif
all: build all: build
dist/setup-config: gf.cabal Setup.hs WebSetup.hs dist/setup-config: gf.cabal Setup.hs WebSetup.hs
cabal configure ifneq ($(STACK),1)
cabal ${CMD_PFX}configure
endif
build: dist/setup-config build: dist/setup-config
cabal build ${CMD} ${CMD_PFX}build
install: install:
cabal copy ifeq ($(STACK),1)
cabal register stack install
else
cabal ${CMD_PFX}copy
cabal ${CMD_PFX}register
endif
doc: doc:
cabal haddock ${CMD} ${CMD_PFX}haddock
clean: clean:
cabal clean ${CMD} ${CMD_PFX}clean
bash bin/clean_html bash bin/clean_html
gf:
cabal build rgl-none
strip dist/build/gf/gf
html:: html::
bash bin/update_html bash bin/update_html
@@ -33,9 +50,9 @@ html::
# number to the top of debian/changelog. # number to the top of debian/changelog.
# (Tested on Ubuntu 15.04. You need to install dpkg-dev & debhelper.) # (Tested on Ubuntu 15.04. You need to install dpkg-dev & debhelper.)
deb: deb:
dpkg-buildpackage -b -uc dpkg-buildpackage -b -uc -d
# Make an OS X Installer package # Make a macOS installer package
pkg: pkg:
FMT=pkg bash bin/build-binary-dist.sh FMT=pkg bash bin/build-binary-dist.sh
@@ -48,6 +65,6 @@ bintar:
# Make a source tar.gz distribution using git to make sure that everything is included. # Make a source tar.gz distribution using git to make sure that everything is included.
# We put the distribution in dist/ so it is removed on `make clean` # We put the distribution in dist/ so it is removed on `make clean`
sdist: # sdist:
test -d dist || mkdir dist # test -d dist || mkdir dist
git archive --format=tar.gz --output=dist/gf-${VERSION}.tar.gz HEAD # git archive --format=tar.gz --output=dist/gf-${VERSION}.tar.gz HEAD

View File

@@ -1,4 +1,4 @@
![GF Logo](doc/Logos/gf1.svg) ![GF Logo](https://www.grammaticalframework.org/doc/Logos/gf1.svg)
# Grammatical Framework (GF) # Grammatical Framework (GF)
@@ -38,8 +38,23 @@ or:
``` ```
stack install stack install
``` ```
Note that if you are unlucky to have Cabal 3.0 or later, then it uses
the so-called Nix style commands. Using those for GF development is
a pain. Every time when you change something in the source code, Cabal
will generate a new folder for GF to look for the GF libraries and
the GF cloud. Either reinstall everything with every change in the
compiler, or be sane and stop using cabal-install. Instead you can do:
```
runghc Setup.hs configure
runghc Setup.hs build
sudo runghc Setup.hs install
```
The script will install the GF dependencies globally. The only solution
to the Nix madness that I found is radical:
For more information, including links to precompiled binaries, see the [download page](http://www.grammaticalframework.org/download/index.html). "No person, no problem" (Нет человека нет проблемы).
For more information, including links to precompiled binaries, see the [download page](https://www.grammaticalframework.org/download/index.html).
## About this repository ## About this repository

View File

@@ -47,11 +47,14 @@ but the generated _artifacts_ must be manually attached to the release as _asset
In order to do this you will need to be added the [GF maintainers](https://hackage.haskell.org/package/gf/maintainers/) on Hackage. In order to do this you will need to be added the [GF maintainers](https://hackage.haskell.org/package/gf/maintainers/) on Hackage.
1. Run `make sdist` 1. Run `stack sdist --test-tarball` and address any issues.
2. Upload the package, either: 2. Upload the package, either:
1. **Manually**: visit <https://hackage.haskell.org/upload> and upload the file `dist/gf-X.Y.tar.gz` 1. **Manually**: visit <https://hackage.haskell.org/upload> and upload the file generated by the previous command.
2. **via Cabal (≥2.4)**: `cabal upload dist/gf-X.Y.tar.gz` 2. **via Stack**: `stack upload . --candidate`
3. If the documentation-building fails on the Hackage server, do: 3. After testing the candidate, publish it:
1. **Manually**: visit <https://hackage.haskell.org/package/gf-X.Y.Z/candidate/publish>
1. **via Stack**: `stack upload .`
4. If the documentation-building fails on the Hackage server, do:
``` ```
cabal v2-haddock --builddir=dist/docs --haddock-for-hackage --enable-doc cabal v2-haddock --builddir=dist/docs --haddock-for-hackage --enable-doc
cabal upload --documentation dist/docs/*-docs.tar.gz cabal upload --documentation dist/docs/*-docs.tar.gz

View File

@@ -4,42 +4,68 @@ import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..),absoluteInstallDirs
import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..)) import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..))
import Distribution.PackageDescription(PackageDescription(..),emptyHookedBuildInfo) import Distribution.PackageDescription(PackageDescription(..),emptyHookedBuildInfo)
import Distribution.Simple.BuildPaths(exeExtension) import Distribution.Simple.BuildPaths(exeExtension)
import System.Directory
import System.FilePath((</>),(<.>)) import System.FilePath((</>),(<.>))
import System.Process
import Control.Monad(forM_,unless)
import Control.Exception(bracket_)
import Data.Char(isSpace)
import WebSetup import WebSetup
-- | Notice about RGL not built anymore
noRGLmsg :: IO ()
noRGLmsg = putStrLn "Notice: the RGL is not built as part of GF anymore. See https://github.com/GrammaticalFramework/gf-rgl"
main :: IO () main :: IO ()
main = defaultMainWithHooks simpleUserHooks main = defaultMainWithHooks simpleUserHooks
{ preBuild = gfPreBuild { preConf = gfPreConf
, preBuild = gfPreBuild
, postBuild = gfPostBuild , postBuild = gfPostBuild
, preInst = gfPreInst , preInst = gfPreInst
, postInst = gfPostInst , postInst = gfPostInst
, postCopy = gfPostCopy , postCopy = gfPostCopy
} }
where where
gfPreBuild args = gfPre args . buildDistPref gfPreConf args flags = do
gfPreInst args = gfPre args . installDistPref pkgs <- fmap (map (dropWhile isSpace) . tail . lines)
(readProcess "ghc-pkg" ["list"] "")
forM_ dependencies $ \pkg -> do
let name = takeWhile (/='/') (drop 36 pkg)
unless (name `elem` pkgs) $ do
let fname = name <.> ".tar.gz"
callProcess "wget" [pkg,"-O",fname]
callProcess "tar" ["-xzf",fname]
removeFile fname
bracket_ (setCurrentDirectory name) (setCurrentDirectory ".." >> removeDirectoryRecursive name) $ do
exists <- doesFileExist "Setup.hs"
unless exists $ do
writeFile "Setup.hs" (unlines [
"import Distribution.Simple",
"main = defaultMain"
])
let to_descr = reverse .
(++) (reverse ".cabal") .
drop 1 .
dropWhile (/='-') .
reverse
callProcess "wget" [to_descr pkg, "-O", to_descr name]
callProcess "runghc" ["Setup.hs","configure"]
callProcess "runghc" ["Setup.hs","build"]
callProcess "sudo" ["runghc","Setup.hs","install"]
preConf simpleUserHooks args flags
gfPreBuild args = gfPre args . buildDistPref
gfPreInst args = gfPre args . installDistPref
gfPre args distFlag = do gfPre args distFlag = do
return emptyHookedBuildInfo return emptyHookedBuildInfo
gfPostBuild args flags pkg lbi = do gfPostBuild args flags pkg lbi = do
-- noRGLmsg
let gf = default_gf lbi let gf = default_gf lbi
buildWeb gf flags (pkg,lbi) buildWeb gf flags (pkg,lbi)
gfPostInst args flags pkg lbi = do gfPostInst args flags pkg lbi = do
-- noRGLmsg
saveInstallPath args flags (pkg,lbi)
installWeb (pkg,lbi) installWeb (pkg,lbi)
gfPostCopy args flags pkg lbi = do gfPostCopy args flags pkg lbi = do
-- noRGLmsg
saveCopyPath args flags (pkg,lbi)
copyWeb flags (pkg,lbi) copyWeb flags (pkg,lbi)
-- `cabal sdist` will not make a proper dist archive, for that see `make sdist` -- `cabal sdist` will not make a proper dist archive, for that see `make sdist`
@@ -47,27 +73,16 @@ main = defaultMainWithHooks simpleUserHooks
gfSDist pkg lbi hooks flags = do gfSDist pkg lbi hooks flags = do
return () return ()
saveInstallPath :: [String] -> InstallFlags -> (PackageDescription, LocalBuildInfo) -> IO () dependencies = [
saveInstallPath args flags bi = do "https://hackage.haskell.org/package/utf8-string-1.0.2/utf8-string-1.0.2.tar.gz",
let "https://hackage.haskell.org/package/json-0.10/json-0.10.tar.gz",
dest = NoCopyDest "https://hackage.haskell.org/package/network-bsd-2.8.1.0/network-bsd-2.8.1.0.tar.gz",
dir = datadir (uncurry absoluteInstallDirs bi dest) "https://hackage.haskell.org/package/httpd-shed-0.4.1.1/httpd-shed-0.4.1.1.tar.gz",
writeFile dataDirFile dir "https://hackage.haskell.org/package/exceptions-0.10.5/exceptions-0.10.5.tar.gz",
"https://hackage.haskell.org/package/stringsearch-0.3.6.6/stringsearch-0.3.6.6.tar.gz",
saveCopyPath :: [String] -> CopyFlags -> (PackageDescription, LocalBuildInfo) -> IO () "https://hackage.haskell.org/package/multipart-0.2.1/multipart-0.2.1.tar.gz",
saveCopyPath args flags bi = do "https://hackage.haskell.org/package/cgi-3001.5.0.0/cgi-3001.5.0.0.tar.gz"
let ]
dest = case copyDest flags of
NoFlag -> NoCopyDest
Flag d -> d
dir = datadir (uncurry absoluteInstallDirs bi dest)
writeFile dataDirFile dir
-- | Name of file where installation's data directory is recording
-- This is a last-resort way in which the seprate RGL build script
-- can determine where to put the compiled RGL files
dataDirFile :: String
dataDirFile = "DATA_DIR"
-- | Get path to locally-built gf -- | Get path to locally-built gf
default_gf :: LocalBuildInfo -> FilePath default_gf :: LocalBuildInfo -> FilePath

View File

@@ -32,7 +32,7 @@ set -x # print commands before executing them
pushd src/runtime/c pushd src/runtime/c
bash setup.sh configure --prefix="$prefix" bash setup.sh configure --prefix="$prefix"
bash setup.sh build 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" bash setup.sh install prefix="$destdir$prefix"
popd popd
@@ -46,7 +46,7 @@ if which >/dev/null python; then
pyver=$(ls "$destdir$prefix/lib" | sed -n 's/^python//p') pyver=$(ls "$destdir$prefix/lib" | sed -n 's/^python//p')
pydest="$destdir/Library/Python/$pyver/site-packages" pydest="$destdir/Library/Python/$pyver/site-packages"
mkdir -p "$pydest" 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 fi
popd popd
else else

11
debian/changelog vendored
View File

@@ -1,3 +1,14 @@
gf (3.12) noble; urgency=low
* GF 3.12
-- Inari Listenmaa <inari@digitalgrammars.com> Fri, 8 Aug 2025 18:29:29 +0100
gf (3.11) bionic focal; urgency=low
* GF 3.11
-- Inari Listenmaa <inari@digitalgrammars.com> Sun, 25 Jul 2021 10:27:40 +0800
gf (3.10.4-1) xenial bionic cosmic; urgency=low gf (3.10.4-1) xenial bionic cosmic; urgency=low
* GF 3.10.4 * GF 3.10.4

2
debian/control vendored
View File

@@ -3,7 +3,7 @@ Section: devel
Priority: optional Priority: optional
Maintainer: Thomas Hallgren <hallgren@chalmers.se> Maintainer: Thomas Hallgren <hallgren@chalmers.se>
Standards-Version: 3.9.2 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/ Homepage: http://www.grammaticalframework.org/
Package: gf Package: gf

18
debian/rules vendored
View File

@@ -17,28 +17,30 @@ override_dh_auto_configure:
cd src/runtime/c && bash setup.sh configure --prefix=/usr cd src/runtime/c && bash setup.sh configure --prefix=/usr
cd src/runtime/c && bash setup.sh build cd src/runtime/c && bash setup.sh build
cabal update cabal update
cabal install --only-dependencies cabal v1-install --only-dependencies
cabal configure --prefix=/usr -fserver -fc-runtime --extra-lib-dirs=$(CURDIR)/src/runtime/c/.libs --extra-include-dirs=$(CURDIR)/src/runtime/c cabal v1-configure --prefix=/usr -fserver -fc-runtime --extra-lib-dirs=$(CURDIR)/src/runtime/c/.libs --extra-include-dirs=$(CURDIR)/src/runtime/c
SET_LDL=LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs SET_LDL=LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs
override_dh_auto_build: 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/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) echo $(SET_LDL)
-$(SET_LDL) cabal build -$(SET_LDL) cabal v1-build
override_dh_auto_install: override_dh_auto_install:
$(SET_LDL) cabal copy --destdir=$(CURDIR)/debian/gf $(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/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/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr install # 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 # D="`find debian/gf -name dist-packages`" && [ -n "$$D" ] && cd $$D && cd .. && mv dist-packages dist-packages
override_dh_usrlocal:
override_dh_auto_clean: override_dh_auto_clean:
rm -fr dist/build rm -fr dist/build
-cd src/runtime/python && rm -fr 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 -cd src/runtime/c && make clean
override_dh_auto_test: override_dh_auto_test:

View File

@@ -0,0 +1,201 @@
GF Developer's Guide: Old installation instructions with Cabal
This page contains the old installation instructions from the [Developer's Guide ../doc/gf-developers.html].
We recommend Stack as a primary installation method, because it's easier for a Haskell beginner, and we want to keep the main instructions short.
But if you are an experienced Haskeller and want to keep using Cabal, here are the old instructions using ``cabal install``.
Note that some of these instructions may be outdated. Other parts may still be useful.
== Compilation from source with Cabal ==
The build system of GF is based on //Cabal//, which is part of the
Haskell Platform, so no extra steps are needed to install it. In the simplest
case, all you need to do to compile and install GF, after downloading the
source code as described above, is
```
$ cabal install
```
This will automatically download any additional Haskell libraries needed to
build GF. If this is the first time you use Cabal, you might need to run
``cabal update`` first, to update the list of available libraries.
If you want more control, the process can also be split up into the usual
//configure//, //build// and //install// steps.
=== Configure ===
During the configuration phase Cabal will check that you have all
necessary tools and libraries needed for GF. The configuration is
started by the command:
```
$ cabal configure
```
If you don't see any error message from the above command then you
have everything that is needed for GF. You can also add the option
``-v`` to see more details about the configuration.
You can use ``cabal configure --help`` to get a list of configuration options.
=== Build ===
The build phase does two things. First it builds the GF compiler from
the Haskell source code and after that it builds the GF Resource Grammar
Library using the already build compiler. The simplest command is:
```
$ cabal build
```
Again you can add the option ``-v`` if you want to see more details.
==== Parallel builds ====
If you have Cabal>=1.20 you can enable parallel compilation by using
```
$ cabal build -j
```
or by putting a line
```
jobs: $ncpus
```
in your ``.cabal/config`` file. Cabal
will pass this option to GHC when building the GF compiler, if you
have GHC>=7.8.
Cabal also passes ``-j`` to GF to enable parallel compilation of the
Resource Grammar Library. This is done unconditionally to avoid
causing problems for developers with Cabal<1.20. You can disable this
by editing the last few lines in ``WebSetup.hs``.
=== Install ===
After you have compiled GF you need to install the executable and libraries
to make the system usable.
```
$ cabal copy
$ cabal register
```
This command installs the GF compiler for a single user, in the standard
place used by Cabal.
On Linux and Mac this could be ``$HOME/.cabal/bin``.
On Mac it could also be ``$HOME/Library/Haskell/bin``.
On Windows this is ``C:\Program Files\Haskell\bin``.
The compiled GF Resource Grammar Library will be installed
under the same prefix, e.g. in
``$HOME/.cabal/share/gf-3.3.3/lib`` on Linux and
in ``C:\Program Files\Haskell\gf-3.3.3\lib`` on Windows.
If you want to install in some other place then use the ``--prefix``
option during the configuration phase.
=== Clean ===
Sometimes you want to clean up the compilation and start again from clean
sources. Use the clean command for this purpose:
```
$ cabal clean
```
%=== SDist ===
%
%You can use the command:
%
%% This does *NOT* include everything that is needed // TH 2012-08-06
%```
%$ cabal sdist
%```
%
%to prepare archive with all source codes needed to compile GF.
=== Known problems with Cabal ===
Some versions of Cabal (at least version 1.16) seem to have a bug that can
cause the following error:
```
Configuring gf-3.x...
setup: Distribution/Simple/PackageIndex.hs:124:8-13: Assertion failed
```
The exact cause of this problem is unclear, but it seems to happen
during the configure phase if the same version of GF is already installed,
so a workaround is to remove the existing installation with
```
ghc-pkg unregister gf
```
You can check with ``ghc-pkg list gf`` that it is gone.
== Compilation with make ==
If you feel more comfortable with Makefiles then there is a thin Makefile
wrapper arround Cabal for you. If you just type:
```
$ make
```
the configuration phase will be run automatically if needed and after that
the sources will be compiled.
%% cabal build rgl-none does not work with recent versions of Cabal
%If you don't want to compile the resource library
%every time then you can use:
%```
%$ make gf
%```
For installation use:
```
$ make install
```
For cleaning:
```
$ make clean
```
%and to build source distribution archive run:
%```
%$ make sdist
%```
== Partial builds of RGL ==
**NOTE**: The following doesn't work with recent versions of ``cabal``. //(This comment was left in 2015, so make your own conclusions.)//
%% // TH 2015-06-22
%Sometimes you just want to work on the GF compiler and don't want to
%recompile the resource library after each change. In this case use
%this extended command:
%```
%$ cabal build rgl-none
%```
The resource grammar library can be compiled in two modes: with present
tense only and with all tenses. By default it is compiled with all
tenses. If you want to use the library with only present tense you can
compile it in this special mode with the command:
```
$ cabal build present
```
You could also control which languages you want to be recompiled by
adding the option ``langs=list``. For example the following command
will compile only the English and the Swedish language:
```
$ cabal build langs=Eng,Swe
```

View File

@@ -1,6 +1,6 @@
GF Developers Guide GF Developers Guide
2018-07-26 2021-07-15
%!options(html): --toc %!options(html): --toc
@@ -15,388 +15,304 @@ you are a GF user who just wants to download and install GF
== Setting up your system for building GF == == Setting up your system for building GF ==
To build GF from source you need to install some tools on your To build GF from source you need to install some tools on your
system: the //Haskell Platform//, //Git// and the //Haskeline library//. system: the Haskell build tool //Stack//, the version control software //Git// and the //Haskeline// library.
**On Linux** the best option is to install the tools via the standard %**On Linux** the best option is to install the tools via the standard
software distribution channels, i.e. by using the //Software Center// %software distribution channels, i.e. by using the //Software Center//
in Ubuntu or the corresponding tool in other popular Linux distributions. %in Ubuntu or the corresponding tool in other popular Linux distributions.
Or, from a Terminal window, the following command should be enough:
- On Ubuntu: ``sudo apt-get install haskell-platform git libghc6-haskeline-dev`` %**On Mac OS and Windows**, the tools can be downloaded from their respective
- On Fedora: ``sudo dnf install haskell-platform git ghc-haskeline-devel`` %web sites, as described below.
=== Stack ===
The primary installation method is via //Stack//.
(You can also use Cabal, but we recommend Stack to those who are new to Haskell.)
To install Stack:
- **On Linux and Mac OS**, do either
``$ curl -sSL https://get.haskellstack.org/ | sh``
or
``$ wget -qO- https://get.haskellstack.org/ | sh``
**On Mac OS and Windows**, the tools can be downloaded from their respective - **On other operating systems**, see the [installation guide https://docs.haskellstack.org/en/stable/install_and_upgrade].
web sites, as described below.
=== The Haskell Platform ===
GF is written in Haskell, so first of all you need %If you already have Stack installed, upgrade it to the latest version by running: ``stack upgrade``
the //Haskell Platform//, e.g. version 8.0.2 or 7.10.3. Downloads
and installation instructions are available from here:
http://hackage.haskell.org/platform/
Once you have installed the Haskell Platform, open a terminal
(Command Prompt on Windows) and try to execute the following command:
```
$ ghc --version
```
This command should show you which version of GHC you have. If the installation
of the Haskell Platform was successful you should see a message like:
```
The Glorious Glasgow Haskell Compilation System, version 8.0.2
```
Other required tools included in the Haskell Platform are
[Cabal http://www.haskell.org/cabal/],
[Alex http://www.haskell.org/alex/]
and
[Happy http://www.haskell.org/happy/].
=== Git === === Git ===
To get the GF source code, you also need //Git//. To get the GF source code, you also need //Git//, a distributed version control system.
//Git// is a distributed version control system, see
https://git-scm.com/downloads for more information.
=== The haskeline library === - **On Linux**, the best option is to install the tools via the standard
software distribution channels:
- On Ubuntu: ``sudo apt-get install git-all``
- On Fedora: ``sudo dnf install git-all``
- **On other operating systems**, see
https://git-scm.com/book/en/v2/Getting-Started-Installing-Git for installation.
=== Haskeline ===
GF uses //haskeline// to enable command line editing in the GF shell. GF uses //haskeline// to enable command line editing in the GF shell.
This should work automatically on Mac OS and Windows, but on Linux one
extra step is needed to make sure the C libraries (terminfo)
required by //haskeline// are installed. Here is one way to do this:
- On Ubuntu: ``sudo apt-get install libghc-haskeline-dev`` - **On Mac OS and Windows**, this should work automatically.
- On Fedora: ``sudo dnf install ghc-haskeline-devel``
- **On Linux**, an extra step is needed to make sure the C libraries (terminfo)
required by //haskeline// are installed:
- On Ubuntu: ``sudo apt-get install libghc-haskeline-dev``
- On Fedora: ``sudo dnf install ghc-haskeline-devel``
== Getting the source == == Getting the source ==[getting-source]
Once you have all tools in place you can get the GF source code. If you Once you have all tools in place you can get the GF source code from
just want to compile and use GF then it is enough to have read-only [GitHub https://github.com/GrammaticalFramework/]:
access. It is also possible to make changes in the source code but if you
want these changes to be applied back to the main source repository you will
have to send the changes to us. If you plan to work continuously on
GF then you should consider getting read-write access.
=== Read-only access === - https://github.com/GrammaticalFramework/gf-core for the GF compiler
- https://github.com/GrammaticalFramework/gf-rgl for the Resource Grammar Library
==== Getting a fresh copy for read-only access ====
Anyone can get the latest development version of GF by running: === Read-only access: clone the main repository ===
If you only want to compile and use GF, you can just clone the repositories as follows:
``` ```
$ git clone https://github.com/GrammaticalFramework/gf-core.git $ git clone https://github.com/GrammaticalFramework/gf-core.git
$ git clone https://github.com/GrammaticalFramework/gf-rgl.git $ git clone https://github.com/GrammaticalFramework/gf-rgl.git
``` ```
This will create directories ``gf-core`` and ``gf-rgl`` in the current directory. To get new updates, run the following anywhere in your local copy of the repository:
==== Updating your copy ====
To get all new patches from each repo:
```
$ git pull
```
This can be done anywhere in your local repository.
==== Recording local changes ====[record]
Since every copy is a repository, you can have local version control
of your changes.
If you have added files, you first need to tell your local repository to
keep them under revision control:
``` ```
$ git add file1 file2 ... $ git pull
``` ```
To record changes, use: === Contribute your changes: fork the main repository ===
If you want the possibility to contribute your changes,
you should create your own fork, do your changes there,
and then send a pull request to the main repository.
+ **Creating and cloning a fork —**
See GitHub documentation for instructions how to [create your own fork https://docs.github.com/en/get-started/quickstart/fork-a-repo]
of the repository. Once you've done it, clone the fork to your local computer.
``` ```
$ git commit file1 file2 ... $ git clone https://github.com/<YOUR_USERNAME>/gf-core.git
``` ```
This creates a patch against the previous version and stores it in your + **Updating your copy —**
local repository. You can record any number of changes before Once you have cloned your fork, you need to set up the main repository as a remote:
pushing them to the main repo. In fact, you don't have to push them at
all if you want to keep the changes only in your local repo.
Instead of enumerating all modified files on the command line,
you can use the flag ``-a`` to automatically record //all// modified
files. You still need to use ``git add`` to add new files.
=== Read-write access ===
If you are a member of the GF project on GitHub, you can push your
changes directly to the GF git repository on GitHub.
``` ```
$ git push $ git remote add upstream https://github.com/GrammaticalFramework/gf-core.git
``` ```
It is also possible for anyone else to contribute by Then you can get the latest updates by running the following:
- creating a fork of the GF repository on GitHub, ```
- working with local clone of the fork (obtained with ``git clone``), $ git pull upstream master
- pushing changes to the fork, ```
- and finally sending a pull request.
+ **Recording local changes —**
See Git tutorial on how to [record and push your changes https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository] to your fork.
+ **Pull request —**
When you want to contribute your changes to the main gf-core repository,
[create a pull request https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request]
from your fork.
== Compilation from source with Cabal == If you want to contribute to the RGL as well, do the same process for the RGL repository.
The build system of GF is based on //Cabal//, which is part of the
Haskell Platform, so no extra steps are needed to install it. In the simplest == Compilation from source ==
case, all you need to do to compile and install GF, after downloading the
source code as described above, is By now you should have installed Stack and Haskeline, and cloned the Git repository on your own computer, in a directory called ``gf-core``.
=== Primary recommendation: use Stack ===
Open a terminal, go to the top directory (``gf-core``), and type the following command.
```
$ stack install
```
=== Alternative: use Cabal ===
If you prefer Cabal, then you just need to manually choose a suitable GHC to build GF. We recommend GHC 9.6.7, see other supported options in [gf.cabal https://github.com/GrammaticalFramework/gf-core/blob/master/gf.cabal#L14].
The actual installation process is similar to Stack: open a terminal, go to the top directory (``gf-core``), and type the following command.
``` ```
$ cabal install $ cabal install
``` ```
This will automatically download any additional Haskell libraries needed to === Nix ===
build GF. If this is the first time you use Cabal, you might need to run
``cabal update`` first, to update the list of available libraries.
If you want more control, the process can also be split up into the usual As of 3.12, GF can also be installed via Nix. You can install GF from github with the following command:
//configure//, //build// and //install// steps.
=== Configure ===
During the configuration phase Cabal will check that you have all
necessary tools and libraries needed for GF. The configuration is
started by the command:
``` ```
$ cabal configure nix profile install github:GrammaticalFramework/gf-core#gf
``` ```
If you don't see any error message from the above command then you == Compiling GF with C runtime system support ==
have everything that is needed for GF. You can also add the option
``-v`` to see more details about the configuration.
You can use ``cabal configure --help`` to get a list of configuration options. The C runtime system is a separate implementation of the PGF runtime services.
=== Build ===
The build phase does two things. First it builds the GF compiler from
the Haskell source code and after that it builds the GF Resource Grammar
Library using the already build compiler. The simplest command is:
```
$ cabal build
```
Again you can add the option ``-v`` if you want to see more details.
==== Parallel builds ====
If you have Cabal>=1.20 you can enable parallel compilation by using
```
$ cabal build -j
```
or by putting a line
```
jobs: $ncpus
```
in your ``.cabal/config`` file. Cabal
will pass this option to GHC when building the GF compiler, if you
have GHC>=7.8.
Cabal also passes ``-j`` to GF to enable parallel compilation of the
Resource Grammar Library. This is done unconditionally to avoid
causing problems for developers with Cabal<1.20. You can disable this
by editing the last few lines in ``WebSetup.hs``.
==== Partial builds ====
**NOTE**: The following doesn't work with recent versions of ``cabal``.
%% // TH 2015-06-22
Sometimes you just want to work on the GF compiler and don't want to
recompile the resource library after each change. In this case use
this extended command:
```
$ cabal build rgl-none
```
The resource library could also be compiled in two modes: with present
tense only and with all tenses. By default it is compiled with all
tenses. If you want to use the library with only present tense you can
compile it in this special mode with the command:
```
$ cabal build present
```
You could also control which languages you want to be recompiled by
adding the option ``langs=list``. For example the following command
will compile only the English and the Swedish language:
```
$ cabal build langs=Eng,Swe
```
=== Install ===
After you have compiled GF you need to install the executable and libraries
to make the system usable.
```
$ cabal copy
$ cabal register
```
This command installs the GF compiler for a single user, in the standard
place used by Cabal.
On Linux and Mac this could be ``$HOME/.cabal/bin``.
On Mac it could also be ``$HOME/Library/Haskell/bin``.
On Windows this is ``C:\Program Files\Haskell\bin``.
The compiled GF Resource Grammar Library will be installed
under the same prefix, e.g. in
``$HOME/.cabal/share/gf-3.3.3/lib`` on Linux and
in ``C:\Program Files\Haskell\gf-3.3.3\lib`` on Windows.
If you want to install in some other place then use the ``--prefix``
option during the configuration phase.
=== Clean ===
Sometimes you want to clean up the compilation and start again from clean
sources. Use the clean command for this purpose:
```
$ cabal clean
```
%=== SDist ===
%
%You can use the command:
%
%% This does *NOT* include everything that is needed // TH 2012-08-06
%```
%$ cabal sdist
%```
%
%to prepare archive with all source codes needed to compile GF.
=== Known problems with Cabal ===
Some versions of Cabal (at least version 1.16) seem to have a bug that can
cause the following error:
```
Configuring gf-3.x...
setup: Distribution/Simple/PackageIndex.hs:124:8-13: Assertion failed
```
The exact cause of this problem is unclear, but it seems to happen
during the configure phase if the same version of GF is already installed,
so a workaround is to remove the existing installation with
```
ghc-pkg unregister gf
```
You can check with ``ghc-pkg list gf`` that it is gone.
== Compilation with make ==
If you feel more comfortable with Makefiles then there is a thin Makefile
wrapper arround Cabal for you. If you just type:
```
$ make
```
the configuration phase will be run automatically if needed and after that
the sources will be compiled.
%% cabal build rgl-none does not work with recent versions of Cabal
%If you don't want to compile the resource library
%every time then you can use:
%```
%$ make gf
%```
For installation use:
```
$ make install
```
For cleaning:
```
$ make clean
```
%and to build source distribution archive run:
%```
%$ make sdist
%```
== Compiling GF with C run-time system support ==
The C run-time system is a separate implementation of the PGF run-time services.
It makes it possible to work with very large, ambiguous grammars, using It makes it possible to work with very large, ambiguous grammars, using
probabilistic models to obtain probable parses. The C run-time system might probabilistic models to obtain probable parses. The C runtime system might
also be easier to use than the Haskell run-time system on certain platforms, also be easier to use than the Haskell runtime system on certain platforms,
e.g. Android and iOS. e.g. Android and iOS.
To install the C run-time system, go to the ``src/runtime/c`` directory To install the C runtime system, go to the ``src/runtime/c`` directory.
%and follow the instructions in the ``INSTALL`` file.
and use the ``install.sh`` script:
```
bash setup.sh configure
bash setup.sh build
bash setup.sh install
```
This will install
the C header files and libraries need to write C programs that use PGF grammars.
Some example C programs are included in the ``utils`` subdirectory, e.g.
``pgf-translate.c``.
When the C run-time system is installed, you can install GF with C run-time - **On Linux and Mac OS —**
support by doing You should have autoconf, automake, libtool and make.
If you are missing some of them, follow the
instructions in the [INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file.
Once you have the required libraries, the easiest way to install the C runtime is to use the ``install.sh`` script. Just type
``$ bash install.sh``
This will install the C header files and libraries need to write C programs
that use PGF grammars.
% If this doesn't work for you, follow the manual instructions in the [INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file under your operating system.
- **On other operating systems —** Follow the instructions in the
[INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file under your operating system.
Depending on what you want to do with the C runtime, you can follow one or more of the following steps.
=== Use the C runtime from another programming language ===[bindings]
% **If you just want to use the C runtime from Python or Haskell, you don't need to change your GF installation.**
- **What —**
This is the most common use case for the C runtime: compile
your GF grammars into PGF with the standard GF executable,
and manipulate the PGFs from another programming language,
using the bindings to the C runtime.
- **How —**
The Python, Java and Haskell bindings are found in the
``src/runtime/{python,java,haskell-bind}`` directories,
respecively. Compile them by following the instructions
in the ``INSTALL`` or ``README`` files in those directories.
The Python library can also be installed from PyPI using ``pip install pgf``.
//If you are on Mac and get an error about ``clang`` version, you can try some of [these solutions https://stackoverflow.com/questions/63972113/big-sur-clang-invalid-version-error-due-to-macosx-deployment-target]—but be careful before removing any existing installations.//
=== Use GF shell with C runtime support ===
- **What —**
If you want to use the GF shell with C runtime functionalities, then you need to (re)compile GF with special flags.
The GF shell can be started with ``gf -cshell`` or ``gf -crun`` to use
the C run-time system instead of the Haskell run-time system.
Only limited functionality is available when running the shell in these
modes (use the ``help`` command in the shell for details).
(Re)compiling your GF with these flags will also give you
Haskell bindings to the C runtime, as a library called ``PGF2``,
but if you want Python bindings, you need to do [the previous step #bindings].
% ``PGF2``: a module to import in Haskell programs, providing a binding to the C run-time system.
- **How —**
Add (or uncomment) the following lines in the ``stack.yaml`` file:
``` ```
cabal install -fserver -fc-runtime flags:
gf:
c-runtime: true
extra-lib-dirs:
- /usr/local/lib
``` ```
from the top directory. This give you three new things: and then run ``stack install`` from the top directory (``gf-core``).
- ``PGF2``: a module to import in Haskell programs, providing a binding to Run the newly built executable with the flag ``-cshell``, and you should see the following welcome message:
the C run-time system.
- The GF shell can be started with ``gf -cshell`` or ``gf -crun`` to use ```
the C run-time system instead of the Haskell run-time system. $ gf -cshell
Only limited functionality is available when running the shell in these
modes (use the ``help`` command in the shell for details).
- ``gf -server`` mode is extended with new requests to call the C run-time * * *
system, e.g. ``c-parse``, ``c-linearize`` and ``c-translate``. * *
* *
*
*
* * * * * * *
* * *
* * * * * *
* * *
* * *
This is GF version 3.12.0.
Built on ...
Git info: ...
Flags: interrupt server c-runtime
License: see help -license.
This shell uses the C run-time system. See help for available commands.
>
```
//If you get an "``error while loading shared libraries``" when trying to run GF with C runtime, remember to declare your ``LD_LIBRARY_PATH``.//
//Add ``export LD_LIBRARY_PATH="/usr/local/lib"`` to either your ``.bashrc`` or ``.profile``. You should now be able to start GF with C runtime.//
=== Python and Java bindings === === Use GF server mode with C runtime ===
- **What —**
With this feature, ``gf -server`` mode is extended with new requests to call the C run-time
system, e.g. ``c-parse``, ``c-linearize`` and ``c-translate``.
- **How —**
Add the following lines in the ``stack.yaml`` file:
```
flags:
gf:
c-runtime: true
server: true
extra-lib-dirs:
- /usr/local/lib
```
and then run ``stack install``, also from the top directory.
The C run-time system can also be used from Python and Java. Python and Java
bindings are found in the ``src/runtime/python`` and ``src/runtime/java``
directories, respecively. Compile them by following the instructions in
the ``INSTALL`` files in those directories.
The Python library can also be installed from PyPI using `pip install pgf`.
== Compilation of RGL == == Compilation of RGL ==
As of 2018-07-26, the RGL is distributed separately from the GF compiler and runtimes. As of 2018-07-26, the RGL is distributed separately from the GF compiler and runtimes.
To get the source, follow the previous instructions on [how to clone a repository with Git #getting-source].
After cloning the RGL, you should have a directory named ``gf-rgl`` on your computer.
=== Simple === === Simple ===
To install the RGL, you can use the following commands from within the ``gf-rgl`` repository: To install the RGL, you can use the following commands from within the ``gf-rgl`` repository:
``` ```
@@ -418,103 +334,68 @@ If you do not have Haskell installed, you can use the simple build script ``Setu
== Creating binary distribution packages == == Creating binary distribution packages ==
=== Creating .deb packages for Ubuntu === The binaries are generated with Github Actions. More details can be viewed here:
This was tested on Ubuntu 14.04 for the release of GF 3.6, and the https://github.com/GrammaticalFramework/gf-core/actions/workflows/build-binary-packages.yml
resulting ``.deb`` packages appears to work on Ubuntu 12.04, 13.10 and 14.04.
For the release of GF 3.7, we generated ``.deb`` packages on Ubuntu 15.04 and
tested them on Ubuntu 12.04 and 14.04.
Under Ubuntu, Haskell executables are statically linked against other Haskell
libraries, so the .deb packages are fairly self-contained.
==== Preparations ==== == Running the test suite ==
The GF test suite is run with one of the following commands from the top directory:
``` ```
sudo apt-get install dpkg-dev debhelper $ cabal test
``` ```
==== Creating the package ==== or
Make sure the ``debian/changelog`` starts with an entry that describes the
version you are building. Then run
``` ```
make deb $ stack test
``` ```
If get error messages about missing dependencies
(e.g. ``autoconf``, ``automake``, ``libtool-bin``, ``python-dev``,
``java-sdk``, ``txt2tags``)
use ``apt-get intall`` to install them, then try again.
=== Creating OS X Installer packages ===
Run
```
make pkg
```
=== Creating binary tar distributions ===
Run
```
make bintar
```
=== Creating .rpm packages for Fedora ===
This is possible, but the procedure has not been automated.
It involves using the cabal-rpm tool,
```
sudo dnf install cabal-rpm
```
and following the Fedora guide
[How to create an RPM package http://fedoraproject.org/wiki/How_to_create_an_RPM_package].
Under Fedora, Haskell executables are dynamically linked against other Haskell
libraries, so ``.rpm`` packages for all Haskell libraries that GF depends on
are required. Most of them are already available in the Fedora distribution,
but a few of them might have to be built and distributed along with
the GF ``.rpm`` package.
When building ``.rpm`` packages for GF 3.4, we also had to build ``.rpm``s for
``fst`` and ``httpd-shed``.
== Running the testsuite ==
**NOTE:** The test suite has not been maintained recently, so expect many
tests to fail.
%% // TH 2012-08-06
GF has testsuite. It is run with the following command:
```
$ cabal test
```
The testsuite architecture for GF is very simple but still very flexible. The testsuite architecture for GF is very simple but still very flexible.
GF by itself is an interpreter and could execute commands in batch mode. GF by itself is an interpreter and could execute commands in batch mode.
This is everything that we need to organize a testsuite. The root of the This is everything that we need to organize a testsuite. The root of the
testsuite is the testsuite/ directory. It contains subdirectories which testsuite is the ``testsuite/`` directory. It contains subdirectories
themself contain GF batch files (with extension .gfs). The above command which themselves contain GF batch files (with extension ``.gfs``).
searches the subdirectories of the testsuite/ directory for files with extension The above command searches the subdirectories of the ``testsuite/`` directory
.gfs and when it finds one it is executed with the GF interpreter. for files with extension ``.gfs`` and when it finds one, it is executed with
The output of the script is stored in file with extension .out and is compared the GF interpreter. The output of the script is stored in file with extension ``.out``
with the content of the corresponding file with extension .gold, if there is one. and is compared with the content of the corresponding file with extension ``.gold``, if there is one.
If the contents are identical the command reports that the test was passed successfully.
Otherwise the test had failed.
Every time when you make some changes to GF that have to be tested, instead of Every time when you make some changes to GF that have to be tested,
writing the commands by hand in the GF shell, add them to one .gfs file in the testsuite instead of writing the commands by hand in the GF shell, add them to one ``.gfs``
and run the test. In this way you can use the same test later and we will be sure file in the testsuite subdirectory where its ``.gf`` file resides and run the test.
that we will not incidentaly break your code later. In this way you can use the same test later and we will be sure that we will not
accidentally break your code later.
**Test Outcome - Passed:** If the contents of the files with the ``.out`` extension
are identical to their correspondingly-named files with the extension ``.gold``,
the command will report that the tests passed successfully, e.g.
If you don't want to run the whole testsuite you can write the path to the subdirectory
in which you are interested. For example:
``` ```
$ cabal test testsuite/compiler Running 1 test suites...
Test suite gf-tests: RUNNING...
Test suite gf-tests: PASS
1 of 1 test suites (1 of 1 test cases) passed.
``` ```
will run only the testsuite for the compiler.
**Test Outcome - Failed:** If there is a contents mismatch between the files
with the ``.out`` extension and their corresponding files with the extension ``.gold``,
the test diagnostics will show a fail and the areas that failed. e.g.
```
testsuite/compiler/compute/Records.gfs: OK
testsuite/compiler/compute/Variants.gfs: FAIL
testsuite/compiler/params/params.gfs: OK
Test suite gf-tests: FAIL
0 of 1 test suites (0 of 1 test cases) passed.
```
The fail results overview is available in gf-tests.html which shows 4 columns:
+ __Results__ - only areas that fail will appear. (Note: There are 3 failures in the gf-tests.html which are labelled as (expected). These failures should be ignored.)
+ __Input__ - which is the test written in the .gfs file
+ __Gold__ - the expected output from running the test set out in the .gfs file. This column refers to the contents from the .gold extension files.
+ __Output__ - This column refers to the contents from the .out extension files which are generated as test output.
After fixing the areas which fail, rerun the test command. Repeat the entire process of fix-and-test until the test suite passes before submitting a pull request to include your changes.

75
doc/gf-editor-modes.md Normal file
View File

@@ -0,0 +1,75 @@
# Editor modes & IDE integration for GF
We collect GF modes for various editors on this page. Contributions are welcome!
## Emacs
[gf.el](https://github.com/GrammaticalFramework/gf-emacs-mode) by Johan
Bockgård provides syntax highlighting and automatic indentation and
lets you run the GF Shell in an emacs buffer. See installation
instructions inside.
## Atom
[language-gf](https://atom.io/packages/language-gf), by John J. Camilleri
## Visual Studio Code
* [Grammatical Framework Language Server](https://marketplace.visualstudio.com/items?itemName=anka-213.gf-vscode) by Andreas Källberg.
This provides syntax highlighting and a client for the Grammatical Framework language server. Follow the installation instructions in the link.
* [Grammatical Framework](https://marketplace.visualstudio.com/items?itemName=GrammaticalFramework.gf-vscode) is a simpler extension
without any external dependencies which provides only syntax highlighting.
## Eclipse
[GF Eclipse Plugin](https://github.com/GrammaticalFramework/gf-eclipse-plugin/), by John J. Camilleri
## Gedit
By John J. Camilleri
Copy the file below to
`~/.local/share/gtksourceview-3.0/language-specs/gf.lang` (under Ubuntu).
* [gf.lang](../src/tools/gf.lang)
Some helpful notes/links:
* The code is based heavily on the `haskell.lang` file which I found in
`/usr/share/gtksourceview-2.0/language-specs/haskell.lang`.
* Ruslan Osmanov recommends
[registering your file extension as its own MIME type](http://osmanov-dev-notes.blogspot.com/2011/04/how-to-add-new-highlight-mode-in-gedit.html)
(see also [here](https://help.ubuntu.com/community/AddingMimeTypes)),
however on my system the `.gf` extension was already registered
as a generic font (`application/x-tex-gf`) and I didn't want to risk
messing any of that up.
* This is a quick 5-minute job and might require some tweaking.
[The GtkSourceView language definition tutorial](http://developer.gnome.org/gtksourceview/stable/lang-tutorial.html)
is the place to start looking.
* Contributions are welcome!
## Geany
By John J. Camilleri
[Custom filetype](http://www.geany.org/manual/dev/index.html#custom-filetypes)
config files for syntax highlighting in [Geany](http://www.geany.org/).
For version 1.36 and above, copy one of the files below to
`/usr/share/geany/filedefs/filetypes.GF.conf` (under Ubuntu).
If you're using a version older than 1.36, copy the file to `/usr/share/geany/filetypes.GF.conf`.
You will need to manually create the file.
* [light-filetypes.GF.conf](../src/tools/light-filetypes.GF.conf)
* [dark-filetypes.GF.conf](../src/tools/dark-filetypes.GF.conf)
You will also need to edit the `filetype_extensions.conf` file and add the
following line somewhere:
```
GF=*.gf
```
## Vim
[vim-gf](https://github.com/gdetrez/vim-gf)

View File

@@ -1,72 +0,0 @@
Editor modes & IDE integration for GF
We collect GF modes for various editors on this page. Contributions are
welcome!
==Emacs==
[gf.el https://github.com/GrammaticalFramework/gf-emacs-mode] by Johan
Bockgård provides syntax highlighting and automatic indentation and
lets you run the GF Shell in an emacs buffer. See installation
instructions inside.
==Atom==
[language-gf https://atom.io/packages/language-gf], by John J. Camilleri
==Eclipse==
[GF Eclipse Plugin https://github.com/GrammaticalFramework/gf-eclipse-plugin/], by John J. Camilleri
==Gedit==
By John J. Camilleri
Copy the file below to
``~/.local/share/gtksourceview-3.0/language-specs/gf.lang`` (under Ubuntu).
- [gf.lang ../src/tools/gf.lang]
Some helpful notes/links:
- The code is based heavily on the ``haskell.lang`` file which I found in
``/usr/share/gtksourceview-2.0/language-specs/haskell.lang``.
- Ruslan Osmanov recommends
[registering your file extension as its own MIME type http://osmanov-dev-notes.blogspot.com/2011/04/how-to-add-new-highlight-mode-in-gedit.html]
(see also [here https://help.ubuntu.com/community/AddingMimeTypes]),
however on my system the ``.gf`` extension was already registered
as a generic font (``application/x-tex-gf``) and I didn't want to risk
messing any of that up.
- This is a quick 5-minute job and might require some tweaking.
[The GtkSourceView language definition tutorial http://developer.gnome.org/gtksourceview/stable/lang-tutorial.html]
is the place to start looking.
- Contributions are welcome!
==Geany==
By John J. Camilleri
[Custom filetype http://www.geany.org/manual/dev/index.html#custom-filetypes]
config files for syntax highlighting in [Geany http://www.geany.org/].
Copy one of the files below to ``/usr/share/geany/filetypes.GF.conf``
(under Ubuntu). You will need to manually create the file.
- [light-filetypes.GF.conf ../src/tools/light-filetypes.GF.conf]
- [dark-filetypes.GF.conf ../src/tools/dark-filetypes.GF.conf]
You will also need to edit the ``filetype_extensions.conf`` file and add the
following line somewhere:
```
GF=*.gf
```
==Vim==
[vim-gf https://github.com/gdetrez/vim-gf]

View File

@@ -46,7 +46,7 @@
#TINY #TINY
The command has one argument which is either function, expression or 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 the argument is a function then ?its type is printed out.
If it is a category then the category definition is printed. If it is a category then the category definition is printed.
If a whole expression is given it prints the expression with refined 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 #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 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, all metavariables in the tree. The generation can be biased by probabilities,
given in a file in the -probs flag. given in a file in the -probs flag.
@@ -315,13 +315,14 @@ given in a file in the -probs flag.
| ``-cat`` | generation category | ``-cat`` | generation category
| ``-lang`` | uses only functions that have linearizations in all these languages | ``-lang`` | uses only functions that have linearizations in all these languages
| ``-number`` | number of trees generated | ``-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) | ``-probs`` | file with biased probabilities (format 'f 0.4' one by line)
- Examples: - Examples:
| ``gr`` | one tree in the startcat of the current grammar | ``gr`` | one tree in the startcat of the current grammar
| ``gr -cat=NP -number=16`` | 16 trees in the category NP | ``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 -lang=LangHin,LangTha -cat=Cl`` | Cl, both in LangHin and LangTha
| ``gr -probs=FILE`` | generate with bias | ``gr -probs=FILE`` | generate with bias
| ``gr (AdjCN ? (UseN ?))`` | generate trees of form (AdjCN ? (UseN ?)) | ``gr (AdjCN ? (UseN ?))`` | generate trees of form (AdjCN ? (UseN ?))
@@ -338,8 +339,8 @@ given in a file in the -probs flag.
#TINY #TINY
Generates all trees of a given category. By default, 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 5, but this can be changed by a flag.
If a Tree argument is given, the command completes the Tree with values If a Tree argument is given, the command completes the Tree with values
to all metavariables in the tree. to all metavariables in the tree.
@@ -353,7 +354,7 @@ to all metavariables in the tree.
- Examples: - 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 -number=16`` | 16 trees in the category NP
| ``gt -cat=NP -depth=2`` | trees in the category NP to depth 2 | ``gt -cat=NP -depth=2`` | trees in the category NP to depth 2
| ``gt (AdjCN ? (UseN ?))`` | trees of form (AdjCN ? (UseN ?)) | ``gt (AdjCN ? (UseN ?))`` | trees of form (AdjCN ? (UseN ?))
@@ -582,7 +583,7 @@ trees where a function node is a metavariable.
- Examples: - Examples:
| ``l -lang=LangSwe,LangNor -chunks ? a b (? c d)`` | | ``l -lang=LangSwe,LangNor -chunks ? a b (? c d)`` |
#NORMAL #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. The default start category can be overridden by the -cat flag.
See also the ps command for lexing and character encoding. 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 the parser. For example if -openclass="A,N,V" is given, the parser
will accept unknown adjectives, nouns and verbs with the resource grammar. will accept unknown adjectives, nouns and verbs with the resource grammar.

View File

@@ -7,7 +7,6 @@ title: "Grammatical Framework: Authors and Acknowledgements"
The current maintainers of GF are The current maintainers of GF are
[Krasimir Angelov](http://www.chalmers.se/cse/EN/organization/divisions/computing-science/people/angelov-krasimir), [Krasimir Angelov](http://www.chalmers.se/cse/EN/organization/divisions/computing-science/people/angelov-krasimir),
[Thomas Hallgren](http://www.cse.chalmers.se/~hallgren/),
[Aarne Ranta](http://www.cse.chalmers.se/~aarne/), [Aarne Ranta](http://www.cse.chalmers.se/~aarne/),
[John J. Camilleri](http://johnjcamilleri.com), and [John J. Camilleri](http://johnjcamilleri.com), and
[Inari Listenmaa](https://inariksit.github.io/). [Inari Listenmaa](https://inariksit.github.io/).
@@ -22,6 +21,7 @@ and
The following people have contributed code to some of the versions: The following people have contributed code to some of the versions:
- [Thomas Hallgren](http://www.cse.chalmers.se/~hallgren/) (University of Gothenburg)
- Grégoire Détrez (University of Gothenburg) - Grégoire Détrez (University of Gothenburg)
- Ramona Enache (University of Gothenburg) - Ramona Enache (University of Gothenburg)
- [Björn Bringert](http://www.cse.chalmers.se/alumni/bringert) (University of Gothenburg) - [Björn Bringert](http://www.cse.chalmers.se/alumni/bringert) (University of Gothenburg)

View File

@@ -1188,7 +1188,7 @@ use ``generate_trees = gt``.
this wine is fresh this wine is fresh
this wine is warm 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: set by using the ``depth`` flag:
``` ```
> generate_trees -depth=2 | l > generate_trees -depth=2 | l
@@ -1265,10 +1265,16 @@ Human eye may prefer to see a visualization: ``visualize_tree = vt``:
> parse "this delicious cheese is very Italian" | visualize_tree > parse "this delicious cheese is very Italian" | visualize_tree
``` ```
The tree is generated in postscript (``.ps``) file. The ``-view`` option is used for The tree is generated in postscript (``.ps``) file. The ``-view`` option is used for
telling what command to use to view the file. Its default is ``"open"``, which works telling what command to use to view the file.
on Mac OS X. On Ubuntu Linux, one can write
This works on Mac OS X:
``` ```
> parse "this delicious cheese is very Italian" | visualize_tree -view="eog" > parse "this delicious cheese is very Italian" | visualize_tree -view=open
```
On Linux, one can use one of the following commands.
```
> parse "this delicious cheese is very Italian" | visualize_tree -view=eog
> parse "this delicious cheese is very Italian" | visualize_tree -view=xdg-open
``` ```
@@ -1733,6 +1739,13 @@ A new module can **extend** an old one:
Pizza : Kind ; 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
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``).
Parallel to the abstract syntax, extensions can Parallel to the abstract syntax, extensions can
be built for concrete syntaxes: be built for concrete syntaxes:
``` ```
@@ -3733,7 +3746,7 @@ However, type-incorrect commands are rejected by the typecheck:
The parsing is successful but the type checking failed with error(s): The parsing is successful but the type checking failed with error(s):
Couldn't match expected type Device light Couldn't match expected type Device light
against the interred type Device fan against the interred type Device fan
In the expression: DKindOne fan In the expression: DKindOne fan
``` ```
#NEW #NEW
@@ -4171,7 +4184,7 @@ division of integers.
``` ```
abstract Calculator = { abstract Calculator = {
flags startcat = Exp ; flags startcat = Exp ;
cat Exp ; cat Exp ;
fun fun
@@ -4578,7 +4591,7 @@ in any multilingual grammar between any languages in the grammar.
module Main where module Main where
import PGF import PGF
import System (getArgs) import System.Environment (getArgs)
main :: IO () main :: IO ()
main = do main = do

View File

@@ -1,8 +1,9 @@
--- ---
title: Grammatical Framework Download and Installation title: Grammatical Framework Download and Installation
... date: 25 July 2021
---
**GF 3.11** was released on ... December 2020. **GF 3.11** was released on 25 July 2021.
What's new? See the [release notes](release-3.11.html). What's new? See the [release notes](release-3.11.html).
@@ -24,22 +25,25 @@ Binary packages are available for Debian/Ubuntu, macOS, and Windows and include:
Unlike in previous versions, the binaries **do not** include the RGL. Unlike in previous versions, the binaries **do not** include the RGL.
[Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/RELEASE-3.11) [Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/3.11)
#### Debian/Ubuntu #### Debian/Ubuntu
There are two versions: `gf-3.11-ubuntu-18.04.deb` for Ubuntu 18.04 (Cosmic), and `gf-3.11-ubuntu-20.04.deb` for Ubuntu 20.04 (Focal).
To install the package use: To install the package use:
``` ```
sudo dpkg -i gf_3.11.deb sudo apt-get install ./gf-3.11-ubuntu-*.deb
``` ```
The Ubuntu `.deb` packages should work on Ubuntu 16.04, 18.04 and similar Linux distributions. <!-- The Ubuntu `.deb` packages should work on Ubuntu 16.04, 18.04 and similar Linux distributions. -->
#### macOS #### macOS
To install the package, just double-click it and follow the installer instructions. To install the package, just double-click it and follow the installer instructions.
The packages should work on at least 10.13 (High Sierra) and 10.14 (Mojave). The packages should work on at least Catalina and Big Sur.
#### Windows #### Windows
@@ -49,26 +53,39 @@ You will probably need to update the `PATH` environment variable to include your
For more information, see [Using GF on Windows](https://www.grammaticalframework.org/~inari/gf-windows.html) (latest updated for Windows 10). For more information, see [Using GF on Windows](https://www.grammaticalframework.org/~inari/gf-windows.html) (latest updated for Windows 10).
## Installing the latest Hackage release (macOS, Linux, and WSL2 on Windows) ## Installing from Hackage
_Instructions applicable for macOS, Linux, and WSL2 on Windows._
[GF is on Hackage](http://hackage.haskell.org/package/gf), so under [GF is on Hackage](http://hackage.haskell.org/package/gf), so under
normal circumstances the procedure is fairly simple: normal circumstances the procedure is fairly simple:
1. Install ghcup https://www.haskell.org/ghcup/ ```
2. `ghcup install ghc 8.10.4` cabal update
3. `ghcup set ghc 8.10.4` cabal install gf-3.11
4. `cabal update` ```
5. On Linux: install some C libraries from your Linux distribution (see note below)
6. `cabal install gf-3.11`
You can also download the source code release from [GitHub](https://github.com/GrammaticalFramework/gf-core/releases),
and follow the instructions below under **Installing from the latest developer source code**.
### Notes ### 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** **Installation location**
The above steps installs GF for a single user. 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`), 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): so you might want to add this directory to your path (in `.bash_profile` or similar):
@@ -80,32 +97,34 @@ PATH=$HOME/.cabal/bin:$PATH
GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which
on Linux depends on some non-Haskell libraries that won't be installed on Linux depends on some non-Haskell libraries that won't be installed
automatically by cabal, and therefore need to be installed manually. automatically by Cabal, and therefore need to be installed manually.
Here is one way to do this: Here is one way to do this:
- On Ubuntu: `sudo apt-get install libghc-haskeline-dev` - On Ubuntu: `sudo apt-get install libghc-haskeline-dev`
- On Fedora: `sudo dnf install ghc-haskeline-devel` - On Fedora: `sudo dnf install ghc-haskeline-devel`
**GHC version** ## Installing from source code
The GF source code has been updated to compile with GHC versions 7.10 through to 8.8. **Obtaining**
## Installing from the latest developer source code To obtain the source code for the **release**,
download it from [GitHub](https://github.com/GrammaticalFramework/gf-core/releases).
If you haven't already, clone the repository with: 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 git clone https://github.com/GrammaticalFramework/gf-core.git
``` ```
2. If you've already cloned the repository previously, update with:
If you've already cloned the repository previously, update with:
``` ```
git pull git pull
``` ```
Then install with:
**Installing**
You can then install with:
``` ```
cabal install cabal install
``` ```
@@ -116,10 +135,12 @@ or, if you're a Stack user:
stack install stack install
``` ```
The above notes for installing from source apply also in these cases. <!--The above notes for installing from source apply also in these cases.-->
For more info on working with the GF source code, see the For more info on working with the GF source code, see the
[GF Developers Guide](../doc/gf-developers.html). [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 ## Installing the Python bindings from PyPI
The Python library is available on PyPI as `pgf`, so it can be installed using: The Python library is available on PyPI as `pgf`, so it can be installed using:

191
download/index-3.12.md Normal file
View File

@@ -0,0 +1,191 @@
---
title: Grammatical Framework Download and Installation
date: 8 August 2025
---
**GF 3.12** was released on 8 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-the-rgl-from-a-binary-release).
---
## 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
- Python bindings to the C run-time system
[Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/3.12)
#### Debian/Ubuntu
The package targets Ubuntu 24.04 (Noble).
To install it, use:
```
sudo apt install ./gf-3.12-ubuntu-24.04.deb
```
#### macOS
If you are on an Intel Mac (2019 or older), use `gf-3.12-macos-intel.pkg`.<br>
For newer ARM-based Macs (Apple Silicon M1, M2, M3), use `gf-3.12-macos-arm.pkg`.
After downloading, right click on the file and click on Open.[^1]
You will see a dialog saying that "macOS cannot verify the developer of "gf-3.12-macos-intel.pkg". Are you sure you want to open it?".
Press Open.
[^1]: If you just double click on the file, you will get an error message "gf-3.12-macos-intel.pkg" cannot be opened because it is from an unidentified developer.
#### Windows
To install the package:
1. unpack it anywhere and take note of the full path to the folder containing the `.exe` file.
2. add it to the `PATH` environment variable
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 9.6.7.
#### Obtaining Haskell
There are various ways of obtaining Haskell, including:
- ghcup
1. Install from https://www.haskell.org/ghcup/
2. `ghcup install ghc 9.6.7`
3. `ghcup set ghc 9.6.7`
- 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
```
<!--The above notes for installing from source apply also in these cases.-->
For more info on working with the GF source code, see the
[GF Developers Guide](../doc/gf-developers.html).
## Installing the Python bindings from PyPI
The Python library is available on PyPI as `pgf`, so it can be installed using:
```
pip install pgf
```
If this doesn't work, you will need to install the C runtime manually; see the instructions [here](https://www.grammaticalframework.org/doc/gf-developers.html#toc12).
---
## 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.
For more information, see [Using GF on Windows](https://www.grammaticalframework.org/~inari/gf-windows.html) (latest updated for Windows 10).
## 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)

View File

@@ -1,8 +1,8 @@
<html> <html>
<head> <head>
<meta http-equiv="refresh" content="0; URL=/download/index-3.10.html" /> <meta http-equiv="refresh" content="0; URL=/download/index-3.11.html" />
</head> </head>
<body> <body>
You are being redirected to <a href="index-3.10.html">the current version</a> of this page. You are being redirected to <a href="index-3.12.html">the current version</a> of this page.
</body> </body>
</html> </html>

View File

@@ -1,7 +1,7 @@
--- ---
title: GF 3.11 Release Notes title: GF 3.11 Release Notes
date: ... December 2020 date: 25 July 2021
... ---
## Installation ## Installation
@@ -12,24 +12,27 @@ See the [download page](index-3.11.html).
From this release, the binary GF core packages do not contain the RGL. From this release, the binary GF core packages do not contain the RGL.
The RGL's release cycle is now completely separate from GF's. See [RGL releases](https://github.com/GrammaticalFramework/gf-rgl/releases). The RGL's release cycle is now completely separate from GF's. See [RGL releases](https://github.com/GrammaticalFramework/gf-rgl/releases).
Over 400 changes have been pushed to GF core Over 500 changes have been pushed to GF core
since the release of GF 3.10 in December 2018. since the release of GF 3.10 in December 2018.
## General ## General
- Make the test suite work again. - Make the test suite work again.
- Compatibility with new versions of GHC, including multiple Stack files for the different versions. - Compatibility with new versions of GHC, including multiple Stack files for the different versions.
- Updates to build scripts and CI. - Support for newer version of Ubuntu 20.04 in the precompiled binaries.
- Bug fixes. - Updates to build scripts and CI workflows.
- Bug fixes and code cleanup.
## GF compiler and run-time library ## GF compiler and run-time library
- Huge improvements in time & space requirements for grammar compilation (pending [#87](https://github.com/GrammaticalFramework/gf-core/pull/87)).
- Add CoNLL output to `visualize_tree` shell command. - Add CoNLL output to `visualize_tree` shell command.
- Add canonical GF as output format in the compiler. - Add canonical GF as output format in the compiler.
- Add PGF JSON as output format in the compiler. - Add PGF JSON as output format in the compiler.
- Deprecate JavaScript runtime in favour of updated [TypeScript runtime](https://github.com/GrammaticalFramework/gf-typescript). - Deprecate JavaScript runtime in favour of updated [TypeScript runtime](https://github.com/GrammaticalFramework/gf-typescript).
- Improvements in time & space requirements when compiling certain grammars.
- Improvements to Haskell export. - Improvements to Haskell export.
- Improvements to the GF shell.
- Improvements to canonical GF compilation.
- Improvements to the C runtime. - Improvements to the C runtime.
- Improvements to `gf -server` mode. - Improvements to `gf -server` mode.
- Clearer compiler error messages. - Clearer compiler error messages.

37
download/release-3.12.md Normal file
View File

@@ -0,0 +1,37 @@
---
title: GF 3.12 Release Notes
date: 08 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

43
flake.lock generated Normal file
View File

@@ -0,0 +1,43 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1704290814,
"narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

50
flake.nix Normal file
View File

@@ -0,0 +1,50 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
systems.url = "github:nix-systems/default";
};
nixConfig = {
# extra-trusted-public-keys =
# "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
# extra-substituters = "https://devenv.cachix.org";
};
outputs = { self, nixpkgs, systems, ... }@inputs:
let forEachSystem = nixpkgs.lib.genAttrs (import systems);
in {
packages = forEachSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
haskellPackages = pkgs.haskell.packages.ghc925.override {
overrides = self: _super: {
cgi = pkgs.haskell.lib.unmarkBroken (pkgs.haskell.lib.dontCheck
(self.callHackage "cgi" "3001.5.0.1" { }));
};
};
in {
gf = pkgs.haskell.lib.overrideCabal
(haskellPackages.callCabal2nixWithOptions "gf" self "--flag=-server"
{ }) (_old: {
# Fix utf8 encoding problems
patches = [
# Already applied in master
# (
# pkgs.fetchpatch {
# url = "https://github.com/anka-213/gf-core/commit/6f1ca05fddbcbc860898ddf10a557b513dfafc18.patch";
# sha256 = "17vn3hncxm1dwbgpfmrl6gk6wljz3r28j191lpv5zx741pmzgbnm";
# }
# )
./nix/expose-all.patch
./nix/revert-new-cabal-madness.patch
];
jailbreak = true;
# executableSystemDepends = [
# (pkgs.ncurses.override { enableStatic = true; })
# ];
# executableHaskellDepends = [ ];
});
});
};
}

View File

@@ -2,7 +2,7 @@ concrete FoodIta of Food = {
lincat lincat
Comment, Item, Kind, Quality = Str ; Comment, Item, Kind, Quality = Str ;
lin lin
Pred item quality = item ++ "è" ++ quality ; Pred item quality = item ++ "è" ++ quality ;
This kind = "questo" ++ kind ; This kind = "questo" ++ kind ;
That kind = "quel" ++ kind ; That kind = "quel" ++ kind ;
Mod quality kind = kind ++ quality ; Mod quality kind = kind ++ quality ;

View File

@@ -32,5 +32,5 @@ resource ResIta = open Prelude in {
in in
adjective nero (ner+"a") (ner+"i") (ner+"e") ; adjective nero (ner+"a") (ner+"i") (ner+"e") ;
copula : Number => Str = copula : Number => Str =
table {Sg => "è" ; Pl => "sono"} ; table {Sg => "è" ; Pl => "sono"} ;
} }

View File

@@ -8,13 +8,13 @@ instance LexFoodsFin of LexFoods =
cheese_N = mkN "juusto" ; cheese_N = mkN "juusto" ;
fish_N = mkN "kala" ; fish_N = mkN "kala" ;
fresh_A = mkA "tuore" ; fresh_A = mkA "tuore" ;
warm_A = mkA warm_A = mkA
(mkN "lämmin" "lämpimän" "lämmintä" "lämpimänä" "lämpimään" (mkN "lämmin" "lämpimän" "lämmintä" "lämpimänä" "lämpimään"
"lämpiminä" "lämpimiä" "lämpimien" "lämpimissä" "lämpimiin" "lämpiminä" "lämpimiä" "lämpimien" "lämpimissä" "lämpimiin"
) )
"lämpimämpi" "lämpimin" ; "lämpimämpi" "lämpimin" ;
italian_A = mkA "italialainen" ; italian_A = mkA "italialainen" ;
expensive_A = mkA "kallis" ; expensive_A = mkA "kallis" ;
delicious_A = mkA "herkullinen" ; delicious_A = mkA "herkullinen" ;
boring_A = mkA "tylsä" ; boring_A = mkA "tylsä" ;
} }

View File

@@ -1,16 +1,16 @@
-- (c) 2009 Aarne Ranta under LGPL -- (c) 2009 Aarne Ranta under LGPL
instance LexFoodsGer of LexFoods = instance LexFoodsGer of LexFoods =
open SyntaxGer, ParadigmsGer in { open SyntaxGer, ParadigmsGer in {
oper oper
wine_N = mkN "Wein" ; wine_N = mkN "Wein" ;
pizza_N = mkN "Pizza" "Pizzen" feminine ; pizza_N = mkN "Pizza" "Pizzen" feminine ;
cheese_N = mkN "Käse" "Käse" masculine ; cheese_N = mkN "Käse" "Käse" masculine ;
fish_N = mkN "Fisch" ; fish_N = mkN "Fisch" ;
fresh_A = mkA "frisch" ; fresh_A = mkA "frisch" ;
warm_A = mkA "warm" "wärmer" "wärmste" ; warm_A = mkA "warm" "wärmer" "wärmste" ;
italian_A = mkA "italienisch" ; italian_A = mkA "italienisch" ;
expensive_A = mkA "teuer" ; expensive_A = mkA "teuer" ;
delicious_A = mkA "köstlich" ; delicious_A = mkA "köstlich" ;
boring_A = mkA "langweilig" ; boring_A = mkA "langweilig" ;
} }

View File

@@ -7,10 +7,10 @@ instance LexFoodsSwe of LexFoods =
pizza_N = mkN "pizza" ; pizza_N = mkN "pizza" ;
cheese_N = mkN "ost" ; cheese_N = mkN "ost" ;
fish_N = mkN "fisk" ; fish_N = mkN "fisk" ;
fresh_A = mkA "färsk" ; fresh_A = mkA "färsk" ;
warm_A = mkA "varm" ; warm_A = mkA "varm" ;
italian_A = mkA "italiensk" ; italian_A = mkA "italiensk" ;
expensive_A = mkA "dyr" ; expensive_A = mkA "dyr" ;
delicious_A = mkA "läcker" ; delicious_A = mkA "läcker" ;
boring_A = mkA "tråkig" ; boring_A = mkA "tråkig" ;
} }

View File

@@ -6,7 +6,7 @@ concrete QueryFin of Query = {
Odd = pred "pariton" ; Odd = pred "pariton" ;
Prime = pred "alkuluku" ; Prime = pred "alkuluku" ;
Number i = i.s ; Number i = i.s ;
Yes = "kyllä" ; Yes = "kyllä" ;
No = "ei" ; No = "ei" ;
oper oper
pred : Str -> Str -> Str = \f,x -> "onko" ++ x ++ f ; pred : Str -> Str -> Str = \f,x -> "onko" ++ x ++ f ;

View File

@@ -43,10 +43,10 @@ oper
} ; } ;
auxVerb : Aux -> Verb = \a -> case a of { auxVerb : Aux -> Verb = \a -> case a of {
Avere => Avere =>
mkVerb "avere" "ho" "hai" "ha" "abbiamo" "avete" "hanno" "avuto" Avere ; mkVerb "avere" "ho" "hai" "ha" "abbiamo" "avete" "hanno" "avuto" Avere ;
Essere => Essere =>
mkVerb "essere" "sono" "sei" "è" "siamo" "siete" "sono" "stato" Essere mkVerb "essere" "sono" "sei" "è" "siamo" "siete" "sono" "stato" Essere
} ; } ;
agrPart : Verb -> Agr -> ClitAgr -> Str = \v,a,c -> case v.aux of { agrPart : Verb -> Agr -> ClitAgr -> Str = \v,a,c -> case v.aux of {

194
gf.cabal
View File

@@ -1,20 +1,24 @@
name: gf name: gf
version: 3.10.4-git version: 3.12.0
cabal-version: >= 1.22 cabal-version: 1.22
build-type: Custom build-type: Simple
license: OtherLicense license: OtherLicense
license-file: LICENSE license-file: LICENSE
category: Natural Language Processing, Compiler category: Natural Language Processing, Compiler
synopsis: Grammatical Framework synopsis: Grammatical Framework
description: GF, Grammatical Framework, is a programming language for multilingual grammar applications description: GF, Grammatical Framework, is a programming language for multilingual grammar applications
homepage: http://www.grammaticalframework.org/ maintainer: John J. Camilleri <john@digitalgrammars.com>
homepage: https://www.grammaticalframework.org/
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
maintainer: Thomas Hallgren tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4, GHC==9.0.2, GHC==9.2.4, GHC==9.6.7
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3
data-dir: src data-dir: src
extra-source-files: WebSetup.hs extra-source-files:
README.md
CHANGELOG.md
WebSetup.hs
doc/Logos/gf0.png
data-files: data-files:
www/*.html www/*.html
www/*.css www/*.css
@@ -40,25 +44,17 @@ data-files:
www/translator/*.css www/translator/*.css
www/translator/*.js www/translator/*.js
custom-setup
setup-depends:
base,
Cabal >=1.22.0.0,
directory,
filepath,
process >=1.0.1.1
source-repository head source-repository head
type: git type: git
location: https://github.com/GrammaticalFramework/gf-core.git location: https://github.com/GrammaticalFramework/gf-core.git
flag interrupt flag interrupt
Description: Enable Ctrl+Break in the shell Description: Enable Ctrl+Break in the shell
Default: True Default: True
flag server flag server
Description: Include --server mode Description: Include --server mode
Default: True Default: True
flag network-uri flag network-uri
description: Get Network.URI from the network-uri package description: Get Network.URI from the network-uri package
@@ -70,24 +66,29 @@ flag network-uri
flag c-runtime flag c-runtime
Description: Include functionality from the C run-time library (which must be installed already) Description: Include functionality from the C run-time library (which must be installed already)
Default: False Default: False
library library
default-language: Haskell2010 default-language: Haskell2010
build-depends: base >= 4.6 && <5, build-depends:
array, -- GHC 8.0.2 to GHC 8.10.4
containers, array >= 0.5.1 && < 0.6,
bytestring, base >= 4.9.1 && < 4.22,
utf8-string, bytestring >= 0.10.8 && < 0.12,
random, containers >= 0.5.7 && < 0.7,
pretty, exceptions >= 0.8.3 && < 0.11,
mtl, ghc-prim >= 0.5.0 && <= 0.10.0,
exceptions, mtl >= 2.2.1 && <= 2.3.1,
fail, pretty >= 1.1.3 && < 1.2,
-- For compatability with ghc < 8 random >= 1.1 && < 1.3,
-- We need transformers-compat >= 0.6.3, but that is only in newer snapshots where it is redundant. utf8-string >= 1.0.1.1 && < 1.1
transformers-compat,
ghc-prim if impl(ghc<8.0)
build-depends:
-- We need this in order for ghc-7.10 to build
transformers-compat >= 0.6.3 && < 0.7,
fail >= 4.9.0 && < 4.10
hs-source-dirs: src/runtime/haskell hs-source-dirs: src/runtime/haskell
other-modules: other-modules:
@@ -102,7 +103,7 @@ library
--ghc-options: -fwarn-unused-imports --ghc-options: -fwarn-unused-imports
--if impl(ghc>=7.8) --if impl(ghc>=7.8)
-- ghc-options: +RTS -A20M -RTS -- ghc-options: +RTS -A20M -RTS
ghc-prof-options: -fprof-auto -- ghc-prof-options: -fprof-auto
exposed-modules: exposed-modules:
PGF PGF
@@ -136,18 +137,29 @@ library
if flag(c-runtime) if flag(c-runtime)
exposed-modules: PGF2 exposed-modules: PGF2
other-modules: PGF2.FFI PGF2.Expr PGF2.Type other-modules:
GF.Interactive2 GF.Command.Commands2 PGF2.FFI
hs-source-dirs: src/runtime/haskell-bind PGF2.Expr
build-tools: hsc2hs PGF2.Type
GF.Interactive2
GF.Command.Commands2
hs-source-dirs: src/runtime/haskell-bind
build-tools: hsc2hs
extra-libraries: pgf gu extra-libraries: pgf gu
c-sources: src/runtime/haskell-bind/utils.c c-sources: src/runtime/haskell-bind/utils.c
cc-options: -std=c99 cc-options: -std=c99
---- GF compiler as a library: ---- GF compiler as a library:
build-depends: filepath, directory>=1.2, time, build-depends:
process, haskeline, parallel>=3, json directory >= 1.3.0 && < 1.4,
filepath >= 1.4.1 && < 1.5,
haskeline >= 0.7.3 && < 0.9,
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,
template-haskell >= 2.13.0.0 && < 2.21
hs-source-dirs: src/compiler hs-source-dirs: src/compiler
exposed-modules: exposed-modules:
@@ -158,12 +170,19 @@ library
GF.Grammar.Canonical GF.Grammar.Canonical
other-modules: other-modules:
GF.Main GF.Compiler GF.Interactive GF.Main
GF.Compiler
GF.Interactive
GF.Compile GF.CompileInParallel GF.CompileOne GF.Compile.GetGrammar GF.Compile
GF.CompileInParallel
GF.CompileOne
GF.Compile.GetGrammar
GF.Grammar GF.Grammar
GF.Data.Operations GF.Infra.Option GF.Infra.UseIO GF.Data.Operations
GF.Infra.Option
GF.Infra.UseIO
GF.Command.Abstract GF.Command.Abstract
GF.Command.CommandInfo GF.Command.CommandInfo
@@ -273,12 +292,17 @@ library
cpp-options: -DC_RUNTIME cpp-options: -DC_RUNTIME
if flag(server) if flag(server)
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7, build-depends:
cgi>=3001.2.2.0 cgi >= 3001.3.0.2 && < 3001.6,
httpd-shed >= 0.4.0 && < 0.5,
network>=2.3 && <3.2
if flag(network-uri) if flag(network-uri)
build-depends: network-uri>=2.6, network>=2.6 build-depends:
network-uri >= 2.6.1.0 && < 2.7,
network>=2.6 && <3.2
else else
build-depends: network<2.6 build-depends:
network >= 2.5 && <3.2
cpp-options: -DSERVER_MODE cpp-options: -DSERVER_MODE
other-modules: other-modules:
@@ -295,7 +319,10 @@ library
Fold Fold
ExampleDemo ExampleDemo
ExampleService ExampleService
hs-source-dirs: src/server src/server/transfer src/example-based hs-source-dirs:
src/server
src/server/transfer
src/example-based
if flag(interrupt) if flag(interrupt)
cpp-options: -DUSE_INTERRUPT cpp-options: -DUSE_INTERRUPT
@@ -304,17 +331,30 @@ library
other-modules: GF.System.NoSignal other-modules: GF.System.NoSignal
if impl(ghc>=7.8) if impl(ghc>=7.8)
build-tools: happy>=1.19, alex>=3.1 build-tools:
happy>=1.19,
alex>=3.1
-- ghc-options: +RTS -A20M -RTS -- ghc-options: +RTS -A20M -RTS
else else
build-tools: happy, alex>=3 build-tools:
happy,
alex>=3
ghc-options: -fno-warn-tabs ghc-options: -fno-warn-tabs
if os(windows) if os(windows)
build-depends: Win32 build-depends:
Win32 >= 2.3.1.1 && < 2.7
else else
build-depends: unix, terminfo>=0.4 build-depends:
terminfo >=0.4.0 && < 0.5
if impl(ghc >= 9.6.6)
build-depends: unix >= 2.8 && < 2.9
else
build-depends: unix >= 2.7.2 && < 2.8
if impl(ghc>=8.2) if impl(ghc>=8.2)
ghc-options: -fhide-source-paths ghc-options: -fhide-source-paths
@@ -322,8 +362,10 @@ library
executable gf executable gf
hs-source-dirs: src/programs hs-source-dirs: src/programs
main-is: gf-main.hs main-is: gf-main.hs
default-language: Haskell2010 default-language: Haskell2010
build-depends: gf, base build-depends:
gf,
base >= 4.9.1 && < 4.22
ghc-options: -threaded ghc-options: -threaded
--ghc-options: -fwarn-unused-imports --ghc-options: -fwarn-unused-imports
@@ -332,25 +374,35 @@ executable gf
if impl(ghc<7.8) if impl(ghc<7.8)
ghc-options: -with-rtsopts=-K64M ghc-options: -with-rtsopts=-K64M
ghc-prof-options: -auto-all -- ghc-prof-options: -auto-all
if impl(ghc>=8.2) if impl(ghc>=8.2)
ghc-options: -fhide-source-paths ghc-options: -fhide-source-paths
executable pgf-shell -- executable pgf-shell
--if !flag(c-runtime) -- --if !flag(c-runtime)
buildable: False -- buildable: False
main-is: pgf-shell.hs -- main-is: pgf-shell.hs
hs-source-dirs: src/runtime/haskell-bind/examples -- hs-source-dirs: src/runtime/haskell-bind/examples
build-depends: gf, base, containers, mtl, lifted-base -- build-depends:
default-language: Haskell2010 -- gf,
if impl(ghc>=7.0) -- base,
ghc-options: -rtsopts -- containers,
-- mtl,
-- lifted-base
-- default-language: Haskell2010
-- if impl(ghc>=7.0)
-- ghc-options: -rtsopts
test-suite gf-tests test-suite gf-tests
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
main-is: run.hs main-is: run.hs
hs-source-dirs: testsuite hs-source-dirs: testsuite
build-depends: base>=4.3 && <5, Cabal>=1.8, directory, filepath, process build-depends:
base >= 4.9.1 && < 4.22,
Cabal >= 1.8,
directory >= 1.3.0 && < 1.4,
filepath >= 1.4.1 && < 1.5,
process >= 1.4.3 && < 1.7
build-tool-depends: gf:gf build-tool-depends: gf:gf
default-language: Haskell2010 default-language: Haskell2010

View File

@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" crossorigin="anonymous">
<link rel="alternate" href="https://github.com/GrammaticalFramework/gf-core/" title="GF GitHub repository"> <link rel="alternate" href="https://github.com/GrammaticalFramework/gf-core/" title="GF GitHub repository">
</head> </head>
@@ -57,6 +57,7 @@
<li><a href="doc/gf-shell-reference.html">Shell Reference</a></li> <li><a href="doc/gf-shell-reference.html">Shell Reference</a></li>
<li><a href="http://www.molto-project.eu/sites/default/files/MOLTO_D2.3.pdf">Best Practices</a> <small>[PDF]</small></li> <li><a href="http://www.molto-project.eu/sites/default/files/MOLTO_D2.3.pdf">Best Practices</a> <small>[PDF]</small></li>
<li><a href="https://www.mitpressjournals.org/doi/pdf/10.1162/COLI_a_00378">Scaling Up (Computational Linguistics 2020)</a></li> <li><a href="https://www.mitpressjournals.org/doi/pdf/10.1162/COLI_a_00378">Scaling Up (Computational Linguistics 2020)</a></li>
<li><a href="https://inariksit.github.io/blog/">GF blog</a></li>
</ul> </ul>
<a href="lib/doc/synopsis/index.html" class="btn btn-primary ml-3"> <a href="lib/doc/synopsis/index.html" class="btn btn-primary ml-3">
@@ -85,10 +86,22 @@
<div class="col-sm-6 col-md-3 mb-4"> <div class="col-sm-6 col-md-3 mb-4">
<h3>Contribute</h3> <h3>Contribute</h3>
<ul class="mb-2"> <ul class="mb-2">
<li><a href="http://groups.google.com/group/gf-dev">Mailing List</a></li> <li>
<a href="https://discord.gg/EvfUsjzmaz">
<i class="fab fa-discord"></i>
Discord
</a>
</li>
<li>
<a href="https://stackoverflow.com/questions/tagged/gf">
<i class="fab fa-stack-overflow"></i>
Stack Overflow
</a>
</li>
<li><a href="https://groups.google.com/group/gf-dev">Mailing List</a></li>
<li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Issue Tracker</a></li> <li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Issue Tracker</a></li>
<li><a href="//school.grammaticalframework.org/">Summer School</a></li>
<li><a href="doc/gf-people.html">Authors</a></li> <li><a href="doc/gf-people.html">Authors</a></li>
<li><a href="//school.grammaticalframework.org/2020/">Summer School</a></li>
</ul> </ul>
<a href="https://github.com/GrammaticalFramework/" class="btn btn-primary ml-3"> <a href="https://github.com/GrammaticalFramework/" class="btn btn-primary ml-3">
<i class="fab fa-github mr-1"></i> <i class="fab fa-github mr-1"></i>
@@ -154,7 +167,7 @@ least one, it may help you to get a first idea of what GF is.
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h2>Applications & Availability</h2> <h2>Applications & availability</h2>
<p> <p>
GF can be used for building GF can be used for building
<a href="//cloud.grammaticalframework.org/translator/">translation systems</a>, <a href="//cloud.grammaticalframework.org/translator/">translation systems</a>,
@@ -214,60 +227,50 @@ least one, it may help you to get a first idea of what GF is.
</p> </p>
<p> <p>
We run the IRC channel <strong><code>#gf</code></strong> on the Freenode network, where you are welcome to look for help with small questions or just start a general discussion. We run the <a href="https://discord.gg/EvfUsjzmaz">GF server on Discord</a>, where you are welcome to look for help with small questions or just start a general discussion.
You can <a href="https://webchat.freenode.net/?channels=gf">open a web chat</a>
or <a href="/irc/">browse the channel logs</a>.
</p> </p>
<p> <p>
If you have a larger question which the community may benefit from, we recommend you ask it on the <a href="http://groups.google.com/group/gf-dev">mailing list</a>. For bug reports and feature requests, please create an issue in the
<a href="https://github.com/GrammaticalFramework/gf-core/issues">GF Core</a> or
<a href="https://github.com/GrammaticalFramework/gf-rgl/issues">RGL</a> repository.
For programming questions, consider asking them on <a href="https://stackoverflow.com/questions/tagged/gf">Stack Overflow with the <code>gf</code> tag</a>.
If you have a more general question to the community, we recommend you ask it on the <a href="http://groups.google.com/group/gf-dev">mailing list</a>.
</p> </p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<h2>News</h2> <h2>News</h2>
<dl class="row"> <dl class="row">
<dt class="col-sm-3 text-center text-nowrap">2025-08-08</dt>
<dd class="col-sm-9">
<strong>GF 3.12 released.</strong>
<a href="download/release-3.12.html">Release notes</a>
</dd>
<dt class="col-sm-3 text-center text-nowrap">2025-01-18</dt>
<dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2025/">9th GF Summer School</a>, in Gothenburg, Sweden, 18 &ndash; 29 August 2025.
</dd>
<dt class="col-sm-3 text-center text-nowrap">2023-01-24</dt>
<dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2023/">8th GF Summer School</a>, in Tampere, Finland, 14 &ndash; 25 August 2023.
</dd>
<dt class="col-sm-3 text-center text-nowrap">2021-07-25</dt>
<dd class="col-sm-9">
<strong>GF 3.11 released.</strong>
<a href="download/release-3.11.html">Release notes</a>
</dd>
<dt class="col-sm-3 text-center text-nowrap">2021-05-05</dt> <dt class="col-sm-3 text-center text-nowrap">2021-05-05</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
<a href="https://cloud.grammaticalframework.org/wordnet/">GF WordNet</a> now supports languages for which there are no other WordNets. New additions: Afrikaans, German, Korean, Maltese, Polish, Somali, Swahili. <a href="https://cloud.grammaticalframework.org/wordnet/">GF WordNet</a> now supports languages for which there are no other WordNets. New additions: Afrikaans, German, Korean, Maltese, Polish, Somali, Swahili.
</dd> </dd>
<dt class="col-sm-3 text-center text-nowrap">2021-03-01</dt>
<dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2020/">Seventh GF Summer School</a>, in Singapore and online, 26 July &ndash; 8 August 2021.
</dd>
<dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt> <dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
<a href="https://www.mitpressjournals.org/doi/pdf/10.1162/COLI_a_00378">Abstract Syntax as Interlingua</a>: Scaling Up the Grammatical Framework from Controlled Languages to Robust Pipelines. A paper in Computational Linguistics (2020) summarizing much of the development in GF in the past ten years. <a href="https://www.mitpressjournals.org/doi/pdf/10.1162/COLI_a_00378">Abstract Syntax as Interlingua</a>: Scaling Up the Grammatical Framework from Controlled Languages to Robust Pipelines. A paper in Computational Linguistics (2020) summarizing much of the development in GF in the past ten years.
</dd> </dd>
<dt class="col-sm-3 text-center text-nowrap">2018-12-03</dt>
<dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2018/">Sixth GF Summer School</a> in Stellenbosch (South Africa), 314 December 2018
</dd>
<dt class="col-sm-3 text-center text-nowrap">2018-12-02</dt>
<dd class="col-sm-9">
<strong>GF 3.10 released.</strong>
<a href="download/release-3.10.html">Release notes</a>
</dd>
<dt class="col-sm-3 text-center text-nowrap">2018-07-25</dt>
<dd class="col-sm-9">
The GF repository has been split in two:
<a href="https://github.com/GrammaticalFramework/gf-core">gf-core</a> and
<a href="https://github.com/GrammaticalFramework/gf-rgl">gf-rgl</a>.
The original <a href="https://github.com/GrammaticalFramework/GF">GF</a> repository is now archived.
</dd>
<dt class="col-sm-3 text-center text-nowrap">2017-08-11</dt>
<dd class="col-sm-9">
<strong>GF 3.9 released.</strong>
<a href="download/release-3.9.html">Release notes</a>
</dd>
<dt class="col-sm-3 text-center text-nowrap">2017-06-29</dt>
<dd class="col-sm-9">
GF is moving to <a href="https://github.com/GrammaticalFramework/GF/">GitHub</a>.</dd>
<dt class="col-sm-3 text-center text-nowrap">2017-03-13</dt>
<dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2017/">GF Summer School</a> in Riga (Latvia), 14-25 August 2017
</dd>
</dl> </dl>
<h2>Projects</h2> <h2>Projects</h2>
@@ -337,7 +340,7 @@ least one, it may help you to get a first idea of what GF is.
Libraries are at the heart of modern software engineering. In natural language Libraries are at the heart of modern software engineering. In natural language
applications, libraries are a way to cope with thousands of details involved in applications, libraries are a way to cope with thousands of details involved in
syntax, lexicon, and inflection. The syntax, lexicon, and inflection. The
<a href="lib/doc/synopsis/index.html">GF resource grammar library</a> has <a href="lib/doc/synopsis/index.html">GF resource grammar library</a> (RGL) has
support for an increasing number of languages, currently including support for an increasing number of languages, currently including
Afrikaans, Afrikaans,
Amharic (partial), Amharic (partial),

12
nix/expose-all.patch Normal file
View File

@@ -0,0 +1,12 @@
diff --git a/gf.cabal b/gf.cabal
index 0076e7638..8d3fe4b49 100644
--- a/gf.cabal
+++ b/gf.cabal
@@ -168,7 +168,6 @@ Library
GF.Text.Lexing
GF.Grammar.Canonical
- other-modules:
GF.Main
GF.Compiler
GF.Interactive

View File

@@ -0,0 +1,193 @@
commit 45e5473fcd5707af93646d9a116867a4d4e3e9c9
Author: Andreas Källberg <anka.213@gmail.com>
Date: Mon Oct 10 14:57:12 2022 +0200
Revert "workaround for the Nix madness"
This reverts commit 1294269cd60f3db7b056135104615625baeb528c.
There are easier workarounds, like using
cabal v1-build
etc. instead of just `cabal build`
These changes also broke a whole bunch of other stuff
diff --git a/README.md b/README.md
index ba35795a4..79e6ab68f 100644
--- a/README.md
+++ b/README.md
@@ -38,21 +38,6 @@ or:
```
stack install
```
-Note that if you are unlucky to have Cabal 3.0 or later, then it uses
-the so-called Nix style commands. Using those for GF development is
-a pain. Every time when you change something in the source code, Cabal
-will generate a new folder for GF to look for the GF libraries and
-the GF cloud. Either reinstall everything with every change in the
-compiler, or be sane and stop using cabal-install. Instead you can do:
-```
-runghc Setup.hs configure
-runghc Setup.hs build
-sudo runghc Setup.hs install
-```
-The script will install the GF dependencies globally. The only solution
-to the Nix madness that I found is radical:
-
- "No person, no problem" (Нет человека нет проблемы).
For more information, including links to precompiled binaries, see the [download page](https://www.grammaticalframework.org/download/index.html).
diff --git a/Setup.hs b/Setup.hs
index 58dc3e0c6..f8309cc00 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -4,68 +4,42 @@ import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..),absoluteInstallDirs
import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..))
import Distribution.PackageDescription(PackageDescription(..),emptyHookedBuildInfo)
import Distribution.Simple.BuildPaths(exeExtension)
-import System.Directory
import System.FilePath((</>),(<.>))
-import System.Process
-import Control.Monad(forM_,unless)
-import Control.Exception(bracket_)
-import Data.Char(isSpace)
import WebSetup
+-- | Notice about RGL not built anymore
+noRGLmsg :: IO ()
+noRGLmsg = putStrLn "Notice: the RGL is not built as part of GF anymore. See https://github.com/GrammaticalFramework/gf-rgl"
+
main :: IO ()
main = defaultMainWithHooks simpleUserHooks
- { preConf = gfPreConf
- , preBuild = gfPreBuild
+ { preBuild = gfPreBuild
, postBuild = gfPostBuild
, preInst = gfPreInst
, postInst = gfPostInst
, postCopy = gfPostCopy
}
where
- gfPreConf args flags = do
- pkgs <- fmap (map (dropWhile isSpace) . tail . lines)
- (readProcess "ghc-pkg" ["list"] "")
- forM_ dependencies $ \pkg -> do
- let name = takeWhile (/='/') (drop 36 pkg)
- unless (name `elem` pkgs) $ do
- let fname = name <.> ".tar.gz"
- callProcess "wget" [pkg,"-O",fname]
- callProcess "tar" ["-xzf",fname]
- removeFile fname
- bracket_ (setCurrentDirectory name) (setCurrentDirectory ".." >> removeDirectoryRecursive name) $ do
- exists <- doesFileExist "Setup.hs"
- unless exists $ do
- writeFile "Setup.hs" (unlines [
- "import Distribution.Simple",
- "main = defaultMain"
- ])
- let to_descr = reverse .
- (++) (reverse ".cabal") .
- drop 1 .
- dropWhile (/='-') .
- reverse
- callProcess "wget" [to_descr pkg, "-O", to_descr name]
- callProcess "runghc" ["Setup.hs","configure"]
- callProcess "runghc" ["Setup.hs","build"]
- callProcess "sudo" ["runghc","Setup.hs","install"]
-
- preConf simpleUserHooks args flags
-
- gfPreBuild args = gfPre args . buildDistPref
- gfPreInst args = gfPre args . installDistPref
+ gfPreBuild args = gfPre args . buildDistPref
+ gfPreInst args = gfPre args . installDistPref
gfPre args distFlag = do
return emptyHookedBuildInfo
gfPostBuild args flags pkg lbi = do
+ -- noRGLmsg
let gf = default_gf lbi
buildWeb gf flags (pkg,lbi)
gfPostInst args flags pkg lbi = do
+ -- noRGLmsg
+ saveInstallPath args flags (pkg,lbi)
installWeb (pkg,lbi)
gfPostCopy args flags pkg lbi = do
+ -- noRGLmsg
+ saveCopyPath args flags (pkg,lbi)
copyWeb flags (pkg,lbi)
-- `cabal sdist` will not make a proper dist archive, for that see `make sdist`
@@ -73,16 +47,27 @@ main = defaultMainWithHooks simpleUserHooks
gfSDist pkg lbi hooks flags = do
return ()
-dependencies = [
- "https://hackage.haskell.org/package/utf8-string-1.0.2/utf8-string-1.0.2.tar.gz",
- "https://hackage.haskell.org/package/json-0.10/json-0.10.tar.gz",
- "https://hackage.haskell.org/package/network-bsd-2.8.1.0/network-bsd-2.8.1.0.tar.gz",
- "https://hackage.haskell.org/package/httpd-shed-0.4.1.1/httpd-shed-0.4.1.1.tar.gz",
- "https://hackage.haskell.org/package/exceptions-0.10.5/exceptions-0.10.5.tar.gz",
- "https://hackage.haskell.org/package/stringsearch-0.3.6.6/stringsearch-0.3.6.6.tar.gz",
- "https://hackage.haskell.org/package/multipart-0.2.1/multipart-0.2.1.tar.gz",
- "https://hackage.haskell.org/package/cgi-3001.5.0.0/cgi-3001.5.0.0.tar.gz"
- ]
+saveInstallPath :: [String] -> InstallFlags -> (PackageDescription, LocalBuildInfo) -> IO ()
+saveInstallPath args flags bi = do
+ let
+ dest = NoCopyDest
+ dir = datadir (uncurry absoluteInstallDirs bi dest)
+ writeFile dataDirFile dir
+
+saveCopyPath :: [String] -> CopyFlags -> (PackageDescription, LocalBuildInfo) -> IO ()
+saveCopyPath args flags bi = do
+ let
+ dest = case copyDest flags of
+ NoFlag -> NoCopyDest
+ Flag d -> d
+ dir = datadir (uncurry absoluteInstallDirs bi dest)
+ writeFile dataDirFile dir
+
+-- | Name of file where installation's data directory is recording
+-- This is a last-resort way in which the seprate RGL build script
+-- can determine where to put the compiled RGL files
+dataDirFile :: String
+dataDirFile = "DATA_DIR"
-- | Get path to locally-built gf
default_gf :: LocalBuildInfo -> FilePath
diff --git a/gf.cabal b/gf.cabal
index a055b86be..d00a5b935 100644
--- a/gf.cabal
+++ b/gf.cabal
@@ -2,7 +2,7 @@ name: gf
version: 3.11.0-git
cabal-version: 1.22
-build-type: Simple
+build-type: Custom
license: OtherLicense
license-file: LICENSE
category: Natural Language Processing, Compiler
@@ -44,6 +44,14 @@ data-files:
www/translator/*.css
www/translator/*.js
+custom-setup
+ setup-depends:
+ base >= 4.9.1 && < 4.16,
+ Cabal >= 1.22.0.0,
+ directory >= 1.3.0 && < 1.4,
+ filepath >= 1.4.1 && < 1.5,
+ process >= 1.0.1.1 && < 1.7
+
source-repository head
type: git
location: https://github.com/GrammaticalFramework/gf-core.git

View File

@@ -4,6 +4,7 @@ module GF.Command.Commands (
options,flags, options,flags,
) where ) where
import Prelude hiding (putStrLn,(<>)) -- GHC 8.4.1 clash with Text.PrettyPrint import Prelude hiding (putStrLn,(<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
import System.Info(os)
import PGF import PGF
@@ -21,6 +22,7 @@ import GF.Infra.SIO
import GF.Command.Abstract import GF.Command.Abstract
import GF.Command.CommandInfo import GF.Command.CommandInfo
import GF.Command.CommonCommands import GF.Command.CommonCommands
import qualified GF.Command.CommonCommands as Common
import GF.Text.Clitics import GF.Text.Clitics
import GF.Quiz import GF.Quiz
@@ -165,14 +167,15 @@ pgfCommands = Map.fromList [
synopsis = "generate random trees in the current abstract syntax", synopsis = "generate random trees in the current abstract syntax",
syntax = "gr [-cat=CAT] [-number=INT]", syntax = "gr [-cat=CAT] [-number=INT]",
examples = [ examples = [
mkEx "gr -- one tree in the startcat of the current grammar", 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 -number=16 -- 16 trees in the category NP",
mkEx "gr -lang=LangHin,LangTha -cat=Cl -- Cl, both in LangHin and LangTha", mkEx "gr -cat=NP -depth=2 -- one tree in the category NP, up to depth 2",
mkEx "gr -probs=FILE -- generate with bias", mkEx "gr -lang=LangHin,LangTha -cat=Cl -- Cl, both in LangHin and LangTha",
mkEx "gr (AdjCN ? (UseN ?)) -- generate trees of form (AdjCN ? (UseN ?))" mkEx "gr -probs=FILE -- generate with bias",
mkEx "gr (AdjCN ? (UseN ?)) -- generate trees of form (AdjCN ? (UseN ?))"
], ],
explanation = unlines [ 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", "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,", "all metavariables in the tree. The generation can be biased by probabilities,",
"given in a file in the -probs flag." "given in a file in the -probs flag."
@@ -181,13 +184,13 @@ pgfCommands = Map.fromList [
("cat","generation category"), ("cat","generation category"),
("lang","uses only functions that have linearizations in all these languages"), ("lang","uses only functions that have linearizations in all these languages"),
("number","number of trees generated"), ("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)") ("probs", "file with biased probabilities (format 'f 0.4' one by line)")
], ],
exec = getEnv $ \ opts arg (Env pgf mos) -> do exec = getEnv $ \ opts arg (Env pgf mos) -> do
pgf <- optProbs opts (optRestricted opts pgf) pgf <- optProbs opts (optRestricted opts pgf)
gen <- newStdGen gen <- newStdGen
let dp = valIntOpts "depth" 4 opts let dp = valIntOpts "depth" Common.default_depth opts
let ts = case mexp (toExprs arg) of let ts = case mexp (toExprs arg) of
Just ex -> generateRandomFromDepth gen pgf ex (Just dp) Just ex -> generateRandomFromDepth gen pgf ex (Just dp)
Nothing -> generateRandomDepth gen pgf (optType pgf opts) (Just dp) Nothing -> generateRandomDepth gen pgf (optType pgf opts) (Just dp)
@@ -198,28 +201,28 @@ pgfCommands = Map.fromList [
synopsis = "generates a list of trees, by default exhaustive", synopsis = "generates a list of trees, by default exhaustive",
explanation = unlines [ explanation = unlines [
"Generates all trees of a given category. By default, ", "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", "If a Tree argument is given, the command completes the Tree with values",
"to all metavariables in the tree." "to all metavariables in the tree."
], ],
flags = [ flags = [
("cat","the generation category"), ("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"), ("lang","excludes functions that have no linearization in this language"),
("number","the number of trees generated") ("number","the number of trees generated")
], ],
examples = [ examples = [
mkEx "gt -- all trees in the startcat, to depth 4", 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 -number=16 -- 16 trees in the category NP",
mkEx "gt -cat=NP -depth=2 -- trees in the category NP to depth 2", 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 (AdjCN ? (UseN ?)) -- trees of form (AdjCN ? (UseN ?))"
], ],
exec = getEnv $ \ opts arg (Env pgf mos) -> do exec = getEnv $ \ opts arg (Env pgf mos) -> do
let pgfr = optRestricted opts pgf let pgfr = optRestricted opts pgf
let dp = valIntOpts "depth" 4 opts let dp = valIntOpts "depth" Common.default_depth opts
let ts = case mexp (toExprs arg) of let ts = case toExprs arg of
Just ex -> generateFromDepth pgfr ex (Just dp) [] -> generateAllDepth pgfr (optType pgf opts) (Just dp)
Nothing -> generateAllDepth pgfr (optType pgf opts) (Just dp) es -> concat [generateFromDepth pgfr e (Just dp) | e <- es]
returnFromExprs $ take (optNumInf opts) ts returnFromExprs $ take (optNumInf opts) ts
}), }),
("i", emptyCommandInfo { ("i", emptyCommandInfo {
@@ -427,7 +430,8 @@ pgfCommands = Map.fromList [
"are type checking and semantic computation." "are type checking and semantic computation."
], ],
examples = [ examples = [
mkEx "pt -compute (plus one two) -- compute value" mkEx "pt -compute (plus one two) -- compute value",
mkEx ("p \"the 4 dogs\" | pt -transfer=digits2numeral | l -- \"the four dogs\" ")
], ],
exec = getEnv $ \ opts arg (Env pgf mos) -> exec = getEnv $ \ opts arg (Env pgf mos) ->
returnFromExprs . takeOptNum opts . treeOps pgf opts $ toExprs arg, returnFromExprs . takeOptNum opts . treeOps pgf opts $ toExprs arg,
@@ -545,7 +549,7 @@ pgfCommands = Map.fromList [
"which is processed by dot (graphviz) and displayed by the program indicated", "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", "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).", "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 exec = getEnv $ \ opts arg (Env pgf mos) -> do
let absname = abstractName pgf let absname = abstractName pgf
@@ -758,7 +762,7 @@ pgfCommands = Map.fromList [
[] -> [parse_ pgf lang (optType pgf opts) (Just dp) s | lang <- optLangs pgf opts] [] -> [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] open_typs -> [parseWithRecovery pgf lang (optType pgf opts) open_typs (Just dp) s | lang <- optLangs pgf opts]
where where
dp = valIntOpts "depth" 4 opts dp = valIntOpts "depth" Common.default_depth opts
fromParse opts = foldr (joinPiped . fromParse1 opts) void fromParse opts = foldr (joinPiped . fromParse1 opts) void
@@ -798,9 +802,9 @@ pgfCommands = Map.fromList [
_ | isOpt "tabtreebank" opts -> _ | isOpt "tabtreebank" opts ->
return $ concat $ intersperse "\t" $ (showExpr [] t) : return $ concat $ intersperse "\t" $ (showExpr [] t) :
[s | lang <- optLangs pgf opts, s <- linear pgf opts lang 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] _ -> [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] [(lang, unwords (intersperse "<+>" (map (unlines . linear pgf opts lang) (treeChunks t)))) | lang <- optLangs pgf opts]
linear :: PGF -> [Option] -> CId -> Expr -> [String] linear :: PGF -> [Option] -> CId -> Expr -> [String]
@@ -882,11 +886,15 @@ pgfCommands = Map.fromList [
Right ty -> ty Right ty -> ty
Nothing -> error ("Can't parse '"++str++"' as a type") Nothing -> error ("Can't parse '"++str++"' as a type")
optViewFormat opts = valStrOpts "format" "png" opts optViewFormat opts = valStrOpts "format" "png" opts
optViewGraph opts = valStrOpts "view" "open" opts optViewGraph opts = valStrOpts "view" open_cmd opts
optNum opts = valIntOpts "number" 1 opts optNum opts = valIntOpts "number" 1 opts
optNumInf opts = valIntOpts "number" 1000000000 opts ---- 10^9 optNumInf opts = valIntOpts "number" 1000000000 opts ---- 10^9
takeOptNum opts = take (optNumInf opts) takeOptNum opts = take (optNumInf opts)
open_cmd | os == "linux" = "xdg-open"
| os == "mingw32" = "start"
| otherwise = "open"
returnFromExprs es = return $ case es of returnFromExprs es = return $ case es of
[] -> pipeMessage "no trees found" [] -> pipeMessage "no trees found"
_ -> fromExprs es _ -> fromExprs es
@@ -1000,13 +1008,13 @@ viewLatex view name grphs = do
restrictedSystem $ "pdflatex " ++ texfile restrictedSystem $ "pdflatex " ++ texfile
restrictedSystem $ view ++ " " ++ pdffile restrictedSystem $ view ++ " " ++ pdffile
return void return void
---- copied from VisualizeTree ; not sure about proper place AR Nov 2015 ---- copied from VisualizeTree ; not sure about proper place AR Nov 2015
latexDoc :: [String] -> String latexDoc :: [String] -> String
latexDoc body = unlines $ latexDoc body = unlines $
"\\batchmode" "\\batchmode"
: "\\documentclass{article}" : "\\documentclass{article}"
: "\\usepackage[utf8]{inputenc}" : "\\usepackage[utf8]{inputenc}"
: "\\begin{document}" : "\\begin{document}"
: spaces body : spaces body
++ ["\\end{document}"] ++ ["\\end{document}"]
@@ -1022,4 +1030,4 @@ stanzas = map unlines . chop . lines where
#if !(MIN_VERSION_base(4,9,0)) #if !(MIN_VERSION_base(4,9,0))
errorWithoutStackTrace = error errorWithoutStackTrace = error
#endif #endif

View File

@@ -19,6 +19,12 @@ import Data.Char (isSpace)
import qualified PGF as H(showCId,showExpr,toATree,toTrie,Trie(..)) 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 extend old new = Map.union (Map.fromList new) old -- Map.union is left-biased
commonCommands :: (Monad m,MonadSIO m) => Map.Map String (CommandInfo m) commonCommands :: (Monad m,MonadSIO m) => Map.Map String (CommandInfo m)

View File

@@ -5,6 +5,8 @@ module GF.Command.TreeOperations (
) where ) where
import PGF(Expr,PGF,CId,compute,mkApp,unApp,unapply,unMeta,exprSize,exprFunctions) import PGF(Expr,PGF,CId,compute,mkApp,unApp,unapply,unMeta,exprSize,exprFunctions)
import PGF.Data(Expr(EApp,EFun))
import PGF.TypeCheck(inferExpr)
import Data.List import Data.List
type TreeOp = [Expr] -> [Expr] type TreeOp = [Expr] -> [Expr]
@@ -16,15 +18,17 @@ allTreeOps :: PGF -> [(String,(String,Either TreeOp (CId -> TreeOp)))]
allTreeOps pgf = [ allTreeOps pgf = [
("compute",("compute by using semantic definitions (def)", ("compute",("compute by using semantic definitions (def)",
Left $ map (compute pgf))), Left $ map (compute pgf))),
("transfer",("apply this transfer function to all maximal subtrees of suitable type",
Right $ \f -> map (transfer pgf f))), -- HL 12/24, modified from gf-3.3
("largest",("sort trees from largest to smallest, in number of nodes", ("largest",("sort trees from largest to smallest, in number of nodes",
Left $ largest)), Left $ largest)),
("nub",("remove duplicate trees", ("nub\t",("remove duplicate trees",
Left $ nub)), Left $ nub)),
("smallest",("sort trees from smallest to largest, in number of nodes", ("smallest",("sort trees from smallest to largest, in number of nodes",
Left $ smallest)), Left $ smallest)),
("subtrees",("return all fully applied subtrees (stopping at abstractions), by default sorted from the largest", ("subtrees",("return all fully applied subtrees (stopping at abstractions), by default sorted from the largest",
Left $ concatMap subtrees)), Left $ concatMap subtrees)),
("funs",("return all fun functions appearing in the tree, with duplications", ("funs\t",("return all fun functions appearing in the tree, with duplications",
Left $ \es -> [mkApp f [] | e <- es, f <- exprFunctions e])) Left $ \es -> [mkApp f [] | e <- es, f <- exprFunctions e]))
] ]
@@ -48,3 +52,18 @@ subtrees :: Expr -> [Expr]
subtrees t = t : case unApp t of subtrees t = t : case unApp t of
Just (f,ts) -> concatMap subtrees ts Just (f,ts) -> concatMap subtrees ts
_ -> [] -- don't go under abstractions _ -> [] -- don't go under abstractions
-- Apply transfer function f:C -> D to all maximal subtrees s:C of tree e and replace
-- these s by the values of f(s). This modifies the 'simple-minded transfer' of gf-3.3.
-- If applied to strict subtrees s of e, better use with f:C -> C only. HL 12/2024
transfer :: PGF -> CId -> Expr -> Expr
transfer pgf f e = case inferExpr pgf (appf e) of
Left _err -> case e of
EApp g a -> EApp (transfer pgf f g) (transfer pgf f a)
_ -> e
Right _ty -> case (compute pgf (appf e)) of
v | v /= (appf e) -> v
_ -> e -- default case of f, or f has no computation rule
where
appf = EApp (EFun f)

View File

@@ -18,7 +18,7 @@ import Data.List
-------------------------- --------------------------
cf2pgf :: FilePath -> ParamCFG -> PGF cf2pgf :: FilePath -> ParamCFG -> PGF
cf2pgf fpath cf = cf2pgf fpath cf =
let pgf = PGF Map.empty aname (cf2abstr cf) (Map.singleton cname (cf2concr cf)) let pgf = PGF Map.empty aname (cf2abstr cf) (Map.singleton cname (cf2concr cf))
in updateProductionIndices pgf in updateProductionIndices pgf
where where
@@ -33,7 +33,7 @@ cf2abstr cfg = Abstr aflags afuns acats
acats = Map.fromList [(cat, ([], [(0,mkRuleName rule) | rule <- rules], 0)) acats = Map.fromList [(cat, ([], [(0,mkRuleName rule) | rule <- rules], 0))
| (cat,rules) <- (Map.toList . Map.fromListWith (++)) | (cat,rules) <- (Map.toList . Map.fromListWith (++))
[(cat2id cat, catRules cfg cat) | [(cat2id cat, catRules cfg cat) |
cat <- allCats' cfg]] cat <- allCats' cfg]]
afuns = Map.fromList [(mkRuleName rule, (cftype [cat2id c | NonTerminal c <- ruleRhs rule] (cat2id (ruleLhs rule)), 0, Nothing, 0)) afuns = Map.fromList [(mkRuleName rule, (cftype [cat2id c | NonTerminal c <- ruleRhs rule] (cat2id (ruleLhs rule)), 0, Nothing, 0))
| rule <- allRules cfg] | rule <- allRules cfg]
@@ -52,7 +52,7 @@ cf2concr cfg = Concr Map.empty Map.empty
cats = allCats' cfg cats = allCats' cfg
rules = allRules cfg rules = allRules cfg
sequences0 = Set.fromList (listArray (0,0) [SymCat 0 0] : sequences0 = Set.fromList (listArray (0,0) [SymCat 0 0] :
map mkSequence rules) map mkSequence rules)
sequences = listArray (0,Set.size sequences0-1) (Set.toList sequences0) sequences = listArray (0,Set.size sequences0-1) (Set.toList sequences0)
@@ -102,7 +102,7 @@ cf2concr cfg = Concr Map.empty Map.empty
mkLinDefRef (cat,_) = mkLinDefRef (cat,_) =
(cat2fid cat 0,[0]) (cat2fid cat 0,[0])
addProd prods (fid,prod) = addProd prods (fid,prod) =
case IntMap.lookup fid prods of case IntMap.lookup fid prods of
Just set -> IntMap.insert fid (Set.insert prod set) prods Just set -> IntMap.insert fid (Set.insert prod set) prods
@@ -130,5 +130,5 @@ cf2concr cfg = Concr Map.empty Map.empty
mkRuleName rule = mkRuleName rule =
case ruleName rule of case ruleName rule of
CFObj n _ -> n CFObj n _ -> n
_ -> wildCId _ -> wildCId

View File

@@ -175,7 +175,7 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do
checkTyp gr typ checkTyp gr typ
case md of case md of
Just eqs -> mapM_ (\(L loc eq) -> mkCheck loc "the definition of function" $ Just eqs -> mapM_ (\(L loc eq) -> mkCheck loc "the definition of function" $
checkDef gr (m,c) typ eq) eqs checkDef gr (m,c) typ eq) eqs
Nothing -> return () Nothing -> return ()
return (AbsFun (Just (L loc typ)) ma md moper) return (AbsFun (Just (L loc typ)) ma md moper)
@@ -316,7 +316,7 @@ linTypeOfType cnc m typ = do
mkLinArg (i,(n,mc@(m,cat))) = do mkLinArg (i,(n,mc@(m,cat))) = do
val <- lookLin mc val <- lookLin mc
let vars = mkRecType varLabel $ replicate n typeStr let vars = mkRecType varLabel $ replicate n typeStr
symb = argIdent n cat i symb = argIdent n cat i
rec <- if n==0 then return val else rec <- if n==0 then return val else
errIn (render ("extending" $$ errIn (render ("extending" $$
nest 2 vars $$ nest 2 vars $$

View File

@@ -30,11 +30,12 @@ import Debug.Trace(trace)
normalForm :: GlobalEnv -> L Ident -> Term -> Term normalForm :: GlobalEnv -> L Ident -> Term -> Term
normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc) normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc)
nfx :: GlobalEnv -> Term -> Err Term
nfx env@(GE _ _ _ loc) t = do nfx env@(GE _ _ _ loc) t = do
v <- eval env [] t v <- eval env [] t
case value2term loc [] v of return (value2term loc [] v)
Left i -> fail ("variable #"++show i++" is out of scope") -- Old value2term error message:
Right t -> return t -- Left i -> fail ("variable #"++show i++" is out of scope")
eval :: GlobalEnv -> Env -> Term -> Err Value eval :: GlobalEnv -> Env -> Term -> Err Value
eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t
@@ -171,11 +172,11 @@ value env t0 =
ImplArg t -> (VImplArg.) # value env t ImplArg t -> (VImplArg.) # value env t
Table p res -> liftM2 VTblType # value env p <# value env res Table p res -> liftM2 VTblType # value env p <# value env res
RecType rs -> do lovs <- mapPairsM (value env) rs RecType rs -> do lovs <- mapPairsM (value env) rs
return $ \vs->VRecType $ mapSnd ($vs) lovs return $ \vs->VRecType $ mapSnd ($ vs) lovs
t@(ExtR t1 t2) -> ((extR t.)# both id) # both (value env) (t1,t2) t@(ExtR t1 t2) -> ((extR t.)# both id) # both (value env) (t1,t2)
FV ts -> ((vfv .) # sequence) # mapM (value env) ts FV ts -> ((vfv .) # sequence) # mapM (value env) ts
R as -> do lovs <- mapPairsM (value env.snd) as R as -> do lovs <- mapPairsM (value env.snd) as
return $ \ vs->VRec $ mapSnd ($vs) lovs return $ \ vs->VRec $ mapSnd ($ vs) lovs
T i cs -> valueTable env i cs T i cs -> valueTable env i cs
V ty ts -> do pvs <- paramValues env ty V ty ts -> do pvs <- paramValues env ty
((VV ty pvs .) . sequence) # mapM (value env) ts ((VV ty pvs .) . sequence) # mapM (value env) ts
@@ -288,9 +289,9 @@ glue env (v1,v2) = glu v1 v2
(v1,v2) -> if flag optPlusAsBind (opts env) (v1,v2) -> if flag optPlusAsBind (opts env)
then VC v1 (VC (VApp BIND []) v2) then VC v1 (VC (VApp BIND []) v2)
else let loc = gloc env else let loc = gloc env
vt v = case value2term loc (local env) v of vt v = value2term loc (local env) v
Left i -> Error ('#':show i) -- Old value2term error message:
Right t -> t -- Left i -> Error ('#':show i)
originalMsg = render $ ppL loc (hang "unsupported token gluing" 4 originalMsg = render $ ppL loc (hang "unsupported token gluing" 4
(Glue (vt v1) (vt v2))) (Glue (vt v1) (vt v2)))
term = render $ pp $ Glue (vt v1) (vt v2) term = render $ pp $ Glue (vt v1) (vt v2)
@@ -355,9 +356,9 @@ select env vv =
(v1,v2) -> ok2 VS v1 v2 (v1,v2) -> ok2 VS v1 v2
match loc cs v = match loc cs v =
case value2term loc [] v of err bad return (matchPattern cs (value2term loc [] v))
Left i -> bad ("variable #"++show i++" is out of scope") -- Old value2term error message:
Right t -> err bad return (matchPattern cs t) -- Left i -> bad ("variable #"++show i++" is out of scope")
where where
bad = fail . ("In pattern matching: "++) bad = fail . ("In pattern matching: "++)
@@ -375,24 +376,23 @@ valueTable env i cs =
where where
dynamic cs' ty _ = cases cs' # value env ty dynamic cs' ty _ = cases cs' # value env ty
cases cs' vty vs = err keep ($vs) (convertv cs' (vty vs)) cases cs' vty vs = err keep ($ vs) (convertv cs' (vty vs))
where where
keep msg = --trace (msg++"\n"++render (ppTerm Unqualified 0 (T i cs))) $ keep msg = --trace (msg++"\n"++render (ppTerm Unqualified 0 (T i cs))) $
VT wild (vty vs) (mapSnd ($vs) cs') VT wild (vty vs) (mapSnd ($ vs) cs')
wild = case i of TWild _ -> True; _ -> False wild = case i of TWild _ -> True; _ -> False
convertv cs' vty = convertv cs' vty =
case value2term (gloc env) [] vty of convert' cs' =<< paramValues'' env (value2term (gloc env) [] vty)
Left i -> fail ("variable #"++show i++" is out of scope") -- Old value2term error message: Left i -> fail ("variable #"++show i++" is out of scope")
Right pty -> convert' cs' =<< paramValues'' env pty
convert cs' ty = convert' cs' =<< paramValues' env ty convert cs' ty = convert' cs' =<< paramValues' env ty
convert' cs' ((pty,vs),pvs) = convert' cs' ((pty,vs),pvs) =
do sts <- mapM (matchPattern cs') vs do sts <- mapM (matchPattern cs') vs
return $ \ vs -> VV pty pvs $ map (err bug id . valueMatch env) return $ \ vs -> VV pty pvs $ map (err bug id . valueMatch env)
(mapFst ($vs) sts) (mapFst ($ vs) sts)
valueCase (p,t) = do p' <- measurePatt # inlinePattMacro p valueCase (p,t) = do p' <- measurePatt # inlinePattMacro p
pvs <- linPattVars p' pvs <- linPattVars p'
@@ -430,19 +430,19 @@ apply' :: CompleteEnv -> Term -> [OpenValue] -> Err OpenValue
apply' env t [] = value env t apply' env t [] = value env t
apply' env t vs = apply' env t vs =
case t of case t of
QC x -> return $ \ svs -> VCApp x (map ($svs) vs) QC x -> return $ \ svs -> VCApp x (map ($ svs) vs)
{- {-
Q x@(m,f) | m==cPredef -> return $ Q x@(m,f) | m==cPredef -> return $
let constr = --trace ("predef "++show x) . let constr = --trace ("predef "++show x) .
VApp x VApp x
in \ svs -> maybe constr id (Map.lookup f predefs) in \ svs -> maybe constr id (Map.lookup f predefs)
$ map ($svs) vs $ map ($ svs) vs
| otherwise -> do r <- resource env x | otherwise -> do r <- resource env x
return $ \ svs -> vapply (gloc env) r (map ($svs) vs) return $ \ svs -> vapply (gloc env) r (map ($ svs) vs)
-} -}
App t1 t2 -> apply' env t1 . (:vs) =<< value env t2 App t1 t2 -> apply' env t1 . (:vs) =<< value env t2
_ -> do fv <- value env t _ -> do fv <- value env t
return $ \ svs -> vapply (gloc env) (fv svs) (map ($svs) vs) return $ \ svs -> vapply (gloc env) (fv svs) (map ($ svs) vs)
vapply :: GLocation -> Value -> [Value] -> Value vapply :: GLocation -> Value -> [Value] -> Value
vapply loc v [] = v vapply loc v [] = v
@@ -492,58 +492,60 @@ vtrace loc arg res = trace (render (hang (pv arg) 4 ("->"<+>pv res))) res
pf (_,VString n) = pp n pf (_,VString n) = pp n
pf (_,v) = ppV v pf (_,v) = ppV v
pa (_,v) = ppV v pa (_,v) = ppV v
ppV v = case value2term' True loc [] v of ppV v = ppTerm Unqualified 10 (value2term' True loc [] v)
Left i -> "variable #" <> pp i <+> "is out of scope" -- Old value2term error message:
Right t -> ppTerm Unqualified 10 t -- Left i -> "variable #" <> pp i <+> "is out of scope"
-- | Convert a value back to a term -- | Convert a value back to a term
value2term :: GLocation -> [Ident] -> Value -> Either Int Term value2term :: GLocation -> [Ident] -> Value -> Term
value2term = value2term' False value2term = value2term' False
value2term' :: Bool -> p -> [Ident] -> Value -> Term
value2term' stop loc xs v0 = value2term' stop loc xs v0 =
case v0 of case v0 of
VApp pre vs -> liftM (foldl App (Q (cPredef,predefName pre))) (mapM v2t vs) VApp pre vs -> applyMany (Q (cPredef,predefName pre)) vs
VCApp f vs -> liftM (foldl App (QC f)) (mapM v2t vs) VCApp f vs -> applyMany (QC f) vs
VGen j vs -> liftM2 (foldl App) (var j) (mapM v2t vs) VGen j vs -> applyMany (var j) vs
VMeta j env vs -> liftM (foldl App (Meta j)) (mapM v2t vs) VMeta j env vs -> applyMany (Meta j) vs
VProd bt v x f -> liftM2 (Prod bt x) (v2t v) (v2t' x f) VProd bt v x f -> Prod bt x (v2t v) (v2t' x f)
VAbs bt x f -> liftM (Abs bt x) (v2t' x f) VAbs bt x f -> Abs bt x (v2t' x f)
VInt n -> return (EInt n) VInt n -> EInt n
VFloat f -> return (EFloat f) VFloat f -> EFloat f
VString s -> return (if null s then Empty else K s) VString s -> if null s then Empty else K s
VSort s -> return (Sort s) VSort s -> Sort s
VImplArg v -> liftM ImplArg (v2t v) VImplArg v -> ImplArg (v2t v)
VTblType p res -> liftM2 Table (v2t p) (v2t res) VTblType p res -> Table (v2t p) (v2t res)
VRecType rs -> liftM RecType (mapM (\(l,v) -> fmap ((,) l) (v2t v)) rs) VRecType rs -> RecType [(l, v2t v) | (l,v) <- rs]
VRec as -> liftM R (mapM (\(l,v) -> v2t v >>= \t -> return (l,(Nothing,t))) as) VRec as -> R [(l, (Nothing, v2t v)) | (l,v) <- as]
VV t _ vs -> liftM (V t) (mapM v2t vs) VV t _ vs -> V t (map v2t vs)
VT wild v cs -> v2t v >>= \t -> liftM (T ((if wild then TWild else TTyped) t)) (mapM nfcase cs) VT wild v cs -> T ((if wild then TWild else TTyped) (v2t v)) (map nfcase cs)
VFV vs -> liftM FV (mapM v2t vs) VFV vs -> FV (map v2t vs)
VC v1 v2 -> liftM2 C (v2t v1) (v2t v2) VC v1 v2 -> C (v2t v1) (v2t v2)
VS v1 v2 -> liftM2 S (v2t v1) (v2t v2) VS v1 v2 -> S (v2t v1) (v2t v2)
VP v l -> v2t v >>= \t -> return (P t l) VP v l -> P (v2t v) l
VPatt p -> return (EPatt p) VPatt p -> EPatt p
VPattType v -> v2t v >>= return . EPattType VPattType v -> EPattType $ v2t v
VAlts v vvs -> liftM2 Alts (v2t v) (mapM (\(x,y) -> liftM2 (,) (v2t x) (v2t y)) vvs) VAlts v vvs -> Alts (v2t v) [(v2t x, v2t y) | (x,y) <- vvs]
VStrs vs -> liftM Strs (mapM v2t vs) VStrs vs -> Strs (map v2t vs)
-- VGlue v1 v2 -> Glue (v2t v1) (v2t v2) -- VGlue v1 v2 -> Glue (v2t v1) (v2t v2)
-- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2) -- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2)
VError err -> return (Error err) VError err -> Error err
where where
applyMany f vs = foldl App f (map v2t vs)
v2t = v2txs xs v2t = v2txs xs
v2txs = value2term' stop loc v2txs = value2term' stop loc
v2t' x f = v2txs (x:xs) (bind f (gen xs)) v2t' x f = v2txs (x:xs) (bind f (gen xs))
var j var j
| j<length xs = Right (Vr (reverse xs !! j)) | j<length xs = Vr (reverse xs !! j)
| otherwise = Left j | otherwise = error ("variable #"++show j++" is out of scope")
pushs xs e = foldr push e xs pushs xs e = foldr push e xs
push x (env,xs) = ((x,gen xs):env,x:xs) push x (env,xs) = ((x,gen xs):env,x:xs)
gen xs = VGen (length xs) [] gen xs = VGen (length xs) []
nfcase (p,f) = liftM ((,) p) (v2txs xs' (bind f env')) nfcase (p,f) = (,) p (v2txs xs' (bind f env'))
where (env',xs') = pushs (pattVars p) ([],xs) where (env',xs') = pushs (pattVars p) ([],xs)
bind (Bind f) x = if stop bind (Bind f) x = if stop

View File

@@ -27,6 +27,10 @@ instance Predef Int where
instance Predef Bool where instance Predef Bool where
toValue = boolV toValue = boolV
fromValue v = case v of
VCApp (mn,i) [] | mn == cPredef && i == cPTrue -> return True
VCApp (mn,i) [] | mn == cPredef && i == cPFalse -> return False
_ -> verror "Bool" v
instance Predef String where instance Predef String where
toValue = string toValue = string

View File

@@ -201,11 +201,11 @@ instance Fail.MonadFail CnvMonad where
fail = bug fail = bug
instance Applicative CnvMonad where instance Applicative CnvMonad where
pure = return pure a = CM (\gr c s -> c a s)
(<*>) = ap (<*>) = ap
instance Monad CnvMonad where instance Monad CnvMonad where
return a = CM (\gr c s -> c a s) return = pure
CM m >>= k = CM (\gr c s -> m gr (\a s -> unCM (k a) gr c s) s) CM m >>= k = CM (\gr c s -> m gr (\a s -> unCM (k a) gr c s) s)
instance MonadState ([ProtoFCat],[Symbol]) CnvMonad where instance MonadState ([ProtoFCat],[Symbol]) CnvMonad where

View File

@@ -42,11 +42,12 @@ getSourceModule opts file0 =
raw <- liftIO $ keepTemp tmp raw <- liftIO $ keepTemp tmp
--ePutStrLn $ "1 "++file0 --ePutStrLn $ "1 "++file0
(optCoding,parsed) <- parseSource opts pModDef raw (optCoding,parsed) <- parseSource opts pModDef raw
let indentLines = unlines . map (" "++) . lines
case parsed of case parsed of
Left (Pn l c,msg) -> do file <- liftIO $ writeTemp tmp Left (Pn l c,msg) -> do file <- liftIO $ writeTemp tmp
cwd <- getCurrentDirectory cwd <- getCurrentDirectory
let location = makeRelative cwd file++":"++show l++":"++show c let location = makeRelative cwd file++":"++show l++":"++show c
raise (location++":\n "++msg) raise (location++":\n" ++ indentLines msg)
Right (i,mi0) -> Right (i,mi0) ->
do liftIO $ removeTemp tmp do liftIO $ removeTemp tmp
let mi =mi0 {mflags=mflags mi0 `addOptions` opts, msrc=file0} let mi =mi0 {mflags=mflags mi0 `addOptions` opts, msrc=file0}

View File

@@ -51,7 +51,7 @@ grammar2haskell opts name gr = foldr (++++) [] $
derivingClause derivingClause
| dataExt = "deriving (Show,Data)" | dataExt = "deriving (Show,Data)"
| otherwise = "deriving Show" | otherwise = "deriving Show"
extraImports | gadt = ["import Control.Monad.Identity", "import Data.Monoid"] extraImports | gadt = ["import Control.Monad.Identity", "import Control.Monad", "import Data.Monoid"]
| dataExt = ["import Data.Data"] | dataExt = ["import Data.Data"]
| otherwise = [] | otherwise = []
pgfImports | pgf2 = ["import PGF2 hiding (Tree)", "", "showCId :: CId -> String", "showCId = id"] pgfImports | pgf2 = ["import PGF2 hiding (Tree)", "", "showCId :: CId -> String", "showCId = id"]

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/05/30 18:39:44 $ -- > CVS $Date: 2005/05/30 18:39:44 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.19 $ -- > CVS $Revision: 1.19 $
-- --
@@ -23,9 +23,9 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Compile.Rename ( module GF.Compile.Rename (
renameSourceTerm, renameSourceTerm,
renameModule renameModule
) where ) where
import GF.Infra.Ident import GF.Infra.Ident
import GF.Infra.CheckM import GF.Infra.CheckM
@@ -68,7 +68,7 @@ renameIdentTerm env = accumulateError (renameIdentTerm' env)
-- Fails immediately on error, makes it possible to try other possibilities -- Fails immediately on error, makes it possible to try other possibilities
renameIdentTerm' :: Status -> Term -> Check Term renameIdentTerm' :: Status -> Term -> Check Term
renameIdentTerm' env@(act,imps) t0 = renameIdentTerm' env@(act,imps) t0 =
case t0 of case t0 of
Vr c -> ident predefAbs c Vr c -> ident predefAbs c
Cn c -> ident (\_ s -> checkError s) c Cn c -> ident (\_ s -> checkError s) c
@@ -85,8 +85,8 @@ renameIdentTerm' env@(act,imps) t0 =
_ -> return t0 _ -> return t0
where where
opens = [st | (OSimple _,st) <- imps] opens = [st | (OSimple _,st) <- imps]
qualifs = [(m, st) | (OQualif m _, st) <- imps] ++ qualifs = [(m, st) | (OQualif m _, st) <- imps] ++
[(m, st) | (OQualif _ m, st) <- imps] ++ [(m, st) | (OQualif _ m, st) <- imps] ++
[(m, st) | (OSimple m, st) <- imps] -- qualif is always possible [(m, st) | (OSimple m, st) <- imps] -- qualif is always possible
-- this facility is mainly for BWC with GF1: you need not import PredefAbs -- this facility is mainly for BWC with GF1: you need not import PredefAbs
@@ -94,7 +94,7 @@ renameIdentTerm' env@(act,imps) t0 =
| isPredefCat c = return (Q (cPredefAbs,c)) | isPredefCat c = return (Q (cPredefAbs,c))
| otherwise = checkError s | otherwise = checkError s
ident alt c = ident alt c =
case Map.lookup c act of case Map.lookup c act of
Just f -> return (f c) Just f -> return (f c)
_ -> case mapMaybe (Map.lookup c) opens of _ -> case mapMaybe (Map.lookup c) opens of
@@ -157,7 +157,7 @@ modInfo2status (o,mo) = (o,tree2status o (jments mo))
self2status :: ModuleName -> ModuleInfo -> StatusMap self2status :: ModuleName -> ModuleInfo -> StatusMap
self2status c m = Map.mapWithKey (info2status (Just c)) (jments m) self2status c m = Map.mapWithKey (info2status (Just c)) (jments m)
renameInfo :: FilePath -> Status -> Module -> Ident -> Info -> Check Info renameInfo :: FilePath -> Status -> Module -> Ident -> Info -> Check Info
renameInfo cwd status (m,mi) i info = renameInfo cwd status (m,mi) i info =
case info of case info of
@@ -208,7 +208,7 @@ renameTerm env vars = ren vars where
Abs b x t -> liftM (Abs b x) (ren (x:vs) t) Abs b x t -> liftM (Abs b x) (ren (x:vs) t)
Prod bt x a b -> liftM2 (Prod bt x) (ren vs a) (ren (x:vs) b) Prod bt x a b -> liftM2 (Prod bt x) (ren vs a) (ren (x:vs) b)
Typed a b -> liftM2 Typed (ren vs a) (ren vs b) Typed a b -> liftM2 Typed (ren vs a) (ren vs b)
Vr x Vr x
| elem x vs -> return trm | elem x vs -> return trm
| otherwise -> renid trm | otherwise -> renid trm
Cn _ -> renid trm Cn _ -> renid trm
@@ -219,7 +219,7 @@ renameTerm env vars = ren vars where
i' <- case i of i' <- case i of
TTyped ty -> liftM TTyped $ ren vs ty -- the only annotation in source TTyped ty -> liftM TTyped $ ren vs ty -- the only annotation in source
_ -> return i _ -> return i
liftM (T i') $ mapM (renCase vs) cs liftM (T i') $ mapM (renCase vs) cs
Let (x,(m,a)) b -> do Let (x,(m,a)) b -> do
m' <- case m of m' <- case m of
@@ -229,7 +229,7 @@ renameTerm env vars = ren vars where
b' <- ren (x:vs) b b' <- ren (x:vs) b
return $ Let (x,(m',a')) b' return $ Let (x,(m',a')) b'
P t@(Vr r) l -- Here we have $r.l$ and this is ambiguous it could be either P t@(Vr r) l -- Here we have $r.l$ and this is ambiguous it could be either
-- record projection from variable or constant $r$ or qualified expression with module $r$ -- record projection from variable or constant $r$ or qualified expression with module $r$
| elem r vs -> return trm -- try var proj first .. | elem r vs -> return trm -- try var proj first ..
| otherwise -> checks [ renid' (Q (MN r,label2ident l)) -- .. and qualified expression second. | otherwise -> checks [ renid' (Q (MN r,label2ident l)) -- .. and qualified expression second.
@@ -331,7 +331,7 @@ renamePattern env patt =
renameContext :: Status -> Context -> Check Context renameContext :: Status -> Context -> Check Context
renameContext b = renc [] where renameContext b = renc [] where
renc vs cont = case cont of renc vs cont = case cont of
(bt,x,t) : xts (bt,x,t) : xts
| isWildIdent x -> do | isWildIdent x -> do
t' <- ren vs t t' <- ren vs t
xts' <- renc vs xts xts' <- renc vs xts

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/09/15 16:22:02 $ -- > CVS $Date: 2005/09/15 16:22:02 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.16 $ -- > CVS $Revision: 1.16 $
-- --
@@ -13,11 +13,11 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Compile.TypeCheck.Abstract (-- * top-level type checking functions; TC should not be called directly. module GF.Compile.TypeCheck.Abstract (-- * top-level type checking functions; TC should not be called directly.
checkContext, checkContext,
checkTyp, checkTyp,
checkDef, checkDef,
checkConstrs, checkConstrs,
) where ) where
import GF.Data.Operations import GF.Data.Operations
@@ -33,8 +33,8 @@ import GF.Text.Pretty
--import Control.Monad (foldM, liftM, liftM2) --import Control.Monad (foldM, liftM, liftM2)
-- | invariant way of creating TCEnv from context -- | invariant way of creating TCEnv from context
initTCEnv gamma = initTCEnv gamma =
(length gamma,[(x,VGen i x) | ((x,_),i) <- zip gamma [0..]], gamma) (length gamma,[(x,VGen i x) | ((x,_),i) <- zip gamma [0..]], gamma)
-- interface to TC type checker -- interface to TC type checker

View File

@@ -69,7 +69,6 @@ computeLType gr g0 t = comp (reverse [(b,x, Vr x) | (b,x,_) <- g0] ++ g0) t
lockRecType c t' ---- locking to be removed AR 20/6/2009 lockRecType c t' ---- locking to be removed AR 20/6/2009
_ | ty == typeTok -> return typeStr _ | ty == typeTok -> return typeStr
_ | isPredefConstant ty -> return ty
_ -> composOp (comp g) ty _ -> composOp (comp g) ty

View File

@@ -396,7 +396,7 @@ tcRecTypeFields ge scope ((l,ty):rs) mb_ty = do
return ((l,ty):rs,mb_ty) return ((l,ty):rs,mb_ty)
-- | Invariant: if the third argument is (Just rho), -- | Invariant: if the third argument is (Just rho),
-- then rho is in weak-prenex form -- then rho is in weak-prenex form
instSigma :: GlobalEnv -> Scope -> Term -> Sigma -> Maybe Rho -> TcM (Term, Rho) instSigma :: GlobalEnv -> Scope -> Term -> Sigma -> Maybe Rho -> TcM (Term, Rho)
instSigma ge scope t ty1 Nothing = return (t,ty1) -- INST1 instSigma ge scope t ty1 Nothing = return (t,ty1) -- INST1
instSigma ge scope t ty1 (Just ty2) = do -- INST2 instSigma ge scope t ty1 (Just ty2) = do -- INST2
@@ -568,9 +568,9 @@ unifyVar ge scope i env vs ty2 = do -- Check whether i is bound
Bound ty1 -> do v <- liftErr (eval ge env ty1) Bound ty1 -> do v <- liftErr (eval ge env ty1)
unify ge scope (vapply (geLoc ge) v vs) ty2 unify ge scope (vapply (geLoc ge) v vs) ty2
Unbound scope' _ -> case value2term (geLoc ge) (scopeVars scope') ty2 of Unbound scope' _ -> case value2term (geLoc ge) (scopeVars scope') ty2 of
Left i -> let (v,_) = reverse scope !! i -- Left i -> let (v,_) = reverse scope !! i
in tcError ("Variable" <+> pp v <+> "has escaped") -- in tcError ("Variable" <+> pp v <+> "has escaped")
Right ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)] ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)]
if i `elem` ms2 if i `elem` ms2
then tcError ("Occurs check for" <+> ppMeta i <+> "in:" $$ then tcError ("Occurs check for" <+> ppMeta i <+> "in:" $$
nest 2 (ppTerm Unqualified 0 ty2')) nest 2 (ppTerm Unqualified 0 ty2'))
@@ -631,8 +631,8 @@ allBinders = [ identS [x] | x <- ['a'..'z'] ] ++
type Scope = [(Ident,Value)] type Scope = [(Ident,Value)]
type Sigma = Value type Sigma = Value
type Rho = Value -- No top-level ForAll type Rho = Value -- No top-level ForAll
type Tau = Value -- No ForAlls anywhere type Tau = Value -- No ForAlls anywhere
data MetaValue data MetaValue
= Unbound Scope Sigma = Unbound Scope Sigma
@@ -644,7 +644,7 @@ data TcResult a
newtype TcM a = TcM {unTcM :: MetaStore -> [Message] -> TcResult a} newtype TcM a = TcM {unTcM :: MetaStore -> [Message] -> TcResult a}
instance Monad TcM where instance Monad TcM where
return x = TcM (\ms msgs -> TcOk x ms msgs) return = pure
f >>= g = TcM (\ms msgs -> case unTcM f ms msgs of f >>= g = TcM (\ms msgs -> case unTcM f ms msgs of
TcOk x ms msgs -> unTcM (g x) ms msgs TcOk x ms msgs -> unTcM (g x) ms msgs
TcFail msgs -> TcFail msgs) TcFail msgs -> TcFail msgs)
@@ -659,7 +659,7 @@ instance Fail.MonadFail TcM where
instance Applicative TcM where instance Applicative TcM where
pure = return pure x = TcM (\ms msgs -> TcOk x ms msgs)
(<*>) = ap (<*>) = ap
instance Functor TcM where instance Functor TcM where
@@ -724,8 +724,8 @@ getMetaVars loc sc_tys = do
go (Vr tv) acc = acc go (Vr tv) acc = acc
go (App x y) acc = go x (go y acc) go (App x y) acc = go x (go y acc)
go (Meta i) acc go (Meta i) acc
| i `elem` acc = acc | i `elem` acc = acc
| otherwise = i : acc | otherwise = i : acc
go (Q _) acc = acc go (Q _) acc = acc
go (QC _) acc = acc go (QC _) acc = acc
go (Sort _) acc = acc go (Sort _) acc = acc
@@ -742,9 +742,9 @@ getFreeVars loc sc_tys = do
return (foldr (go []) [] tys) return (foldr (go []) [] tys)
where where
go bound (Vr tv) acc go bound (Vr tv) acc
| tv `elem` bound = acc | tv `elem` bound = acc
| tv `elem` acc = acc | tv `elem` acc = acc
| otherwise = tv : acc | otherwise = tv : acc
go bound (App x y) acc = go bound x (go bound y acc) go bound (App x y) acc = go bound x (go bound y acc)
go bound (Meta _) acc = acc go bound (Meta _) acc = acc
go bound (Q _) acc = acc go bound (Q _) acc = acc
@@ -765,9 +765,9 @@ zonkTerm (Meta i) = do
zonkTerm t = composOp zonkTerm t zonkTerm t = composOp zonkTerm t
tc_value2term loc xs v = tc_value2term loc xs v =
case value2term loc xs v of return $ value2term loc xs v
Left i -> tcError ("Variable #" <+> pp i <+> "has escaped") -- Old value2term error message:
Right t -> return t -- Left i -> tcError ("Variable #" <+> pp i <+> "has escaped")

View File

@@ -5,21 +5,22 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/10/02 20:50:19 $ -- > CVS $Date: 2005/10/02 20:50:19 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.11 $ -- > CVS $Revision: 1.11 $
-- --
-- Thierry Coquand's type checking algorithm that creates a trace -- Thierry Coquand's type checking algorithm that creates a trace
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Compile.TypeCheck.TC (AExp(..), module GF.Compile.TypeCheck.TC (
Theory, AExp(..),
checkExp, Theory,
inferExp, checkExp,
checkBranch, inferExp,
eqVal, checkBranch,
whnf eqVal,
) where whnf
) where
import GF.Data.Operations import GF.Data.Operations
import GF.Grammar import GF.Grammar
@@ -31,17 +32,17 @@ import Data.Maybe
import GF.Text.Pretty import GF.Text.Pretty
data AExp = data AExp =
AVr Ident Val AVr Ident Val
| ACn QIdent Val | ACn QIdent Val
| AType | AType
| AInt Int | AInt Int
| AFloat Double | AFloat Double
| AStr String | AStr String
| AMeta MetaId Val | AMeta MetaId Val
| ALet (Ident,(Val,AExp)) AExp | ALet (Ident,(Val,AExp)) AExp
| AApp AExp AExp Val | AApp AExp AExp Val
| AAbs Ident Val AExp | AAbs Ident Val AExp
| AProd Ident AExp AExp | AProd Ident AExp AExp
-- -- | AEqs [([Exp],AExp)] --- not used -- -- | AEqs [([Exp],AExp)] --- not used
| ARecType [ALabelling] | ARecType [ALabelling]
| AR [AAssign] | AR [AAssign]
@@ -50,7 +51,7 @@ data AExp =
| AData Val | AData Val
deriving (Eq,Show) deriving (Eq,Show)
type ALabelling = (Label, AExp) type ALabelling = (Label, AExp)
type AAssign = (Label, (Val, AExp)) type AAssign = (Label, (Val, AExp))
type Theory = QIdent -> Err Val type Theory = QIdent -> Err Val
@@ -71,7 +72,7 @@ whnf :: Val -> Err Val
whnf v = ---- errIn ("whnf" +++ prt v) $ ---- debug whnf v = ---- errIn ("whnf" +++ prt v) $ ---- debug
case v of case v of
VApp u w -> do VApp u w -> do
u' <- whnf u u' <- whnf u
w' <- whnf w w' <- whnf w
app u' w' app u' w'
VClos env e -> eval env e VClos env e -> eval env e
@@ -81,9 +82,9 @@ app :: Val -> Val -> Err Val
app u v = case u of app u v = case u of
VClos env (Abs _ x e) -> eval ((x,v):env) e VClos env (Abs _ x e) -> eval ((x,v):env) e
_ -> return $ VApp u v _ -> return $ VApp u v
eval :: Env -> Term -> Err Val eval :: Env -> Term -> Err Val
eval env e = ---- errIn ("eval" +++ prt e +++ "in" +++ prEnv env) $ eval env e = ---- errIn ("eval" +++ prt e +++ "in" +++ prEnv env) $
case e of case e of
Vr x -> lookupVar env x Vr x -> lookupVar env x
Q c -> return $ VCn c Q c -> return $ VCn c
@@ -95,23 +96,23 @@ eval env e = ---- errIn ("eval" +++ prt e +++ "in" +++ prEnv env) $
_ -> return $ VClos env e _ -> return $ VClos env e
eqVal :: Int -> Val -> Val -> Err [(Val,Val)] eqVal :: Int -> Val -> Val -> Err [(Val,Val)]
eqVal k u1 u2 = ---- errIn (prt u1 +++ "<>" +++ prBracket (show k) +++ prt u2) $ eqVal k u1 u2 = ---- errIn (prt u1 +++ "<>" +++ prBracket (show k) +++ prt u2) $
do do
w1 <- whnf u1 w1 <- whnf u1
w2 <- whnf u2 w2 <- whnf u2
let v = VGen k let v = VGen k
case (w1,w2) of case (w1,w2) of
(VApp f1 a1, VApp f2 a2) -> liftM2 (++) (eqVal k f1 f2) (eqVal k a1 a2) (VApp f1 a1, VApp f2 a2) -> liftM2 (++) (eqVal k f1 f2) (eqVal k a1 a2)
(VClos env1 (Abs _ x1 e1), VClos env2 (Abs _ x2 e2)) -> (VClos env1 (Abs _ x1 e1), VClos env2 (Abs _ x2 e2)) ->
eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2) eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2)
(VClos env1 (Prod _ x1 a1 e1), VClos env2 (Prod _ x2 a2 e2)) -> (VClos env1 (Prod _ x1 a1 e1), VClos env2 (Prod _ x2 a2 e2)) ->
liftM2 (++) liftM2 (++)
(eqVal k (VClos env1 a1) (VClos env2 a2)) (eqVal k (VClos env1 a1) (VClos env2 a2))
(eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2)) (eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2))
(VGen i _, VGen j _) -> return [(w1,w2) | i /= j] (VGen i _, VGen j _) -> return [(w1,w2) | i /= j]
(VCn (_, i), VCn (_,j)) -> return [(w1,w2) | i /= j] (VCn (_, i), VCn (_,j)) -> return [(w1,w2) | i /= j]
--- thus ignore qualifications; valid because inheritance cannot --- thus ignore qualifications; valid because inheritance cannot
--- be qualified. Simplifies annotation. AR 17/3/2005 --- be qualified. Simplifies annotation. AR 17/3/2005
_ -> return [(w1,w2) | w1 /= w2] _ -> return [(w1,w2) | w1 /= w2]
-- invariant: constraints are in whnf -- invariant: constraints are in whnf
@@ -127,10 +128,10 @@ checkExp th tenv@(k,rho,gamma) e ty = do
Abs _ x t -> case typ of Abs _ x t -> case typ of
VClos env (Prod _ y a b) -> do VClos env (Prod _ y a b) -> do
a' <- whnf $ VClos env a --- a' <- whnf $ VClos env a ---
(t',cs) <- checkExp th (t',cs) <- checkExp th
(k+1,(x,v x):rho, (x,a'):gamma) t (VClos ((y,v x):env) b) (k+1,(x,v x):rho, (x,a'):gamma) t (VClos ((y,v x):env) b)
return (AAbs x a' t', cs) return (AAbs x a' t', cs)
_ -> Bad (render ("function type expected for" <+> ppTerm Unqualified 0 e <+> "instead of" <+> ppValue Unqualified 0 typ)) _ -> Bad (render ("function type expected for" <+> ppTerm Unqualified 0 e <+> "instead of" <+> ppValue Unqualified 0 typ))
Let (x, (mb_typ, e1)) e2 -> do Let (x, (mb_typ, e1)) e2 -> do
@@ -150,7 +151,7 @@ checkExp th tenv@(k,rho,gamma) e ty = do
(b',csb) <- checkType th (k+1, (x,v x):rho, (x,VClos rho a):gamma) b (b',csb) <- checkType th (k+1, (x,v x):rho, (x,VClos rho a):gamma) b
return (AProd x a' b', csa ++ csb) return (AProd x a' b', csa ++ csb)
R xs -> R xs ->
case typ of case typ of
VRecType ys -> do case [l | (l,_) <- ys, isNothing (lookup l xs)] of VRecType ys -> do case [l | (l,_) <- ys, isNothing (lookup l xs)] of
[] -> return () [] -> return ()
@@ -174,7 +175,7 @@ checkInferExp th tenv@(k,_,_) e typ = do
(e',w,cs1) <- inferExp th tenv e (e',w,cs1) <- inferExp th tenv e
cs2 <- eqVal k w typ cs2 <- eqVal k w typ
return (e',cs1 ++ cs2) return (e',cs1 ++ cs2)
inferExp :: Theory -> TCEnv -> Term -> Err (AExp, Val, [(Val,Val)]) inferExp :: Theory -> TCEnv -> Term -> Err (AExp, Val, [(Val,Val)])
inferExp th tenv@(k,rho,gamma) e = case e of inferExp th tenv@(k,rho,gamma) e = case e of
Vr x -> mkAnnot (AVr x) $ noConstr $ lookupVar gamma x Vr x -> mkAnnot (AVr x) $ noConstr $ lookupVar gamma x
@@ -200,13 +201,13 @@ inferExp th tenv@(k,rho,gamma) e = case e of
(e2,val2,cs2) <- inferExp th (k,rho,(x,val1):gamma) e2 (e2,val2,cs2) <- inferExp th (k,rho,(x,val1):gamma) e2
return (ALet (x,(val1,e1)) e2, val2, cs1++cs2) return (ALet (x,(val1,e1)) e2, val2, cs1++cs2)
App f t -> do App f t -> do
(f',w,csf) <- inferExp th tenv f (f',w,csf) <- inferExp th tenv f
typ <- whnf w typ <- whnf w
case typ of case typ of
VClos env (Prod _ x a b) -> do VClos env (Prod _ x a b) -> do
(a',csa) <- checkExp th tenv t (VClos env a) (a',csa) <- checkExp th tenv t (VClos env a)
b' <- whnf $ VClos ((x,VClos rho t):env) b b' <- whnf $ VClos ((x,VClos rho t):env) b
return $ (AApp f' a' b', b', csf ++ csa) return $ (AApp f' a' b', b', csf ++ csa)
_ -> Bad (render ("Prod expected for function" <+> ppTerm Unqualified 0 f <+> "instead of" <+> ppValue Unqualified 0 typ)) _ -> Bad (render ("Prod expected for function" <+> ppTerm Unqualified 0 f <+> "instead of" <+> ppValue Unqualified 0 typ))
_ -> Bad (render ("cannot infer type of expression" <+> ppTerm Unqualified 0 e)) _ -> Bad (render ("cannot infer type of expression" <+> ppTerm Unqualified 0 e))
@@ -232,9 +233,9 @@ checkAssign th tenv@(k,rho,gamma) typs (lbl,(Nothing,exp)) = do
return ((lbl,(val,aexp)),cs) return ((lbl,(val,aexp)),cs)
checkBranch :: Theory -> TCEnv -> Equation -> Val -> Err (([Term],AExp),[(Val,Val)]) checkBranch :: Theory -> TCEnv -> Equation -> Val -> Err (([Term],AExp),[(Val,Val)])
checkBranch th tenv b@(ps,t) ty = errIn ("branch" +++ show b) $ checkBranch th tenv b@(ps,t) ty = errIn ("branch" +++ show b) $
chB tenv' ps' ty chB tenv' ps' ty
where where
(ps',_,rho2,k') = ps2ts k ps (ps',_,rho2,k') = ps2ts k ps
tenv' = (k, rho2++rho, gamma) ---- k' ? tenv' = (k, rho2++rho, gamma) ---- k' ?
@@ -245,11 +246,11 @@ checkBranch th tenv b@(ps,t) ty = errIn ("branch" +++ show b) $
typ <- whnf ty typ <- whnf ty
case typ of case typ of
VClos env (Prod _ y a b) -> do VClos env (Prod _ y a b) -> do
a' <- whnf $ VClos env a a' <- whnf $ VClos env a
(p', sigma, binds, cs1) <- checkP tenv p y a' (p', sigma, binds, cs1) <- checkP tenv p y a'
let tenv' = (length binds, sigma ++ rho, binds ++ gamma) let tenv' = (length binds, sigma ++ rho, binds ++ gamma)
((ps',exp),cs2) <- chB tenv' ps2 (VClos ((y,p'):env) b) ((ps',exp),cs2) <- chB tenv' ps2 (VClos ((y,p'):env) b)
return ((p:ps',exp), cs1 ++ cs2) -- don't change the patt return ((p:ps',exp), cs1 ++ cs2) -- don't change the patt
_ -> Bad (render ("Product expected for definiens" <+> ppTerm Unqualified 0 t <+> "instead of" <+> ppValue Unqualified 0 typ)) _ -> Bad (render ("Product expected for definiens" <+> ppTerm Unqualified 0 t <+> "instead of" <+> ppValue Unqualified 0 typ))
[] -> do [] -> do
(e,cs) <- checkExp th tenv t ty (e,cs) <- checkExp th tenv t ty
@@ -259,15 +260,15 @@ checkBranch th tenv b@(ps,t) ty = errIn ("branch" +++ show b) $
let sigma = [(x, VGen i x) | ((x,_),i) <- zip delta [k..]] let sigma = [(x, VGen i x) | ((x,_),i) <- zip delta [k..]]
return (VClos sigma t, sigma, delta, cs) return (VClos sigma t, sigma, delta, cs)
ps2ts k = foldr p2t ([],0,[],k) ps2ts k = foldr p2t ([],0,[],k)
p2t p (ps,i,g,k) = case p of p2t p (ps,i,g,k) = case p of
PW -> (Meta i : ps, i+1,g,k) PW -> (Meta i : ps, i+1,g,k)
PV x -> (Vr x : ps, i, upd x k g,k+1) PV x -> (Vr x : ps, i, upd x k g,k+1)
PAs x p -> p2t p (ps,i,g,k) PAs x p -> p2t p (ps,i,g,k)
PString s -> (K s : ps, i, g, k) PString s -> (K s : ps, i, g, k)
PInt n -> (EInt n : ps, i, g, k) PInt n -> (EInt n : ps, i, g, k)
PFloat n -> (EFloat n : ps, i, g, k) PFloat n -> (EFloat n : ps, i, g, k)
PP c xs -> (mkApp (Q c) xss : ps, j, g',k') PP c xs -> (mkApp (Q c) xss : ps, j, g',k')
where (xss,j,g',k') = foldr p2t ([],i,g,k) xs where (xss,j,g',k') = foldr p2t ([],i,g,k) xs
PImplArg p -> p2t p (ps,i,g,k) PImplArg p -> p2t p (ps,i,g,k)
PTilde t -> (t : ps, i, g, k) PTilde t -> (t : ps, i, g, k)
@@ -307,8 +308,8 @@ checkPatt th tenv exp val = do
case typ of case typ of
VClos env (Prod _ x a b) -> do VClos env (Prod _ x a b) -> do
(a',_,csa) <- checkExpP tenv t (VClos env a) (a',_,csa) <- checkExpP tenv t (VClos env a)
b' <- whnf $ VClos ((x,VClos rho t):env) b b' <- whnf $ VClos ((x,VClos rho t):env) b
return $ (AApp f' a' b', b', csf ++ csa) return $ (AApp f' a' b', b', csf ++ csa)
_ -> Bad (render ("Prod expected for function" <+> ppTerm Unqualified 0 f <+> "instead of" <+> ppValue Unqualified 0 typ)) _ -> Bad (render ("Prod expected for function" <+> ppTerm Unqualified 0 f <+> "instead of" <+> ppValue Unqualified 0 typ))
_ -> Bad (render ("cannot typecheck pattern" <+> ppTerm Unqualified 0 exp)) _ -> Bad (render ("cannot typecheck pattern" <+> ppTerm Unqualified 0 exp))
@@ -321,4 +322,3 @@ mkAnnot :: (Val -> AExp) -> Err (Val,[(Val,Val)]) -> Err (AExp,Val,[(Val,Val)])
mkAnnot a ti = do mkAnnot a ti = do
(v,cs) <- ti (v,cs) <- ti
return (a v, v, cs) return (a v, v, cs)

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/05/30 18:39:44 $ -- > CVS $Date: 2005/05/30 18:39:44 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.8 $ -- > CVS $Revision: 1.8 $
-- --
@@ -34,14 +34,14 @@ buildAnyTree :: Fail.MonadFail m => ModuleName -> [(Ident,Info)] -> m (Map.Map I
buildAnyTree m = go Map.empty buildAnyTree m = go Map.empty
where where
go map [] = return map go map [] = return map
go map ((c,j):is) = do go map ((c,j):is) =
case Map.lookup c map of case Map.lookup c map of
Just i -> case unifyAnyInfo m i j of Just i -> case unifyAnyInfo m i j of
Ok k -> go (Map.insert c k map) is Ok k -> go (Map.insert c k map) is
Bad _ -> fail $ render ("conflicting information in module"<+>m $$ Bad _ -> fail $ render ("conflicting information in module"<+>m $$
nest 4 (ppJudgement Qualified (c,i)) $$ nest 4 (ppJudgement Qualified (c,i)) $$
"and" $+$ "and" $+$
nest 4 (ppJudgement Qualified (c,j))) nest 4 (ppJudgement Qualified (c,j)))
Nothing -> go (Map.insert c j map) is Nothing -> go (Map.insert c j map) is
extendModule :: FilePath -> SourceGrammar -> SourceModule -> Check SourceModule extendModule :: FilePath -> SourceGrammar -> SourceModule -> Check SourceModule
@@ -51,14 +51,14 @@ extendModule cwd gr (name,m)
---- Should be replaced by real control. AR 4/2/2005 ---- Should be replaced by real control. AR 4/2/2005
| mstatus m == MSIncomplete && isModCnc m = return (name,m) | mstatus m == MSIncomplete && isModCnc m = return (name,m)
| otherwise = checkInModule cwd m NoLoc empty $ do | otherwise = checkInModule cwd m NoLoc empty $ do
m' <- foldM extOne m (mextend m) m' <- foldM extOne m (mextend m)
return (name,m') return (name,m')
where where
extOne mo (n,cond) = do extOne mo (n,cond) = do
m0 <- lookupModule gr n m0 <- lookupModule gr n
-- test that the module types match, and find out if the old is complete -- test that the module types match, and find out if the old is complete
unless (sameMType (mtype m) (mtype mo)) unless (sameMType (mtype m) (mtype mo))
(checkError ("illegal extension type to module" <+> name)) (checkError ("illegal extension type to module" <+> name))
let isCompl = isCompleteModule m0 let isCompl = isCompleteModule m0
@@ -67,7 +67,7 @@ extendModule cwd gr (name,m)
js1 <- extendMod gr isCompl ((n,m0), isInherited cond) name (jments mo) js1 <- extendMod gr isCompl ((n,m0), isInherited cond) name (jments mo)
-- if incomplete, throw away extension information -- if incomplete, throw away extension information
return $ return $
if isCompl if isCompl
then mo {jments = js1} then mo {jments = js1}
else mo {mextend= filter ((/=n) . fst) (mextend mo) else mo {mextend= filter ((/=n) . fst) (mextend mo)
@@ -75,7 +75,7 @@ extendModule cwd gr (name,m)
,jments = js1 ,jments = js1
} }
-- | rebuilding instance + interface, and "with" modules, prior to renaming. -- | rebuilding instance + interface, and "with" modules, prior to renaming.
-- AR 24/10/2003 -- AR 24/10/2003
rebuildModule :: FilePath -> SourceGrammar -> SourceModule -> Check SourceModule rebuildModule :: FilePath -> SourceGrammar -> SourceModule -> Check SourceModule
rebuildModule cwd gr mo@(i,mi@(ModInfo mt stat fs_ me mw ops_ med_ msrc_ env_ js_)) = rebuildModule cwd gr mo@(i,mi@(ModInfo mt stat fs_ me mw ops_ med_ msrc_ env_ js_)) =
@@ -88,8 +88,8 @@ rebuildModule cwd gr mo@(i,mi@(ModInfo mt stat fs_ me mw ops_ med_ msrc_ env_ js
-- add the information given in interface into an instance module -- add the information given in interface into an instance module
Nothing -> do Nothing -> do
unless (null is || mstatus mi == MSIncomplete) unless (null is || mstatus mi == MSIncomplete)
(checkError ("module" <+> i <+> (checkError ("module" <+> i <+>
"has open interfaces and must therefore be declared incomplete")) "has open interfaces and must therefore be declared incomplete"))
case mt of case mt of
MTInstance (i0,mincl) -> do MTInstance (i0,mincl) -> do
@@ -113,7 +113,7 @@ rebuildModule cwd gr mo@(i,mi@(ModInfo mt stat fs_ me mw ops_ med_ msrc_ env_ js
let stat' = if all (flip elem infs) is let stat' = if all (flip elem infs) is
then MSComplete then MSComplete
else MSIncomplete else MSIncomplete
unless (stat' == MSComplete || stat == MSIncomplete) unless (stat' == MSComplete || stat == MSIncomplete)
(checkError ("module" <+> i <+> "remains incomplete")) (checkError ("module" <+> i <+> "remains incomplete"))
ModInfo mt0 _ fs me' _ ops0 _ fpath _ js <- lookupModule gr ext ModInfo mt0 _ fs me' _ ops0 _ fpath _ js <- lookupModule gr ext
let ops1 = nub $ let ops1 = nub $
@@ -141,24 +141,24 @@ rebuildModule cwd gr mo@(i,mi@(ModInfo mt stat fs_ me mw ops_ med_ msrc_ env_ js
extendMod :: Grammar -> extendMod :: Grammar ->
Bool -> (Module,Ident -> Bool) -> ModuleName -> Bool -> (Module,Ident -> Bool) -> ModuleName ->
Map.Map Ident Info -> Check (Map.Map Ident Info) Map.Map Ident Info -> Check (Map.Map Ident Info)
extendMod gr isCompl ((name,mi),cond) base new = foldM try new $ Map.toList (jments mi) extendMod gr isCompl ((name,mi),cond) base new = foldM try new $ Map.toList (jments mi)
where where
try new (c,i0) try new (c,i0)
| not (cond c) = return new | not (cond c) = return new
| otherwise = case Map.lookup c new of | otherwise = case Map.lookup c new of
Just j -> case unifyAnyInfo name i j of Just j -> case unifyAnyInfo name i j of
Ok k -> return $ Map.insert c k new Ok k -> return $ Map.insert c k new
Bad _ -> do (base,j) <- case j of Bad _ -> do (base,j) <- case j of
AnyInd _ m -> lookupOrigInfo gr (m,c) AnyInd _ m -> lookupOrigInfo gr (m,c)
_ -> return (base,j) _ -> return (base,j)
(name,i) <- case i of (name,i) <- case i of
AnyInd _ m -> lookupOrigInfo gr (m,c) AnyInd _ m -> lookupOrigInfo gr (m,c)
_ -> return (name,i) _ -> return (name,i)
checkError ("cannot unify the information" $$ checkError ("cannot unify the information" $$
nest 4 (ppJudgement Qualified (c,i)) $$ nest 4 (ppJudgement Qualified (c,i)) $$
"in module" <+> name <+> "with" $$ "in module" <+> name <+> "with" $$
nest 4 (ppJudgement Qualified (c,j)) $$ nest 4 (ppJudgement Qualified (c,j)) $$
"in module" <+> base) "in module" <+> base)
Nothing-> if isCompl Nothing-> if isCompl
then return $ Map.insert c (indirInfo name i) new then return $ Map.insert c (indirInfo name i) new
else return $ Map.insert c i new else return $ Map.insert c i new
@@ -166,11 +166,11 @@ extendMod gr isCompl ((name,mi),cond) base new = foldM try new $ Map.toList (jme
i = globalizeLoc (msrc mi) i0 i = globalizeLoc (msrc mi) i0
indirInfo :: ModuleName -> Info -> Info indirInfo :: ModuleName -> Info -> Info
indirInfo n info = AnyInd b n' where indirInfo n info = AnyInd b n' where
(b,n') = case info of (b,n') = case info of
ResValue _ -> (True,n) ResValue _ -> (True,n)
ResParam _ _ -> (True,n) ResParam _ _ -> (True,n)
AbsFun _ _ Nothing _ -> (True,n) AbsFun _ _ Nothing _ -> (True,n)
AnyInd b k -> (b,k) AnyInd b k -> (b,k)
_ -> (False,n) ---- canonical in Abs _ -> (False,n) ---- canonical in Abs
@@ -194,24 +194,24 @@ globalizeLoc fpath i =
unifyAnyInfo :: ModuleName -> Info -> Info -> Err Info unifyAnyInfo :: ModuleName -> Info -> Info -> Err Info
unifyAnyInfo m i j = case (i,j) of unifyAnyInfo m i j = case (i,j) of
(AbsCat mc1, AbsCat mc2) -> (AbsCat mc1, AbsCat mc2) ->
liftM AbsCat (unifyMaybeL mc1 mc2) liftM AbsCat (unifyMaybeL mc1 mc2)
(AbsFun mt1 ma1 md1 moper1, AbsFun mt2 ma2 md2 moper2) -> (AbsFun mt1 ma1 md1 moper1, AbsFun mt2 ma2 md2 moper2) ->
liftM4 AbsFun (unifyMaybeL mt1 mt2) (unifAbsArrity ma1 ma2) (unifAbsDefs md1 md2) (unifyMaybe moper1 moper2) -- adding defs liftM4 AbsFun (unifyMaybeL mt1 mt2) (unifAbsArrity ma1 ma2) (unifAbsDefs md1 md2) (unifyMaybe moper1 moper2) -- adding defs
(ResParam mt1 mv1, ResParam mt2 mv2) -> (ResParam mt1 mv1, ResParam mt2 mv2) ->
liftM2 ResParam (unifyMaybeL mt1 mt2) (unifyMaybe mv1 mv2) liftM2 ResParam (unifyMaybeL mt1 mt2) (unifyMaybe mv1 mv2)
(ResValue (L l1 t1), ResValue (L l2 t2)) (ResValue (L l1 t1), ResValue (L l2 t2))
| t1==t2 -> return (ResValue (L l1 t1)) | t1==t2 -> return (ResValue (L l1 t1))
| otherwise -> fail "" | otherwise -> fail ""
(_, ResOverload ms t) | elem m ms -> (_, ResOverload ms t) | elem m ms ->
return $ ResOverload ms t return $ ResOverload ms t
(ResOper mt1 m1, ResOper mt2 m2) -> (ResOper mt1 m1, ResOper mt2 m2) ->
liftM2 ResOper (unifyMaybeL mt1 mt2) (unifyMaybeL m1 m2) liftM2 ResOper (unifyMaybeL mt1 mt2) (unifyMaybeL m1 m2)
(CncCat mc1 md1 mr1 mp1 mpmcfg1, CncCat mc2 md2 mr2 mp2 mpmcfg2) -> (CncCat mc1 md1 mr1 mp1 mpmcfg1, CncCat mc2 md2 mr2 mp2 mpmcfg2) ->
liftM5 CncCat (unifyMaybeL mc1 mc2) (unifyMaybeL md1 md2) (unifyMaybeL mr1 mr2) (unifyMaybeL mp1 mp2) (unifyMaybe mpmcfg1 mpmcfg2) liftM5 CncCat (unifyMaybeL mc1 mc2) (unifyMaybeL md1 md2) (unifyMaybeL mr1 mr2) (unifyMaybeL mp1 mp2) (unifyMaybe mpmcfg1 mpmcfg2)
(CncFun m mt1 md1 mpmcfg1, CncFun _ mt2 md2 mpmcfg2) -> (CncFun m mt1 md1 mpmcfg1, CncFun _ mt2 md2 mpmcfg2) ->
liftM3 (CncFun m) (unifyMaybeL mt1 mt2) (unifyMaybeL md1 md2) (unifyMaybe mpmcfg1 mpmcfg2) liftM3 (CncFun m) (unifyMaybeL mt1 mt2) (unifyMaybeL md1 md2) (unifyMaybe mpmcfg1 mpmcfg2)
(AnyInd b1 m1, AnyInd b2 m2) -> do (AnyInd b1 m1, AnyInd b2 m2) -> do

View File

@@ -61,11 +61,11 @@ parallelBatchCompile jobs opts rootfiles0 =
usesPresent (_,paths) = take 1 libs==["present"] usesPresent (_,paths) = take 1 libs==["present"]
where where
libs = [p|path<-paths, libs = [p | path<-paths,
let (d,p0) = splitAt n path let (d,p0) = splitAt n path
p = dropSlash p0, p = dropSlash p0,
d==lib_dir,p `elem` all_modes] d==lib_dir, p `elem` all_modes]
n = length lib_dir n = length lib_dir
all_modes = ["alltenses","present"] all_modes = ["alltenses","present"]
@@ -175,7 +175,7 @@ batchCompile1 lib_dir (opts,filepaths) =
" from being compiled." " from being compiled."
else return (maximum ts,(cnc,gr)) else return (maximum ts,(cnc,gr))
splitEither es = ([x|Left x<-es],[y|Right y<-es]) splitEither es = ([x | Left x<-es], [y | Right y<-es])
canonical path = liftIO $ D.canonicalizePath path `catch` const (return path) canonical path = liftIO $ D.canonicalizePath path `catch` const (return path)
@@ -238,12 +238,12 @@ runCO (CO m) = do (o,x) <- m
instance Functor m => Functor (CollectOutput m) where instance Functor m => Functor (CollectOutput m) where
fmap f (CO m) = CO (fmap (fmap f) m) fmap f (CO m) = CO (fmap (fmap f) m)
instance (Functor m,Monad m) => Applicative (CollectOutput m) where instance (Functor m,Monad m) => Applicative (CollectOutput m) where
pure = return pure x = CO (return (return (),x))
(<*>) = ap (<*>) = ap
instance Monad m => Monad (CollectOutput m) where instance Monad m => Monad (CollectOutput m) where
return x = CO (return (return (),x)) return = pure
CO m >>= f = CO $ do (o1,x) <- m CO m >>= f = CO $ do (o1,x) <- m
let CO m2 = f x let CO m2 = f x
(o2,y) <- m2 (o2,y) <- m2

View File

@@ -16,18 +16,18 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
module GF.Data.BacktrackM ( module GF.Data.BacktrackM (
-- * the backtracking state monad -- * the backtracking state monad
BacktrackM, BacktrackM,
-- * monad specific utilities -- * monad specific utilities
member, member,
cut, cut,
-- * running the monad -- * running the monad
foldBM, runBM, foldBM, runBM,
foldSolutions, solutions, foldSolutions, solutions,
foldFinalStates, finalStates, foldFinalStates, finalStates,
-- * reexport the 'MonadState' class -- * reexport the 'MonadState' class
module Control.Monad.State.Class, module Control.Monad.State.Class,
) where ) where
import Data.List import Data.List
import Control.Applicative import Control.Applicative
@@ -64,13 +64,13 @@ finalStates :: BacktrackM s () -> s -> [s]
finalStates bm = map fst . runBM bm finalStates bm = map fst . runBM bm
instance Applicative (BacktrackM s) where instance Applicative (BacktrackM s) where
pure = return pure a = BM (\c s b -> c a s b)
(<*>) = ap (<*>) = ap
instance Monad (BacktrackM s) where instance Monad (BacktrackM s) where
return a = BM (\c s b -> c a s b) return = pure
BM m >>= k = BM (\c s b -> m (\a s b -> unBM (k a) c s b) s b) BM m >>= k = BM (\c s b -> m (\a s b -> unBM (k a) c s b) s b)
where unBM (BM m) = m where unBM (BM m) = m
#if !(MIN_VERSION_base(4,13,0)) #if !(MIN_VERSION_base(4,13,0))
fail = Fail.fail fail = Fail.fail

View File

@@ -34,7 +34,7 @@ fromErr :: a -> Err a -> a
fromErr a = err (const a) id fromErr a = err (const a) id
instance Monad Err where instance Monad Err where
return = Ok return = pure
Ok a >>= f = f a Ok a >>= f = f a
Bad s >>= f = Bad s Bad s >>= f = Bad s
@@ -54,7 +54,7 @@ instance Functor Err where
fmap f (Bad s) = Bad s fmap f (Bad s) = Bad s
instance Applicative Err where instance Applicative Err where
pure = return pure = Ok
(<*>) = ap (<*>) = ap
-- | added by KJ -- | added by KJ

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/11/10 16:43:44 $ -- > CVS $Date: 2005/11/10 16:43:44 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.2 $ -- > CVS $Revision: 1.2 $
-- --
@@ -34,7 +34,7 @@ import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
data Graph n a b = Graph [n] ![Node n a] ![Edge n b] data Graph n a b = Graph [n] ![Node n a] ![Edge n b]
deriving (Eq,Show) deriving (Eq,Show)
type Node n a = (n,a) type Node n a = (n,a)
type Edge n b = (n,n,b) type Edge n b = (n,n,b)
@@ -63,7 +63,7 @@ emap f (Graph c ns es) = Graph c ns [(x,y,f l) | (x,y,l) <- es]
-- | Add a node to the graph. -- | Add a node to the graph.
newNode :: a -- ^ Node label newNode :: a -- ^ Node label
-> Graph n a b -> Graph n a b
-> (Graph n a b,n) -- ^ Node graph and name of new node -> (Graph n a b,n) -- ^ Node graph and name of new node
newNode l (Graph (c:cs) ns es) = (Graph cs ((c,l):ns) es, c) newNode l (Graph (c:cs) ns es) = (Graph cs ((c,l):ns) es, c)
@@ -83,7 +83,7 @@ newEdges es g = foldl' (flip newEdge) g es
-- lazy version: -- lazy version:
-- newEdges es' (Graph c ns es) = Graph c ns (es'++es) -- newEdges es' (Graph c ns es) = Graph c ns (es'++es)
insertEdgeWith :: Eq n => insertEdgeWith :: Eq n =>
(b -> b -> b) -> Edge n b -> Graph n a b -> Graph n a b (b -> b -> b) -> Edge n b -> Graph n a b -> Graph n a b
insertEdgeWith f e@(x,y,l) (Graph c ns es) = Graph c ns (h es) insertEdgeWith f e@(x,y,l) (Graph c ns es) = Graph c ns (h es)
where h [] = [e] where h [] = [e]
@@ -97,7 +97,7 @@ removeNode n = removeNodes (Set.singleton n)
-- | Remove a set of nodes and all edges to and from those nodes. -- | Remove a set of nodes and all edges to and from those nodes.
removeNodes :: Ord n => Set n -> Graph n a b -> Graph n a b removeNodes :: Ord n => Set n -> Graph n a b -> Graph n a b
removeNodes xs (Graph c ns es) = Graph c ns' es' removeNodes xs (Graph c ns es) = Graph c ns' es'
where where
keepNode n = not (Set.member n xs) keepNode n = not (Set.member n xs)
ns' = [ x | x@(n,_) <- ns, keepNode n ] ns' = [ x | x@(n,_) <- ns, keepNode n ]
es' = [ e | e@(f,t,_) <- es, keepNode f && keepNode t ] es' = [ e | e@(f,t,_) <- es, keepNode f && keepNode t ]
@@ -105,7 +105,7 @@ removeNodes xs (Graph c ns es) = Graph c ns' es'
-- | Get a map of node names to info about each node. -- | Get a map of node names to info about each node.
nodeInfo :: Ord n => Graph n a b -> NodeInfo n a b nodeInfo :: Ord n => Graph n a b -> NodeInfo n a b
nodeInfo g = Map.fromList [ (n, (x, fn inc n, fn out n)) | (n,x) <- nodes g ] nodeInfo g = Map.fromList [ (n, (x, fn inc n, fn out n)) | (n,x) <- nodes g ]
where where
inc = groupEdgesBy edgeTo g inc = groupEdgesBy edgeTo g
out = groupEdgesBy edgeFrom g out = groupEdgesBy edgeFrom g
fn m n = fromMaybe [] (Map.lookup n m) fn m n = fromMaybe [] (Map.lookup n m)
@@ -148,16 +148,16 @@ reverseGraph :: Graph n a b -> Graph n a b
reverseGraph (Graph c ns es) = Graph c ns [ (t,f,l) | (f,t,l) <- es ] reverseGraph (Graph c ns es) = Graph c ns [ (t,f,l) | (f,t,l) <- es ]
-- | Add the nodes from the second graph to the first graph. -- | Add the nodes from the second graph to the first graph.
-- The nodes in the second graph will be renamed using the name -- The nodes in the second graph will be renamed using the name
-- supply in the first graph. -- supply in the first graph.
-- This function is more efficient when the second graph -- This function is more efficient when the second graph
-- is smaller than the first. -- is smaller than the first.
mergeGraphs :: Ord m => Graph n a b -> Graph m a b mergeGraphs :: Ord m => Graph n a b -> Graph m a b
-> (Graph n a b, m -> n) -- ^ The new graph and a function translating -> (Graph n a b, m -> n) -- ^ The new graph and a function translating
-- the old names of nodes in the second graph -- the old names of nodes in the second graph
-- to names in the new graph. -- to names in the new graph.
mergeGraphs (Graph c ns1 es1) g2 = (Graph c' (ns2++ns1) (es2++es1), newName) mergeGraphs (Graph c ns1 es1) g2 = (Graph c' (ns2++ns1) (es2++es1), newName)
where where
(xs,c') = splitAt (length (nodes g2)) c (xs,c') = splitAt (length (nodes g2)) c
newNames = Map.fromList (zip (map fst (nodes g2)) xs) newNames = Map.fromList (zip (map fst (nodes g2)) xs)
newName n = fromJust $ Map.lookup n newNames newName n = fromJust $ Map.lookup n newNames
@@ -170,7 +170,7 @@ renameNodes :: (n -> m) -- ^ renaming function
-> Graph n a b -> Graph m a b -> Graph n a b -> Graph m a b
renameNodes newName c (Graph _ ns es) = Graph c ns' es' renameNodes newName c (Graph _ ns es) = Graph c ns' es'
where ns' = map' (\ (n,x) -> (newName n,x)) ns where ns' = map' (\ (n,x) -> (newName n,x)) ns
es' = map' (\ (f,t,l) -> (newName f, newName t, l)) es es' = map' (\ (f,t,l) -> (newName f, newName t, l)) es
-- | A strict 'map' -- | A strict 'map'
map' :: (a -> b) -> [a] -> [b] map' :: (a -> b) -> [a] -> [b]

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/09/15 18:10:44 $ -- > CVS $Date: 2005/09/15 18:10:44 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.2 $ -- > CVS $Revision: 1.2 $
-- --
@@ -13,14 +13,14 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Data.Graphviz ( module GF.Data.Graphviz (
Graph(..), GraphType(..), Graph(..), GraphType(..),
Node(..), Edge(..), Node(..), Edge(..),
Attr, Attr,
addSubGraphs, addSubGraphs,
setName, setName,
setAttr, setAttr,
prGraphviz prGraphviz
) where ) where
import Data.Char import Data.Char
@@ -70,14 +70,14 @@ prGraphviz g@(Graph t i _ _ _ _) =
graphtype t ++ " " ++ maybe "" esc i ++ " {\n" ++ prGraph g ++ "}\n" graphtype t ++ " " ++ maybe "" esc i ++ " {\n" ++ prGraph g ++ "}\n"
prSubGraph :: Graph -> String prSubGraph :: Graph -> String
prSubGraph g@(Graph _ i _ _ _ _) = prSubGraph g@(Graph _ i _ _ _ _) =
"subgraph" ++ " " ++ maybe "" esc i ++ " {\n" ++ prGraph g ++ "}" "subgraph" ++ " " ++ maybe "" esc i ++ " {\n" ++ prGraph g ++ "}"
prGraph :: Graph -> String prGraph :: Graph -> String
prGraph (Graph t id at ns es ss) = prGraph (Graph t id at ns es ss) =
unlines $ map (++";") (map prAttr at unlines $ map (++";") (map prAttr at
++ map prNode ns ++ map prNode ns
++ map (prEdge t) es ++ map (prEdge t) es
++ map prSubGraph ss) ++ map prSubGraph ss)
graphtype :: GraphType -> String graphtype :: GraphType -> String
@@ -96,7 +96,7 @@ edgeop Undirected = "--"
prAttrList :: [Attr] -> String prAttrList :: [Attr] -> String
prAttrList [] = "" prAttrList [] = ""
prAttrList at = "[" ++ join "," (map prAttr at) ++ "]" prAttrList at = "[" ++ join "," (map prAttr at) ++ "]"
prAttr :: Attr -> String prAttr :: Attr -> String
prAttr (n,v) = esc n ++ " = " ++ esc v prAttr (n,v) = esc n ++ " = " ++ esc v

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/11/11 16:12:41 $ -- > CVS $Date: 2005/11/11 16:12:41 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.22 $ -- > CVS $Revision: 1.22 $
-- --
@@ -15,34 +15,34 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Data.Operations ( module GF.Data.Operations (
-- ** The Error monad -- ** The Error monad
Err(..), err, maybeErr, testErr, fromErr, errIn, Err(..), err, maybeErr, testErr, fromErr, errIn,
lookupErr, lookupErr,
-- ** Error monad class -- ** Error monad class
ErrorMonad(..), checks, --doUntil, allChecks, checkAgain, ErrorMonad(..), checks, --doUntil, allChecks, checkAgain,
liftErr, liftErr,
-- ** Checking
checkUnique, unifyMaybeBy, unifyMaybe,
-- ** Monadic operations on lists and pairs -- ** Checking
mapPairsM, pairM, checkUnique, unifyMaybeBy, unifyMaybe,
-- ** Printing
indent, (+++), (++-), (++++), (+++-), (+++++),
prUpper, prReplicate, prTList, prQuotedString, prParenth, prCurly,
prBracket, prArgList, prSemicList, prCurlyList, restoreEscapes,
numberedParagraphs, prConjList, prIfEmpty, wrapLines,
-- ** Topological sorting -- ** Monadic operations on lists and pairs
topoTest, topoTest2, mapPairsM, pairM,
-- ** Misc -- ** Printing
readIntArg, indent, (+++), (++-), (++++), (+++-), (+++++),
iterFix, chunks, prUpper, prReplicate, prTList, prQuotedString, prParenth, prCurly,
prBracket, prArgList, prSemicList, prCurlyList, restoreEscapes,
) where numberedParagraphs, prConjList, prIfEmpty, wrapLines,
-- ** Topological sorting
topoTest, topoTest2,
-- ** Misc
readIntArg,
iterFix, chunks,
) where
import Data.Char (isSpace, toUpper, isSpace, isDigit) import Data.Char (isSpace, toUpper, isSpace, isDigit)
import Data.List (nub, partition, (\\)) import Data.List (nub, partition, (\\))
@@ -107,7 +107,7 @@ indent i s = replicate i ' ' ++ s
(+++), (++-), (++++), (+++-), (+++++) :: String -> String -> String (+++), (++-), (++++), (+++-), (+++++) :: String -> String -> String
a +++ b = a ++ " " ++ b a +++ b = a ++ " " ++ b
a ++- "" = a a ++- "" = a
a ++- b = a +++ b a ++- b = a +++ b
a ++++ b = a ++ "\n" ++ b a ++++ b = a ++ "\n" ++ b
@@ -145,20 +145,20 @@ prCurly s = "{" ++ s ++ "}"
prBracket s = "[" ++ s ++ "]" prBracket s = "[" ++ s ++ "]"
prArgList, prSemicList, prCurlyList :: [String] -> String prArgList, prSemicList, prCurlyList :: [String] -> String
prArgList = prParenth . prTList "," prArgList = prParenth . prTList ","
prSemicList = prTList " ; " prSemicList = prTList " ; "
prCurlyList = prCurly . prSemicList prCurlyList = prCurly . prSemicList
restoreEscapes :: String -> String restoreEscapes :: String -> String
restoreEscapes s = restoreEscapes s =
case s of case s of
[] -> [] [] -> []
'"' : t -> '\\' : '"' : restoreEscapes t '"' : t -> '\\' : '"' : restoreEscapes t
'\\': t -> '\\' : '\\' : restoreEscapes t '\\': t -> '\\' : '\\' : restoreEscapes t
c : t -> c : restoreEscapes t c : t -> c : restoreEscapes t
numberedParagraphs :: [[String]] -> [String] numberedParagraphs :: [[String]] -> [String]
numberedParagraphs t = case t of numberedParagraphs t = case t of
[] -> [] [] -> []
p:[] -> p p:[] -> p
_ -> concat [(show n ++ ".") : s | (n,s) <- zip [1..] t] _ -> concat [(show n ++ ".") : s | (n,s) <- zip [1..] t]
@@ -204,12 +204,12 @@ topoTest2 g0 = maybe (Right cycles) Left (tsort g)
([],[]) -> Just [] ([],[]) -> Just []
([],_) -> Nothing ([],_) -> Nothing
(ns,rest) -> (leaves:) `fmap` tsort [(n,es \\ leaves) | (n,es)<-rest] (ns,rest) -> (leaves:) `fmap` tsort [(n,es \\ leaves) | (n,es)<-rest]
where leaves = map fst ns where leaves = map fst ns
-- | Fix point iterator (for computing e.g. transitive closures or reachability) -- | Fix point iterator (for computing e.g. transitive closures or reachability)
iterFix :: Eq a => ([a] -> [a]) -> [a] -> [a] iterFix :: Eq a => ([a] -> [a]) -> [a] -> [a]
iterFix more start = iter start start iterFix more start = iter start start
where where
iter old new = if (null new') iter old new = if (null new')
then old then old
@@ -241,7 +241,7 @@ liftErr e = err raise return e
{- {-
instance ErrorMonad (STM s) where instance ErrorMonad (STM s) where
raise msg = STM (\s -> raise msg) raise msg = STM (\s -> raise msg)
handle (STM f) g = STM (\s -> (f s) handle (STM f) g = STM (\s -> (f s)
`handle` (\e -> let STM g' = (g e) in `handle` (\e -> let STM g' = (g e) in
g' s)) g' s))

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/10/26 17:13:13 $ -- > CVS $Date: 2005/10/26 17:13:13 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.1 $ -- > CVS $Revision: 1.1 $
-- --
@@ -83,7 +83,7 @@ transitiveClosure r = fix (Map.map growSet) r
where growSet ys = foldl Set.union ys (map (allRelated r) $ Set.toList ys) where growSet ys = foldl Set.union ys (map (allRelated r) $ Set.toList ys)
reflexiveClosure_ :: Ord a => [a] -- ^ The set over which the relation is defined. reflexiveClosure_ :: Ord a => [a] -- ^ The set over which the relation is defined.
-> Rel a -> Rel a -> Rel a -> Rel a
reflexiveClosure_ u r = relates [(x,x) | x <- u] r reflexiveClosure_ u r = relates [(x,x) | x <- u] r
-- | Uses 'domain' -- | Uses 'domain'
@@ -104,7 +104,7 @@ reflexiveElements :: Ord a => Rel a -> Set a
reflexiveElements r = Set.fromList [ x | (x,ys) <- Map.toList r, x `Set.member` ys ] reflexiveElements r = Set.fromList [ x | (x,ys) <- Map.toList r, x `Set.member` ys ]
-- | Keep the related pairs for which the predicate is true. -- | Keep the related pairs for which the predicate is true.
filterRel :: Ord a => (a -> a -> Bool) -> Rel a -> Rel a filterRel :: Ord a => (a -> a -> Bool) -> Rel a -> Rel a
filterRel p = fst . purgeEmpty . Map.mapWithKey (Set.filter . p) filterRel p = fst . purgeEmpty . Map.mapWithKey (Set.filter . p)
-- | Remove keys that map to no elements. -- | Remove keys that map to no elements.
@@ -112,16 +112,16 @@ purgeEmpty :: Ord a => Rel a -> (Rel a, Set a)
purgeEmpty r = let (r',r'') = Map.partition (not . Set.null) r purgeEmpty r = let (r',r'') = Map.partition (not . Set.null) r
in (r', Map.keysSet r'') in (r', Map.keysSet r'')
-- | Get the equivalence classes from an equivalence relation. -- | Get the equivalence classes from an equivalence relation.
equivalenceClasses :: Ord a => Rel a -> [Set a] equivalenceClasses :: Ord a => Rel a -> [Set a]
equivalenceClasses r = equivalenceClasses_ (Map.keys r) r equivalenceClasses r = equivalenceClasses_ (Map.keys r) r
where equivalenceClasses_ [] _ = [] where equivalenceClasses_ [] _ = []
equivalenceClasses_ (x:xs) r = ys:equivalenceClasses_ zs r equivalenceClasses_ (x:xs) r = ys:equivalenceClasses_ zs r
where ys = allRelated r x where ys = allRelated r x
zs = [x' | x' <- xs, not (x' `Set.member` ys)] zs = [x' | x' <- xs, not (x' `Set.member` ys)]
isTransitive :: Ord a => Rel a -> Bool isTransitive :: Ord a => Rel a -> Bool
isTransitive r = and [z `Set.member` ys | (x,ys) <- Map.toList r, isTransitive r = and [z `Set.member` ys | (x,ys) <- Map.toList r,
y <- Set.toList ys, z <- Set.toList (allRelated r y)] y <- Set.toList ys, z <- Set.toList (allRelated r y)]
isReflexive :: Ord a => Rel a -> Bool isReflexive :: Ord a => Rel a -> Bool
@@ -181,7 +181,7 @@ remove x r = let (mss,r') = Map.updateLookupWithKey (\_ _ -> Nothing) x r
Nothing -> (r', Set.empty, Set.empty) Nothing -> (r', Set.empty, Set.empty)
-- remove element from all incoming and outgoing sets -- remove element from all incoming and outgoing sets
-- of other elements -- of other elements
Just (is,os) -> Just (is,os) ->
let r'' = foldr (\i -> Map.adjust (\ (is',os') -> (is', Set.delete x os')) i) r' $ Set.toList is let r'' = foldr (\i -> Map.adjust (\ (is',os') -> (is', Set.delete x os')) i) r' $ Set.toList is
r''' = foldr (\o -> Map.adjust (\ (is',os') -> (Set.delete x is', os')) o) r'' $ Set.toList os r''' = foldr (\o -> Map.adjust (\ (is',os') -> (Set.delete x is', os')) o) r'' $ Set.toList os
in (r''', is, os) in (r''', is, os)
@@ -190,4 +190,4 @@ incoming :: Ord a => a -> Rel' a -> Set a
incoming x r = maybe Set.empty fst $ Map.lookup x r incoming x r = maybe Set.empty fst $ Map.lookup x r
--outgoing :: Ord a => a -> Rel' a -> Set a --outgoing :: Ord a => a -> Rel' a -> Set a
--outgoing x r = maybe Set.empty snd $ Map.lookup x r --outgoing x r = maybe Set.empty snd $ Map.lookup x r

View File

@@ -4,7 +4,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/10/26 18:47:16 $ -- > CVS $Date: 2005/10/26 18:47:16 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.6 $ -- > CVS $Revision: 1.6 $
-- --
@@ -33,7 +33,7 @@ longerThan n = not . notLongerThan n
lookupList :: Eq a => a -> [(a, b)] -> [b] lookupList :: Eq a => a -> [(a, b)] -> [b]
lookupList a [] = [] lookupList a [] = []
lookupList a (p:ps) | a == fst p = snd p : lookupList a ps lookupList a (p:ps) | a == fst p = snd p : lookupList a ps
| otherwise = lookupList a ps | otherwise = lookupList a ps
split :: [a] -> ([a], [a]) split :: [a] -> ([a], [a])
split (x : y : as) = (x:xs, y:ys) split (x : y : as) = (x:xs, y:ys)
@@ -48,8 +48,8 @@ splitBy p (a : as) = if p a then (a:xs, ys) else (xs, a:ys)
foldMerge :: (a -> a -> a) -> a -> [a] -> a foldMerge :: (a -> a -> a) -> a -> [a] -> a
foldMerge merge zero = fm foldMerge merge zero = fm
where fm [] = zero where fm [] = zero
fm [a] = a fm [a] = a
fm abs = let (as, bs) = split abs in fm as `merge` fm bs fm abs = let (as, bs) = split abs in fm as `merge` fm bs
select :: [a] -> [(a, [a])] select :: [a] -> [(a, [a])]
select [] = [] select [] = []
@@ -68,7 +68,7 @@ safeInit :: [a] -> [a]
safeInit [] = [] safeInit [] = []
safeInit xs = init xs safeInit xs = init xs
-- | Sorts and then groups elements given an ordering of the -- | Sorts and then groups elements given an ordering of the
-- elements. -- elements.
sortGroupBy :: (a -> a -> Ordering) -> [a] -> [[a]] sortGroupBy :: (a -> a -> Ordering) -> [a] -> [[a]]
sortGroupBy f = groupBy (compareEq f) . sortBy f sortGroupBy f = groupBy (compareEq f) . sortBy f

View File

@@ -45,12 +45,12 @@ data LincatDef = LincatDef CatId LinType deriving Show
data LinDef = LinDef FunId [VarId] LinValue deriving Show data LinDef = LinDef FunId [VarId] LinValue deriving Show
-- | Linearization type, RHS of @lincat@ -- | Linearization type, RHS of @lincat@
data LinType = FloatType data LinType = FloatType
| IntType | IntType
| ParamType ParamType | ParamType ParamType
| RecordType [RecordRowType] | RecordType [RecordRowType]
| StrType | StrType
| TableType LinType LinType | TableType LinType LinType
| TupleType [LinType] | TupleType [LinType]
deriving (Eq,Ord,Show) deriving (Eq,Ord,Show)
@@ -60,7 +60,7 @@ newtype ParamType = ParamTypeId ParamId deriving (Eq,Ord,Show)
data LinValue = ConcatValue LinValue LinValue data LinValue = ConcatValue LinValue LinValue
| LiteralValue LinLiteral | LiteralValue LinLiteral
| ErrorValue String | ErrorValue String
| ParamConstant ParamValue | ParamConstant ParamValue
| PredefValue PredefId | PredefValue PredefId
| RecordValue [RecordRowValue] | RecordValue [RecordRowValue]
| TableValue LinType [TableRowValue] | TableValue LinType [TableRowValue]
@@ -74,9 +74,9 @@ data LinValue = ConcatValue LinValue LinValue
| CommentedValue String LinValue | CommentedValue String LinValue
deriving (Eq,Ord,Show) deriving (Eq,Ord,Show)
data LinLiteral = FloatConstant Float data LinLiteral = FloatConstant Float
| IntConstant Int | IntConstant Int
| StrConstant String | StrConstant String
deriving (Eq,Ord,Show) deriving (Eq,Ord,Show)
data LinPattern = ParamPattern ParamPattern data LinPattern = ParamPattern ParamPattern
@@ -107,7 +107,7 @@ newtype PredefId = PredefId Id deriving (Eq,Ord,Show)
newtype LabelId = LabelId Id deriving (Eq,Ord,Show) newtype LabelId = LabelId Id deriving (Eq,Ord,Show)
data VarValueId = VarValueId QualId deriving (Eq,Ord,Show) data VarValueId = VarValueId QualId deriving (Eq,Ord,Show)
-- | Name of param type or param value -- | Name of param type or param value
newtype ParamId = ParamId QualId deriving (Eq,Ord,Show) newtype ParamId = ParamId QualId deriving (Eq,Ord,Show)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -250,7 +250,7 @@ instance PPA LinLiteral where
FloatConstant f -> pp f FloatConstant f -> pp f
IntConstant n -> pp n IntConstant n -> pp n
StrConstant s -> doubleQuotes s -- hmm StrConstant s -> doubleQuotes s -- hmm
instance RhsSeparator LinValue where rhsSep _ = pp "=" instance RhsSeparator LinValue where rhsSep _ = pp "="
instance Pretty LinPattern where instance Pretty LinPattern where
@@ -265,7 +265,7 @@ instance PPA LinPattern where
ParamPattern pv -> ppA pv ParamPattern pv -> ppA pv
RecordPattern r -> block r RecordPattern r -> block r
TuplePattern ps -> "<"<>punctuate "," ps<>">" TuplePattern ps -> "<"<>punctuate "," ps<>">"
WildPattern -> pp "_" WildPattern -> pp "_"
instance RhsSeparator LinPattern where rhsSep _ = pp "=" instance RhsSeparator LinPattern where rhsSep _ = pp "="

View File

@@ -78,6 +78,7 @@ import PGF.Internal (FId, FunId, SeqId, LIndex, Sequence, BindType(..))
import Data.Array.IArray(Array) import Data.Array.IArray(Array)
import Data.Array.Unboxed(UArray) import Data.Array.Unboxed(UArray)
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set
import GF.Text.Pretty import GF.Text.Pretty
@@ -125,10 +126,20 @@ extends :: ModuleInfo -> [ModuleName]
extends = map fst . mextend extends = map fst . mextend
isInherited :: MInclude -> Ident -> Bool isInherited :: MInclude -> Ident -> Bool
isInherited c i = case c of isInherited c =
MIAll -> True case c of
MIOnly is -> elem i is MIAll -> const True
MIExcept is -> notElem i is MIOnly is -> elemOrd is
MIExcept is -> not . elemOrd is
-- | Faster version of `elem`, using a `Set`.
-- Make sure you give this the first argument _outside_ of the inner loop
--
-- Example:
-- > myIntersection xs ys = filter (elemOrd xs) ys
elemOrd :: Ord a => [a] -> a -> Bool
elemOrd list = (`Set.member` set)
where set = Set.fromList list
inheritAll :: ModuleName -> (ModuleName,MInclude) inheritAll :: ModuleName -> (ModuleName,MInclude)
inheritAll i = (i,MIAll) inheritAll i = (i,MIAll)

View File

@@ -4,7 +4,7 @@
module GF.Grammar.Lexer module GF.Grammar.Lexer
( Token(..), Posn(..) ( Token(..), Posn(..)
, P, runP, runPartial, token, lexer, getPosn, failLoc , P, runP, runPartial, token, lexer, getPosn, failLoc
, isReservedWord , isReservedWord, invMap
) where ) where
import Control.Applicative import Control.Applicative
@@ -134,7 +134,7 @@ data Token
| T_Double Double -- double precision float literals | T_Double Double -- double precision float literals
| T_Ident Ident | T_Ident Ident
| T_EOF | T_EOF
-- deriving Show -- debug deriving (Eq, Ord, Show) -- debug
res = eitherResIdent res = eitherResIdent
eitherResIdent :: (Ident -> Token) -> Ident -> Token eitherResIdent :: (Ident -> Token) -> Ident -> Token
@@ -224,6 +224,13 @@ resWords = Map.fromList
] ]
where b s t = (identS s, t) where b s t = (identS s, t)
invMap :: Map.Map Token String
invMap = res
where
lst = Map.toList resWords
flp = map (\(k,v) -> (v,showIdent k)) lst
res = Map.fromList flp
unescapeInitTail :: String -> String unescapeInitTail :: String -> String
unescapeInitTail = unesc . tail where unescapeInitTail = unesc . tail where
unesc s = case s of unesc s = case s of
@@ -267,7 +274,7 @@ type AlexInput2 = (AlexInput,AlexInput)
data ParseResult a data ParseResult a
= POk AlexInput2 a = POk AlexInput2 a
| PFailed Posn -- The position of the error | PFailed Posn -- The position of the error
String -- The error message String -- The error message
newtype P a = P { unP :: AlexInput2 -> ParseResult a } newtype P a = P { unP :: AlexInput2 -> ParseResult a }
@@ -276,11 +283,11 @@ instance Functor P where
fmap = liftA fmap = liftA
instance Applicative P where instance Applicative P where
pure = return pure a = a `seq` (P $ \s -> POk s a)
(<*>) = ap (<*>) = ap
instance Monad P where instance Monad P where
return a = a `seq` (P $ \s -> POk s a) return = pure
(P m) >>= k = P $ \ s -> case m s of (P m) >>= k = P $ \ s -> case m s of
POk s a -> unP (k a) s POk s a -> unP (k a) s
PFailed posn err -> PFailed posn err PFailed posn err -> PFailed posn err

View File

@@ -6,7 +6,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/10/27 13:21:53 $ -- > CVS $Date: 2005/10/27 13:21:53 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.15 $ -- > CVS $Revision: 1.15 $
-- --
@@ -20,17 +20,17 @@ module GF.Grammar.Lookup (
lookupOrigInfo, lookupOrigInfo,
allOrigInfos, allOrigInfos,
lookupResDef, lookupResDefLoc, lookupResDef, lookupResDefLoc,
lookupResType, lookupResType,
lookupOverload, lookupOverload,
lookupOverloadTypes, lookupOverloadTypes,
lookupParamValues, lookupParamValues,
allParamValues, allParamValues,
lookupAbsDef, lookupAbsDef,
lookupLincat, lookupLincat,
lookupFunType, lookupFunType,
lookupCatContext, lookupCatContext,
allOpers, allOpersTo allOpers, allOpersTo
) where ) where
import GF.Data.Operations import GF.Data.Operations
import GF.Infra.Ident import GF.Infra.Ident
@@ -69,7 +69,7 @@ lookupResDef gr x = fmap unLoc (lookupResDefLoc gr x)
lookupResDefLoc gr (m,c) lookupResDefLoc gr (m,c)
| isPredefCat c = fmap noLoc (lock c defLinType) | isPredefCat c = fmap noLoc (lock c defLinType)
| otherwise = look m c | otherwise = look m c
where where
look m c = do look m c = do
info <- lookupQIdentInfo gr (m,c) info <- lookupQIdentInfo gr (m,c)
case info of case info of
@@ -77,7 +77,7 @@ lookupResDefLoc gr (m,c)
ResOper _ Nothing -> return (noLoc (Q (m,c))) ResOper _ Nothing -> return (noLoc (Q (m,c)))
CncCat (Just (L l ty)) _ _ _ _ -> fmap (L l) (lock c ty) CncCat (Just (L l ty)) _ _ _ _ -> fmap (L l) (lock c ty)
CncCat _ _ _ _ _ -> fmap noLoc (lock c defLinType) CncCat _ _ _ _ _ -> fmap noLoc (lock c defLinType)
CncFun (Just (cat,_,_)) (Just (L l tr)) _ _ -> fmap (L l) (unlock cat tr) CncFun (Just (cat,_,_)) (Just (L l tr)) _ _ -> fmap (L l) (unlock cat tr)
CncFun _ (Just ltr) _ _ -> return ltr CncFun _ (Just ltr) _ _ -> return ltr
@@ -95,7 +95,7 @@ lookupResType gr (m,c) = do
-- used in reused concrete -- used in reused concrete
CncCat _ _ _ _ _ -> return typeType CncCat _ _ _ _ _ -> return typeType
CncFun (Just (cat,cont,val)) _ _ _ -> do CncFun (Just (cat,cont,val)) _ _ _ -> do
val' <- lock cat val val' <- lock cat val
return $ mkProd cont val' [] return $ mkProd cont val' []
AnyInd _ n -> lookupResType gr (n,c) AnyInd _ n -> lookupResType gr (n,c)
ResParam _ _ -> return typePType ResParam _ _ -> return typePType
@@ -111,7 +111,7 @@ lookupOverloadTypes gr id@(m,c) = do
-- used in reused concrete -- used in reused concrete
CncCat _ _ _ _ _ -> ret typeType CncCat _ _ _ _ _ -> ret typeType
CncFun (Just (cat,cont,val)) _ _ _ -> do CncFun (Just (cat,cont,val)) _ _ _ -> do
val' <- lock cat val val' <- lock cat val
ret $ mkProd cont val' [] ret $ mkProd cont val' []
ResParam _ _ -> ret typePType ResParam _ _ -> ret typePType
ResValue (L _ t) -> ret t ResValue (L _ t) -> ret t
@@ -130,8 +130,8 @@ lookupOverload gr (m,c) = do
case info of case info of
ResOverload os tysts -> do ResOverload os tysts -> do
tss <- mapM (\x -> lookupOverload gr (x,c)) os tss <- mapM (\x -> lookupOverload gr (x,c)) os
return $ [let (args,val) = typeFormCnc ty in (map (\(b,x,t) -> t) args,(val,tr)) | return $ [let (args,val) = typeFormCnc ty in (map (\(b,x,t) -> t) args,(val,tr)) |
(L _ ty,L _ tr) <- tysts] ++ (L _ ty,L _ tr) <- tysts] ++
concat tss concat tss
AnyInd _ n -> lookupOverload gr (n,c) AnyInd _ n -> lookupOverload gr (n,c)
@@ -216,7 +216,7 @@ lookupCatContext gr m c = do
-- notice that it only gives the modules that are reachable and the opers that are included -- notice that it only gives the modules that are reachable and the opers that are included
allOpers :: Grammar -> [(QIdent,Type,Location)] allOpers :: Grammar -> [(QIdent,Type,Location)]
allOpers gr = allOpers gr =
[((m,op),typ,loc) | [((m,op),typ,loc) |
(m,mi) <- maybe [] (allExtends gr) (greatestResource gr), (m,mi) <- maybe [] (allExtends gr) (greatestResource gr),
(op,info) <- Map.toList (jments mi), (op,info) <- Map.toList (jments mi),

View File

@@ -37,6 +37,9 @@ import PGF(mkCId)
%name pBNFCRules ListCFRule %name pBNFCRules ListCFRule
%name pEBNFRules ListEBNFRule %name pEBNFRules ListEBNFRule
%errorhandlertype explist
%error { happyError }
-- no lexer declaration -- no lexer declaration
%monad { P } { >>= } { return } %monad { P } { >>= } { return }
%lexer { lexer } { T_EOF } %lexer { lexer } { T_EOF }
@@ -430,6 +433,7 @@ Exp3
RecType xs -> RecType (xs ++ [(tupleLabel (length xs+1),$3)]) RecType xs -> RecType (xs ++ [(tupleLabel (length xs+1),$3)])
t -> RecType [(tupleLabel 1,$1), (tupleLabel 2,$3)] } t -> RecType [(tupleLabel 1,$1), (tupleLabel 2,$3)] }
| Exp3 '**' Exp4 { ExtR $1 $3 } | Exp3 '**' Exp4 { ExtR $1 $3 }
| Exp3 '**' '{' ListCase '}' { let v = identS "$vvv" in T TRaw ($4 ++ [(PV v, S $1 (Vr v))]) }
| Exp4 { $1 } | Exp4 { $1 }
Exp4 :: { Term } Exp4 :: { Term }
@@ -701,8 +705,18 @@ Posn
{ {
happyError :: P a happyError :: (Token, [String]) -> P a
happyError = fail "syntax error" happyError (t,strs) = fail $
"Syntax error:\n Unexpected " ++ showToken t ++ ".\n Expected one of:\n"
++ unlines (map ((" - "++).cleanupToken) strs)
where
cleanupToken "Ident" = "an identifier"
cleanupToken x = x
showToken (T_Ident i) = "identifier '" ++ showIdent i ++ "'"
showToken t = case Map.lookup t invMap of
Nothing -> show t
Just s -> "token '" ++ s ++"'"
mkListId,mkConsId,mkBaseId :: Ident -> Ident mkListId,mkConsId,mkBaseId :: Ident -> Ident
mkListId = prefixIdent "List" mkListId = prefixIdent "List"

View File

@@ -5,18 +5,19 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/10/12 12:38:29 $ -- > CVS $Date: 2005/10/12 12:38:29 $
-- > CVS $Author: aarne $ -- > CVS $Author: aarne $
-- > CVS $Revision: 1.7 $ -- > CVS $Revision: 1.7 $
-- --
-- pattern matching for both concrete and abstract syntax. AR -- 16\/6\/2003 -- pattern matching for both concrete and abstract syntax. AR -- 16\/6\/2003
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Grammar.PatternMatch (matchPattern, module GF.Grammar.PatternMatch (
testOvershadow, matchPattern,
findMatch, testOvershadow,
measurePatt findMatch,
) where measurePatt
) where
import GF.Data.Operations import GF.Data.Operations
import GF.Grammar.Grammar import GF.Grammar.Grammar
@@ -30,7 +31,7 @@ import GF.Text.Pretty
--import Debug.Trace --import Debug.Trace
matchPattern :: ErrorMonad m => [(Patt,rhs)] -> Term -> m (rhs, Substitution) matchPattern :: ErrorMonad m => [(Patt,rhs)] -> Term -> m (rhs, Substitution)
matchPattern pts term = matchPattern pts term =
if not (isInConstantForm term) if not (isInConstantForm term)
then raise (render ("variables occur in" <+> pp term)) then raise (render ("variables occur in" <+> pp term))
else do else do
@@ -61,15 +62,15 @@ testOvershadow pts vs = do
findMatch :: ErrorMonad m => [([Patt],rhs)] -> [Term] -> m (rhs, Substitution) findMatch :: ErrorMonad m => [([Patt],rhs)] -> [Term] -> m (rhs, Substitution)
findMatch cases terms = case cases of findMatch cases terms = case cases of
[] -> raise (render ("no applicable case for" <+> hsep (punctuate ',' terms))) [] -> raise (render ("no applicable case for" <+> hsep (punctuate ',' terms)))
(patts,_):_ | length patts /= length terms -> (patts,_):_ | length patts /= length terms ->
raise (render ("wrong number of args for patterns :" <+> hsep patts <+> raise (render ("wrong number of args for patterns :" <+> hsep patts <+>
"cannot take" <+> hsep terms)) "cannot take" <+> hsep terms))
(patts,val):cc -> case mapM tryMatch (zip patts terms) of (patts,val):cc -> case mapM tryMatch (zip patts terms) of
Ok substs -> return (val, concat substs) Ok substs -> return (val, concat substs)
_ -> findMatch cc terms _ -> findMatch cc terms
tryMatch :: (Patt, Term) -> Err [(Ident, Term)] tryMatch :: (Patt, Term) -> Err [(Ident, Term)]
tryMatch (p,t) = do tryMatch (p,t) = do
t' <- termForm t t' <- termForm t
trym p t' trym p t'
where where
@@ -83,26 +84,26 @@ tryMatch (p,t) = do
(PString s, ([],K i,[])) | s==i -> return [] (PString s, ([],K i,[])) | s==i -> return []
(PInt s, ([],EInt i,[])) | s==i -> return [] (PInt s, ([],EInt i,[])) | s==i -> return []
(PFloat s,([],EFloat i,[])) | s==i -> return [] --- rounding? (PFloat s,([],EFloat i,[])) | s==i -> return [] --- rounding?
(PC p pp, ([], Con f, tt)) | (PC p pp, ([], Con f, tt)) |
p `eqStrIdent` f && length pp == length tt -> p `eqStrIdent` f && length pp == length tt ->
do matches <- mapM tryMatch (zip pp tt) do matches <- mapM tryMatch (zip pp tt)
return (concat matches) return (concat matches)
(PP (q,p) pp, ([], QC (r,f), tt)) | (PP (q,p) pp, ([], QC (r,f), tt)) |
-- q `eqStrIdent` r && --- not for inherited AR 10/10/2005 -- q `eqStrIdent` r && --- not for inherited AR 10/10/2005
p `eqStrIdent` f && length pp == length tt -> p `eqStrIdent` f && length pp == length tt ->
do matches <- mapM tryMatch (zip pp tt) do matches <- mapM tryMatch (zip pp tt)
return (concat matches) return (concat matches)
---- hack for AppPredef bug ---- hack for AppPredef bug
(PP (q,p) pp, ([], Q (r,f), tt)) | (PP (q,p) pp, ([], Q (r,f), tt)) |
-- q `eqStrIdent` r && --- -- q `eqStrIdent` r && ---
p `eqStrIdent` f && length pp == length tt -> p `eqStrIdent` f && length pp == length tt ->
do matches <- mapM tryMatch (zip pp tt) do matches <- mapM tryMatch (zip pp tt)
return (concat matches) return (concat matches)
(PR r, ([],R r',[])) | (PR r, ([],R r',[])) |
all (`elem` map fst r') (map fst r) -> all (`elem` map fst r') (map fst r) ->
do matches <- mapM tryMatch do matches <- mapM tryMatch
[(p,snd a) | (l,p) <- r, let Just a = lookup l r'] [(p,snd a) | (l,p) <- r, let Just a = lookup l r']
return (concat matches) return (concat matches)
(PT _ p',_) -> trym p' t' (PT _ p',_) -> trym p' t'
@@ -125,7 +126,7 @@ tryMatch (p,t) = do
(PMSeq mp1 mp2, ([],K s, [])) -> matchPMSeq mp1 mp2 s (PMSeq mp1 mp2, ([],K s, [])) -> matchPMSeq mp1 mp2 s
(PRep p1, ([],K s, [])) -> checks [ (PRep p1, ([],K s, [])) -> checks [
trym (foldr (const (PSeq p1)) (PString "") trym (foldr (const (PSeq p1)) (PString "")
[1..n]) t' | n <- [0 .. length s] [1..n]) t' | n <- [0 .. length s]
] >> ] >>
return [] return []

View File

@@ -1,365 +1,364 @@
---------------------------------------------------------------------- ----------------------------------------------------------------------
-- | -- |
-- Module : GF.Grammar.Printer -- Module : GF.Grammar.Printer
-- Maintainer : Krasimir Angelov -- Maintainer : Krasimir Angelov
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
module GF.Grammar.Printer module GF.Grammar.Printer
( -- ** Pretty printing ( -- ** Pretty printing
TermPrintQual(..) TermPrintQual(..)
, ppModule , ppModule
, ppJudgement , ppJudgement
, ppParams , ppParams
, ppTerm , ppTerm
, ppPatt , ppPatt
, ppValue , ppValue
, ppConstrs , ppConstrs
, ppQIdent , ppQIdent
, ppMeta , ppMeta
, getAbs , getAbs
) where ) where
import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
import GF.Infra.Ident import GF.Infra.Ident
import GF.Infra.Option import GF.Infra.Option
import GF.Grammar.Values import GF.Grammar.Values
import GF.Grammar.Grammar import GF.Grammar.Grammar
import PGF.Internal (ppMeta, ppLit, ppFId, ppFunId, ppSeqId, ppSeq) import PGF.Internal (ppMeta, ppLit, ppFId, ppFunId, ppSeqId, ppSeq)
import GF.Text.Pretty import GF.Text.Pretty
import Data.Maybe (isNothing) import Data.Maybe (isNothing)
import Data.List (intersperse) import Data.List (intersperse)
import qualified Data.Map as Map import qualified Data.Map as Map
--import qualified Data.IntMap as IntMap --import qualified Data.IntMap as IntMap
--import qualified Data.Set as Set --import qualified Data.Set as Set
import qualified Data.Array.IArray as Array import qualified Data.Array.IArray as Array
data TermPrintQual data TermPrintQual
= Terse | Unqualified | Qualified | Internal = Terse | Unqualified | Qualified | Internal
deriving Eq deriving Eq
instance Pretty Grammar where instance Pretty Grammar where
pp = vcat . map (ppModule Qualified) . modules pp = vcat . map (ppModule Qualified) . modules
ppModule :: TermPrintQual -> SourceModule -> Doc ppModule :: TermPrintQual -> SourceModule -> Doc
ppModule q (mn, ModInfo mtype mstat opts exts with opens _ _ mseqs jments) = ppModule q (mn, ModInfo mtype mstat opts exts with opens _ _ mseqs jments) =
hdr $$ hdr $$
nest 2 (ppOptions opts $$ nest 2 (ppOptions opts $$
vcat (map (ppJudgement q) (Map.toList jments)) $$ vcat (map (ppJudgement q) (Map.toList jments)) $$
maybe empty (ppSequences q) mseqs) $$ maybe empty (ppSequences q) mseqs) $$
ftr ftr
where where
hdr = complModDoc <+> modTypeDoc <+> '=' <+> hdr = complModDoc <+> modTypeDoc <+> '=' <+>
hsep (intersperse (pp "**") $ hsep (intersperse (pp "**") $
filter (not . isEmpty) $ [ commaPunct ppExtends exts filter (not . isEmpty) $ [ commaPunct ppExtends exts
, maybe empty ppWith with , maybe empty ppWith with
, if null opens , if null opens
then pp '{' then pp '{'
else "open" <+> commaPunct ppOpenSpec opens <+> "in" <+> '{' else "open" <+> commaPunct ppOpenSpec opens <+> "in" <+> '{'
]) ])
ftr = '}' ftr = '}'
complModDoc = complModDoc =
case mstat of case mstat of
MSComplete -> empty MSComplete -> empty
MSIncomplete -> pp "incomplete" MSIncomplete -> pp "incomplete"
modTypeDoc = modTypeDoc =
case mtype of case mtype of
MTAbstract -> "abstract" <+> mn MTAbstract -> "abstract" <+> mn
MTResource -> "resource" <+> mn MTResource -> "resource" <+> mn
MTConcrete abs -> "concrete" <+> mn <+> "of" <+> abs MTConcrete abs -> "concrete" <+> mn <+> "of" <+> abs
MTInterface -> "interface" <+> mn MTInterface -> "interface" <+> mn
MTInstance ie -> "instance" <+> mn <+> "of" <+> ppExtends ie MTInstance ie -> "instance" <+> mn <+> "of" <+> ppExtends ie
ppExtends (id,MIAll ) = pp id ppExtends (id,MIAll ) = pp id
ppExtends (id,MIOnly incs) = id <+> brackets (commaPunct pp incs) ppExtends (id,MIOnly incs) = id <+> brackets (commaPunct pp incs)
ppExtends (id,MIExcept incs) = id <+> '-' <+> brackets (commaPunct pp incs) ppExtends (id,MIExcept incs) = id <+> '-' <+> brackets (commaPunct pp incs)
ppWith (id,ext,opens) = ppExtends (id,ext) <+> "with" <+> commaPunct ppInstSpec opens ppWith (id,ext,opens) = ppExtends (id,ext) <+> "with" <+> commaPunct ppInstSpec opens
ppOptions opts = ppOptions opts =
"flags" $$ "flags" $$
nest 2 (vcat [option <+> '=' <+> ppLit value <+> ';' | (option,value) <- optionsGFO opts]) nest 2 (vcat [option <+> '=' <+> ppLit value <+> ';' | (option,value) <- optionsGFO opts])
ppJudgement q (id, AbsCat pcont ) = ppJudgement q (id, AbsCat pcont ) =
"cat" <+> id <+> "cat" <+> id <+>
(case pcont of (case pcont of
Just (L _ cont) -> hsep (map (ppDecl q) cont) Just (L _ cont) -> hsep (map (ppDecl q) cont)
Nothing -> empty) <+> ';' Nothing -> empty) <+> ';'
ppJudgement q (id, AbsFun ptype _ pexp poper) = ppJudgement q (id, AbsFun ptype _ pexp poper) =
let kind | isNothing pexp = "data" let kind | isNothing pexp = "data"
| poper == Just False = "oper" | poper == Just False = "oper"
| otherwise = "fun" | otherwise = "fun"
in in
(case ptype of (case ptype of
Just (L _ typ) -> kind <+> id <+> ':' <+> ppTerm q 0 typ <+> ';' Just (L _ typ) -> kind <+> id <+> ':' <+> ppTerm q 0 typ <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case pexp of (case pexp of
Just [] -> empty Just [] -> empty
Just eqs -> "def" <+> vcat [id <+> hsep (map (ppPatt q 2) ps) <+> '=' <+> ppTerm q 0 e <+> ';' | L _ (ps,e) <- eqs] Just eqs -> "def" <+> vcat [id <+> hsep (map (ppPatt q 2) ps) <+> '=' <+> ppTerm q 0 e <+> ';' | L _ (ps,e) <- eqs]
Nothing -> empty) Nothing -> empty)
ppJudgement q (id, ResParam pparams _) = ppJudgement q (id, ResParam pparams _) =
"param" <+> id <+> "param" <+> id <+>
(case pparams of (case pparams of
Just (L _ ps) -> '=' <+> ppParams q ps Just (L _ ps) -> '=' <+> ppParams q ps
_ -> empty) <+> ';' _ -> empty) <+> ';'
ppJudgement q (id, ResValue pvalue) = ppJudgement q (id, ResValue pvalue) =
"-- param constructor" <+> id <+> ':' <+> "-- param constructor" <+> id <+> ':' <+>
(case pvalue of (case pvalue of
(L _ ty) -> ppTerm q 0 ty) <+> ';' (L _ ty) -> ppTerm q 0 ty) <+> ';'
ppJudgement q (id, ResOper ptype pexp) = ppJudgement q (id, ResOper ptype pexp) =
"oper" <+> id <+> "oper" <+> id <+>
(case ptype of {Just (L _ t) -> ':' <+> ppTerm q 0 t; Nothing -> empty} $$ (case ptype of {Just (L _ t) -> ':' <+> ppTerm q 0 t; Nothing -> empty} $$
case pexp of {Just (L _ e) -> '=' <+> ppTerm q 0 e; Nothing -> empty}) <+> ';' case pexp of {Just (L _ e) -> '=' <+> ppTerm q 0 e; Nothing -> empty}) <+> ';'
ppJudgement q (id, ResOverload ids defs) = ppJudgement q (id, ResOverload ids defs) =
"oper" <+> id <+> '=' <+> "oper" <+> id <+> '=' <+>
("overload" <+> '{' $$ ("overload" <+> '{' $$
nest 2 (vcat [id <+> (':' <+> ppTerm q 0 ty $$ '=' <+> ppTerm q 0 e <+> ';') | (L _ ty,L _ e) <- defs]) $$ nest 2 (vcat [id <+> (':' <+> ppTerm q 0 ty $$ '=' <+> ppTerm q 0 e <+> ';') | (L _ ty,L _ e) <- defs]) $$
'}') <+> ';' '}') <+> ';'
ppJudgement q (id, CncCat pcat pdef pref pprn mpmcfg) = ppJudgement q (id, CncCat pcat pdef pref pprn mpmcfg) =
(case pcat of (case pcat of
Just (L _ typ) -> "lincat" <+> id <+> '=' <+> ppTerm q 0 typ <+> ';' Just (L _ typ) -> "lincat" <+> id <+> '=' <+> ppTerm q 0 typ <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case pdef of (case pdef of
Just (L _ exp) -> "lindef" <+> id <+> '=' <+> ppTerm q 0 exp <+> ';' Just (L _ exp) -> "lindef" <+> id <+> '=' <+> ppTerm q 0 exp <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case pref of (case pref of
Just (L _ exp) -> "linref" <+> id <+> '=' <+> ppTerm q 0 exp <+> ';' Just (L _ exp) -> "linref" <+> id <+> '=' <+> ppTerm q 0 exp <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case pprn of (case pprn of
Just (L _ prn) -> "printname" <+> id <+> '=' <+> ppTerm q 0 prn <+> ';' Just (L _ prn) -> "printname" <+> id <+> '=' <+> ppTerm q 0 prn <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case (mpmcfg,q) of (case (mpmcfg,q) of
(Just (PMCFG prods funs),Internal) (Just (PMCFG prods funs),Internal)
-> "pmcfg" <+> id <+> '=' <+> '{' $$ -> "pmcfg" <+> id <+> '=' <+> '{' $$
nest 2 (vcat (map ppProduction prods) $$ nest 2 (vcat (map ppProduction prods) $$
' ' $$ ' ' $$
vcat (map (\(funid,arr) -> ppFunId funid <+> ":=" <+> vcat (map (\(funid,arr) -> ppFunId funid <+> ":=" <+>
parens (hcat (punctuate ',' (map ppSeqId (Array.elems arr))))) parens (hcat (punctuate ',' (map ppSeqId (Array.elems arr)))))
(Array.assocs funs))) $$ (Array.assocs funs))) $$
'}' '}'
_ -> empty) _ -> empty)
ppJudgement q (id, CncFun ptype pdef pprn mpmcfg) = ppJudgement q (id, CncFun ptype pdef pprn mpmcfg) =
(case pdef of (case pdef of
Just (L _ e) -> let (xs,e') = getAbs e Just (L _ e) -> let (xs,e') = getAbs e
in "lin" <+> id <+> hsep (map ppBind xs) <+> '=' <+> ppTerm q 0 e' <+> ';' in "lin" <+> id <+> hsep (map ppBind xs) <+> '=' <+> ppTerm q 0 e' <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case pprn of (case pprn of
Just (L _ prn) -> "printname" <+> id <+> '=' <+> ppTerm q 0 prn <+> ';' Just (L _ prn) -> "printname" <+> id <+> '=' <+> ppTerm q 0 prn <+> ';'
Nothing -> empty) $$ Nothing -> empty) $$
(case (mpmcfg,q) of (case (mpmcfg,q) of
(Just (PMCFG prods funs),Internal) (Just (PMCFG prods funs),Internal)
-> "pmcfg" <+> id <+> '=' <+> '{' $$ -> "pmcfg" <+> id <+> '=' <+> '{' $$
nest 2 (vcat (map ppProduction prods) $$ nest 2 (vcat (map ppProduction prods) $$
' ' $$ ' ' $$
vcat (map (\(funid,arr) -> ppFunId funid <+> ":=" <+> vcat (map (\(funid,arr) -> ppFunId funid <+> ":=" <+>
parens (hcat (punctuate ',' (map ppSeqId (Array.elems arr))))) parens (hcat (punctuate ',' (map ppSeqId (Array.elems arr)))))
(Array.assocs funs))) $$ (Array.assocs funs))) $$
'}' '}'
_ -> empty) _ -> empty)
ppJudgement q (id, AnyInd cann mid) = ppJudgement q (id, AnyInd cann mid) =
case q of case q of
Internal -> "ind" <+> id <+> '=' <+> (if cann then pp "canonical" else empty) <+> mid <+> ';' Internal -> "ind" <+> id <+> '=' <+> (if cann then pp "canonical" else empty) <+> mid <+> ';'
_ -> empty _ -> empty
instance Pretty Term where pp = ppTerm Unqualified 0 instance Pretty Term where pp = ppTerm Unqualified 0
ppTerm q d (Abs b v e) = let (xs,e') = getAbs (Abs b v e) ppTerm q d (Abs b v e) = let (xs,e') = getAbs (Abs b v e)
in prec d 0 ('\\' <> commaPunct ppBind xs <+> "->" <+> ppTerm q 0 e') in prec d 0 ('\\' <> commaPunct ppBind xs <+> "->" <+> ppTerm q 0 e')
ppTerm q d (T TRaw xs) = case getCTable (T TRaw xs) of ppTerm q d (T TRaw xs) = case getCTable (T TRaw xs) of
([],_) -> "table" <+> '{' $$ ([],_) -> "table" <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$ nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$
'}' '}'
(vs,e) -> prec d 0 ("\\\\" <> commaPunct pp vs <+> "=>" <+> ppTerm q 0 e) (vs,e) -> prec d 0 ("\\\\" <> commaPunct pp vs <+> "=>" <+> ppTerm q 0 e)
ppTerm q d (T (TTyped t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$ ppTerm q d (T (TTyped t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$ nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$
'}' '}'
ppTerm q d (T (TComp t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$ ppTerm q d (T (TComp t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$ nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$
'}' '}'
ppTerm q d (T (TWild t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$ ppTerm q d (T (TWild t) xs) = "table" <+> ppTerm q 0 t <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$ nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$
'}' '}'
ppTerm q d (Prod bt x a b)= if x == identW && bt == Explicit ppTerm q d (Prod bt x a b)= if x == identW && bt == Explicit
then prec d 0 (ppTerm q 4 a <+> "->" <+> ppTerm q 0 b) then prec d 0 (ppTerm q 4 a <+> "->" <+> ppTerm q 0 b)
else prec d 0 (parens (ppBind (bt,x) <+> ':' <+> ppTerm q 0 a) <+> "->" <+> ppTerm q 0 b) else prec d 0 (parens (ppBind (bt,x) <+> ':' <+> ppTerm q 0 a) <+> "->" <+> ppTerm q 0 b)
ppTerm q d (Table kt vt)=prec d 0 (ppTerm q 3 kt <+> "=>" <+> ppTerm q 0 vt) ppTerm q d (Table kt vt)=prec d 0 (ppTerm q 3 kt <+> "=>" <+> ppTerm q 0 vt)
ppTerm q d (Let l e) = let (ls,e') = getLet e ppTerm q d (Let l e) = let (ls,e') = getLet e
in prec d 0 ("let" <+> vcat (map (ppLocDef q) (l:ls)) $$ "in" <+> ppTerm q 0 e') in prec d 0 ("let" <+> vcat (map (ppLocDef q) (l:ls)) $$ "in" <+> ppTerm q 0 e')
ppTerm q d (Example e s)=prec d 0 ("in" <+> ppTerm q 5 e <+> str s) ppTerm q d (Example e s)=prec d 0 ("in" <+> ppTerm q 5 e <+> str s)
ppTerm q d (C e1 e2) =prec d 1 (hang (ppTerm q 2 e1) 2 ("++" <+> ppTerm q 1 e2)) ppTerm q d (C e1 e2) =prec d 1 (hang (ppTerm q 2 e1) 2 ("++" <+> ppTerm q 1 e2))
ppTerm q d (Glue e1 e2) =prec d 2 (ppTerm q 3 e1 <+> '+' <+> ppTerm q 2 e2) ppTerm q d (Glue e1 e2) =prec d 2 (ppTerm q 3 e1 <+> '+' <+> ppTerm q 2 e2)
ppTerm q d (S x y) = case x of ppTerm q d (S x y) = case x of
T annot xs -> let e = case annot of T annot xs -> let e = case annot of
TRaw -> y TRaw -> y
TTyped t -> Typed y t TTyped t -> Typed y t
TComp t -> Typed y t TComp t -> Typed y t
TWild t -> Typed y t TWild t -> Typed y t
in "case" <+> ppTerm q 0 e <+>"of" <+> '{' $$ in "case" <+> ppTerm q 0 e <+>"of" <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$ nest 2 (vcat (punctuate ';' (map (ppCase q) xs))) $$
'}' '}'
_ -> prec d 3 (hang (ppTerm q 3 x) 2 ("!" <+> ppTerm q 4 y)) _ -> prec d 3 (hang (ppTerm q 3 x) 2 ("!" <+> ppTerm q 4 y))
ppTerm q d (ExtR x y) = prec d 3 (ppTerm q 3 x <+> "**" <+> ppTerm q 4 y) ppTerm q d (ExtR x y) = prec d 3 (ppTerm q 3 x <+> "**" <+> ppTerm q 4 y)
ppTerm q d (App x y) = prec d 4 (ppTerm q 4 x <+> ppTerm q 5 y) ppTerm q d (App x y) = prec d 4 (ppTerm q 4 x <+> ppTerm q 5 y)
ppTerm q d (V e es) = hang "table" 2 (sep [ppTerm q 6 e,brackets (fsep (punctuate ';' (map (ppTerm q 0) es)))]) ppTerm q d (V e es) = hang "table" 2 (sep [ppTerm q 6 e,brackets (fsep (punctuate ';' (map (ppTerm q 0) es)))])
ppTerm q d (FV es) = prec d 4 ("variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))) ppTerm q d (FV es) = prec d 4 ("variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es))))
ppTerm q d (AdHocOverload es) = "overload" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es))) ppTerm q d (AdHocOverload es) = "overload" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))
ppTerm q d (Alts e xs) = prec d 4 ("pre" <+> braces (ppTerm q 0 e <> ';' <+> fsep (punctuate ';' (map (ppAltern q) xs)))) ppTerm q d (Alts e xs) = prec d 4 ("pre" <+> braces (ppTerm q 0 e <> ';' <+> fsep (punctuate ';' (map (ppAltern q) xs))))
ppTerm q d (Strs es) = "strs" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es))) ppTerm q d (Strs es) = "strs" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))
ppTerm q d (EPatt p) = prec d 4 ('#' <+> ppPatt q 2 p) ppTerm q d (EPatt p) = prec d 4 ('#' <+> ppPatt q 2 p)
ppTerm q d (EPattType t)=prec d 4 ("pattern" <+> ppTerm q 0 t) ppTerm q d (EPattType t)=prec d 4 ("pattern" <+> ppTerm q 0 t)
ppTerm q d (P t l) = prec d 5 (ppTerm q 5 t <> '.' <> l) ppTerm q d (P t l) = prec d 5 (ppTerm q 5 t <> '.' <> l)
ppTerm q d (Cn id) = pp id ppTerm q d (Cn id) = pp id
ppTerm q d (Vr id) = pp id ppTerm q d (Vr id) = pp id
ppTerm q d (Q id) = ppQIdent q id ppTerm q d (Q id) = ppQIdent q id
ppTerm q d (QC id) = ppQIdent q id ppTerm q d (QC id) = ppQIdent q id
ppTerm q d (Sort id) = pp id ppTerm q d (Sort id) = pp id
ppTerm q d (K s) = str s ppTerm q d (K s) = str s
ppTerm q d (EInt n) = pp n ppTerm q d (EInt n) = pp n
ppTerm q d (EFloat f) = pp f ppTerm q d (EFloat f) = pp f
ppTerm q d (Meta i) = ppMeta i ppTerm q d (Meta i) = ppMeta i
ppTerm q d (Empty) = pp "[]" ppTerm q d (Empty) = pp "[]"
ppTerm q d (R []) = pp "<>" -- to distinguish from {} empty RecType ppTerm q d (R []) = pp "<>" -- to distinguish from {} empty RecType
ppTerm q d (R xs) = braces (fsep (punctuate ';' [l <+> ppTerm q d (R xs) = braces (fsep (punctuate ';' [l <+>
fsep [case mb_t of {Just t -> ':' <+> ppTerm q 0 t; Nothing -> empty}, fsep [case mb_t of {Just t -> ':' <+> ppTerm q 0 t; Nothing -> empty},
'=' <+> ppTerm q 0 e] | (l,(mb_t,e)) <- xs])) '=' <+> ppTerm q 0 e] | (l,(mb_t,e)) <- xs]))
ppTerm q d (RecType xs) ppTerm q d (RecType xs)
| q == Terse = case [cat | (l,_) <- xs, let (p,cat) = splitAt 5 (showIdent (label2ident l)), p == "lock_"] of | q == Terse = case [cat | (l,_) <- xs, let (p,cat) = splitAt 5 (showIdent (label2ident l)), p == "lock_"] of
[cat] -> pp cat [cat] -> pp cat
_ -> doc _ -> doc
| otherwise = doc | otherwise = doc
where where
doc = braces (fsep (punctuate ';' [l <+> ':' <+> ppTerm q 0 t | (l,t) <- xs])) doc = braces (fsep (punctuate ';' [l <+> ':' <+> ppTerm q 0 t | (l,t) <- xs]))
ppTerm q d (Typed e t) = '<' <> ppTerm q 0 e <+> ':' <+> ppTerm q 0 t <> '>' ppTerm q d (Typed e t) = '<' <> ppTerm q 0 e <+> ':' <+> ppTerm q 0 t <> '>'
ppTerm q d (ImplArg e) = braces (ppTerm q 0 e) ppTerm q d (ImplArg e) = braces (ppTerm q 0 e)
ppTerm q d (ELincat cat t) = prec d 4 ("lincat" <+> cat <+> ppTerm q 5 t) ppTerm q d (ELincat cat t) = prec d 4 ("lincat" <+> cat <+> ppTerm q 5 t)
ppTerm q d (ELin cat t) = prec d 4 ("lin" <+> cat <+> ppTerm q 5 t) ppTerm q d (ELin cat t) = prec d 4 ("lin" <+> cat <+> ppTerm q 5 t)
ppTerm q d (Error s) = prec d 4 ("Predef.error" <+> str s) ppTerm q d (Error s) = prec d 4 ("Predef.error" <+> str s)
ppEquation q (ps,e) = hcat (map (ppPatt q 2) ps) <+> "->" <+> ppTerm q 0 e ppEquation q (ps,e) = hcat (map (ppPatt q 2) ps) <+> "->" <+> ppTerm q 0 e
ppCase q (p,e) = ppPatt q 0 p <+> "=>" <+> ppTerm q 0 e ppCase q (p,e) = ppPatt q 0 p <+> "=>" <+> ppTerm q 0 e
instance Pretty Patt where pp = ppPatt Unqualified 0 instance Pretty Patt where pp = ppPatt Unqualified 0
ppPatt q d (PAlt p1 p2) = prec d 0 (ppPatt q 0 p1 <+> '|' <+> ppPatt q 1 p2) ppPatt q d (PAlt p1 p2) = prec d 0 (ppPatt q 0 p1 <+> '|' <+> ppPatt q 1 p2)
ppPatt q d (PSeq p1 p2) = prec d 0 (ppPatt q 0 p1 <+> '+' <+> ppPatt q 1 p2) ppPatt q d (PSeq p1 p2) = prec d 0 (ppPatt q 0 p1 <+> '+' <+> ppPatt q 1 p2)
ppPatt q d (PMSeq (_,p1) (_,p2)) = prec d 0 (ppPatt q 0 p1 <+> '+' <+> ppPatt q 1 p2) ppPatt q d (PMSeq (_,p1) (_,p2)) = prec d 0 (ppPatt q 0 p1 <+> '+' <+> ppPatt q 1 p2)
ppPatt q d (PC f ps) = if null ps ppPatt q d (PC f ps) = if null ps
then pp f then pp f
else prec d 1 (f <+> hsep (map (ppPatt q 3) ps)) else prec d 1 (f <+> hsep (map (ppPatt q 3) ps))
ppPatt q d (PP f ps) = if null ps ppPatt q d (PP f ps) = if null ps
then ppQIdent q f then ppQIdent q f
else prec d 1 (ppQIdent q f <+> hsep (map (ppPatt q 3) ps)) else prec d 1 (ppQIdent q f <+> hsep (map (ppPatt q 3) ps))
ppPatt q d (PRep p) = prec d 1 (ppPatt q 3 p <> '*') ppPatt q d (PRep p) = prec d 1 (ppPatt q 3 p <> '*')
ppPatt q d (PAs f p) = prec d 2 (f <> '@' <> ppPatt q 3 p) ppPatt q d (PAs f p) = prec d 2 (f <> '@' <> ppPatt q 3 p)
ppPatt q d (PNeg p) = prec d 2 ('-' <> ppPatt q 3 p) ppPatt q d (PNeg p) = prec d 2 ('-' <> ppPatt q 3 p)
ppPatt q d (PChar) = pp '?' ppPatt q d (PChar) = pp '?'
ppPatt q d (PChars s) = brackets (str s) ppPatt q d (PChars s) = brackets (str s)
ppPatt q d (PMacro id) = '#' <> id ppPatt q d (PMacro id) = '#' <> id
ppPatt q d (PM id) = '#' <> ppQIdent q id ppPatt q d (PM id) = '#' <> ppQIdent q id
ppPatt q d PW = pp '_' ppPatt q d PW = pp '_'
ppPatt q d (PV id) = pp id ppPatt q d (PV id) = pp id
ppPatt q d (PInt n) = pp n ppPatt q d (PInt n) = pp n
ppPatt q d (PFloat f) = pp f ppPatt q d (PFloat f) = pp f
ppPatt q d (PString s) = str s ppPatt q d (PString s) = str s
ppPatt q d (PR xs) = braces (hsep (punctuate ';' [l <+> '=' <+> ppPatt q 0 e | (l,e) <- xs])) ppPatt q d (PR xs) = braces (hsep (punctuate ';' [l <+> '=' <+> ppPatt q 0 e | (l,e) <- xs]))
ppPatt q d (PImplArg p) = braces (ppPatt q 0 p) ppPatt q d (PImplArg p) = braces (ppPatt q 0 p)
ppPatt q d (PTilde t) = prec d 2 ('~' <> ppTerm q 6 t) ppPatt q d (PTilde t) = prec d 2 ('~' <> ppTerm q 6 t)
ppValue :: TermPrintQual -> Int -> Val -> Doc ppValue :: TermPrintQual -> Int -> Val -> Doc
ppValue q d (VGen i x) = x <> "{-" <> i <> "-}" ---- latter part for debugging ppValue q d (VGen i x) = x <> "{-" <> i <> "-}" ---- latter part for debugging
ppValue q d (VApp u v) = prec d 4 (ppValue q 4 u <+> ppValue q 5 v) ppValue q d (VApp u v) = prec d 4 (ppValue q 4 u <+> ppValue q 5 v)
ppValue q d (VCn (_,c)) = pp c ppValue q d (VCn (_,c)) = pp c
ppValue q d (VClos env e) = case e of ppValue q d (VClos env e) = case e of
Meta _ -> ppTerm q d e <> ppEnv env Meta _ -> ppTerm q d e <> ppEnv env
_ -> ppTerm q d e ---- ++ prEnv env ---- for debugging _ -> ppTerm q d e ---- ++ prEnv env ---- for debugging
ppValue q d (VRecType xs) = braces (hsep (punctuate ',' [l <> '=' <> ppValue q 0 v | (l,v) <- xs])) ppValue q d (VRecType xs) = braces (hsep (punctuate ',' [l <> '=' <> ppValue q 0 v | (l,v) <- xs]))
ppValue q d VType = pp "Type" ppValue q d VType = pp "Type"
ppConstrs :: Constraints -> [Doc] ppConstrs :: Constraints -> [Doc]
ppConstrs = map (\(v,w) -> braces (ppValue Unqualified 0 v <+> "<>" <+> ppValue Unqualified 0 w)) ppConstrs = map (\(v,w) -> braces (ppValue Unqualified 0 v <+> "<>" <+> ppValue Unqualified 0 w))
ppEnv :: Env -> Doc ppEnv :: Env -> Doc
ppEnv e = hcat (map (\(x,t) -> braces (x <> ":=" <> ppValue Unqualified 0 t)) e) ppEnv e = hcat (map (\(x,t) -> braces (x <> ":=" <> ppValue Unqualified 0 t)) e)
str s = doubleQuotes s str s = doubleQuotes s
ppDecl q (_,id,typ) ppDecl q (_,id,typ)
| id == identW = ppTerm q 3 typ | id == identW = ppTerm q 3 typ
| otherwise = parens (id <+> ':' <+> ppTerm q 0 typ) | otherwise = parens (id <+> ':' <+> ppTerm q 0 typ)
ppDDecl q (_,id,typ) ppDDecl q (_,id,typ)
| id == identW = ppTerm q 6 typ | id == identW = ppTerm q 6 typ
| otherwise = parens (id <+> ':' <+> ppTerm q 0 typ) | otherwise = parens (id <+> ':' <+> ppTerm q 0 typ)
ppQIdent :: TermPrintQual -> QIdent -> Doc ppQIdent :: TermPrintQual -> QIdent -> Doc
ppQIdent q (m,id) = ppQIdent q (m,id) =
case q of case q of
Terse -> pp id Terse -> pp id
Unqualified -> pp id Unqualified -> pp id
Qualified -> m <> '.' <> id Qualified -> m <> '.' <> id
Internal -> m <> '.' <> id Internal -> m <> '.' <> id
instance Pretty Label where pp = pp . label2ident instance Pretty Label where pp = pp . label2ident
ppOpenSpec (OSimple id) = pp id ppOpenSpec (OSimple id) = pp id
ppOpenSpec (OQualif id n) = parens (id <+> '=' <+> n) ppOpenSpec (OQualif id n) = parens (id <+> '=' <+> n)
ppInstSpec (id,n) = parens (id <+> '=' <+> n) ppInstSpec (id,n) = parens (id <+> '=' <+> n)
ppLocDef q (id, (mbt, e)) = ppLocDef q (id, (mbt, e)) =
id <+> id <+>
(case mbt of {Just t -> ':' <+> ppTerm q 0 t; Nothing -> empty} <+> '=' <+> ppTerm q 0 e) <+> ';' (case mbt of {Just t -> ':' <+> ppTerm q 0 t; Nothing -> empty} <+> '=' <+> ppTerm q 0 e) <+> ';'
ppBind (Explicit,v) = pp v ppBind (Explicit,v) = pp v
ppBind (Implicit,v) = braces v ppBind (Implicit,v) = braces v
ppAltern q (x,y) = ppTerm q 0 x <+> '/' <+> ppTerm q 0 y ppAltern q (x,y) = ppTerm q 0 x <+> '/' <+> ppTerm q 0 y
ppParams q ps = fsep (intersperse (pp '|') (map (ppParam q) ps)) ppParams q ps = fsep (intersperse (pp '|') (map (ppParam q) ps))
ppParam q (id,cxt) = id <+> hsep (map (ppDDecl q) cxt) ppParam q (id,cxt) = id <+> hsep (map (ppDDecl q) cxt)
ppProduction (Production fid funid args) = ppProduction (Production fid funid args) =
ppFId fid <+> "->" <+> ppFunId funid <> ppFId fid <+> "->" <+> ppFunId funid <>
brackets (hcat (punctuate "," (map (hsep . intersperse (pp '|') . map ppFId) args))) brackets (hcat (punctuate "," (map (hsep . intersperse (pp '|') . map ppFId) args)))
ppSequences q seqsArr ppSequences q seqsArr
| null seqs || q /= Internal = empty | null seqs || q /= Internal = empty
| otherwise = "sequences" <+> '{' $$ | otherwise = "sequences" <+> '{' $$
nest 2 (vcat (map ppSeq seqs)) $$ nest 2 (vcat (map ppSeq seqs)) $$
'}' '}'
where where
seqs = Array.assocs seqsArr seqs = Array.assocs seqsArr
commaPunct f ds = (hcat (punctuate "," (map f ds))) commaPunct f ds = (hcat (punctuate "," (map f ds)))
prec d1 d2 doc prec d1 d2 doc
| d1 > d2 = parens doc | d1 > d2 = parens doc
| otherwise = doc | otherwise = doc
getAbs :: Term -> ([(BindType,Ident)], Term) getAbs :: Term -> ([(BindType,Ident)], Term)
getAbs (Abs bt v e) = let (xs,e') = getAbs e getAbs (Abs bt v e) = let (xs,e') = getAbs e
in ((bt,v):xs,e') in ((bt,v):xs,e')
getAbs e = ([],e) getAbs e = ([],e)
getCTable :: Term -> ([Ident], Term) getCTable :: Term -> ([Ident], Term)
getCTable (T TRaw [(PV v,e)]) = let (vs,e') = getCTable e getCTable (T TRaw [(PV v,e)]) = let (vs,e') = getCTable e
in (v:vs,e') in (v:vs,e')
getCTable (T TRaw [(PW, e)]) = let (vs,e') = getCTable e getCTable (T TRaw [(PW, e)]) = let (vs,e') = getCTable e
in (identW:vs,e') in (identW:vs,e')
getCTable e = ([],e) getCTable e = ([],e)
getLet :: Term -> ([LocalDef], Term) getLet :: Term -> ([LocalDef], Term)
getLet (Let l e) = let (ls,e') = getLet e getLet (Let l e) = let (ls,e') = getLet e
in (l:ls,e') in (l:ls,e')
getLet e = ([],e) getLet e = ([],e)

View File

@@ -5,22 +5,23 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/21 16:22:32 $ -- > CVS $Date: 2005/04/21 16:22:32 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.7 $ -- > CVS $Revision: 1.7 $
-- --
-- (Description of the module) -- (Description of the module)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Grammar.Values (-- ** Values used in TC type checking module GF.Grammar.Values (
Val(..), Env, -- ** Values used in TC type checking
-- ** Annotated tree used in editing Val(..), Env,
-- ** Annotated tree used in editing
Binds, Constraints, MetaSubst, Binds, Constraints, MetaSubst,
-- ** For TC -- ** For TC
valAbsInt, valAbsFloat, valAbsString, vType, valAbsInt, valAbsFloat, valAbsString, vType,
isPredefCat, isPredefCat,
eType, eType,
) where ) where
import GF.Infra.Ident import GF.Infra.Ident
import GF.Grammar.Grammar import GF.Grammar.Grammar

View File

@@ -1,13 +1,34 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskell #-}
module GF.Infra.BuildInfo where module GF.Infra.BuildInfo where
import System.Info import System.Info
import Data.Version(showVersion) 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 #-} {-# NOINLINE buildInfo #-}
buildInfo = buildInfo =
"Built on "++os++"/"++arch "Built on "++os++"/"++arch
++" with "++compilerName++"-"++showVersion compilerVersion ++" with "++compilerName++"-"++showVersion compilerVersion ++ " at " ++ buildTime ++ "\nGit info: " ++ gitInfo
++", flags:" ++"\nFlags:"
#ifdef USE_INTERRUPT #ifdef USE_INTERRUPT
++" interrupt" ++" interrupt"
#endif #endif

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/21 16:22:33 $ -- > CVS $Date: 2005/04/21 16:22:33 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.5 $ -- > CVS $Revision: 1.5 $
-- --
@@ -14,10 +14,10 @@
module GF.Infra.CheckM module GF.Infra.CheckM
(Check, CheckResult, Message, runCheck, runCheck', (Check, CheckResult, Message, runCheck, runCheck',
checkError, checkCond, checkWarn, checkWarnings, checkAccumError, checkError, checkCond, checkWarn, checkWarnings, checkAccumError,
checkIn, checkInModule, checkMap, checkMapRecover, checkIn, checkInModule, checkMap, checkMapRecover,
parallelCheck, accumulateError, commitCheck, parallelCheck, accumulateError, commitCheck,
) where ) where
import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
import GF.Data.Operations import GF.Data.Operations
@@ -48,7 +48,7 @@ newtype Check a
instance Functor Check where fmap = liftM instance Functor Check where fmap = liftM
instance Monad Check where instance Monad Check where
return x = Check $ \{-ctxt-} ws -> (ws,Success x) return = pure
f >>= g = Check $ \{-ctxt-} ws -> f >>= g = Check $ \{-ctxt-} ws ->
case unCheck f {-ctxt-} ws of case unCheck f {-ctxt-} ws of
(ws,Success x) -> unCheck (g x) {-ctxt-} ws (ws,Success x) -> unCheck (g x) {-ctxt-} ws
@@ -58,7 +58,7 @@ instance Fail.MonadFail Check where
fail = raise fail = raise
instance Applicative Check where instance Applicative Check where
pure = return pure x = Check $ \{-ctxt-} ws -> (ws,Success x)
(<*>) = ap (<*>) = ap
instance ErrorMonad Check where instance ErrorMonad Check where
@@ -141,10 +141,10 @@ checkMapRecover f = fmap Map.fromList . parallelCheck . map f' . Map.toList
where f' (k,v) = fmap ((,)k) (f k v) where f' (k,v) = fmap ((,)k) (f k v)
{- {-
checkMapRecover f mp = do checkMapRecover f mp = do
let xs = map (\ (k,v) -> (k,runCheck (f k v))) (Map.toList mp) let xs = map (\ (k,v) -> (k,runCheck (f k v))) (Map.toList mp)
case [s | (_,Bad s) <- xs] of case [s | (_,Bad s) <- xs] of
ss@(_:_) -> checkError (text (unlines ss)) ss@(_:_) -> checkError (text (unlines ss))
_ -> do _ -> do
let (kx,ss) = unzip [((k,x),s) | (k, Ok (x,s)) <- xs] let (kx,ss) = unzip [((k,x),s) | (k, Ok (x,s)) <- xs]
if not (all null ss) then checkWarn (text (unlines ss)) else return () if not (all null ss) then checkWarn (text (unlines ss)) else return ()

View File

@@ -52,11 +52,11 @@ newtype SIO a = SIO {unS::PutStr->IO a}
instance Functor SIO where fmap = liftM instance Functor SIO where fmap = liftM
instance Applicative SIO where instance Applicative SIO where
pure = return pure x = SIO (const (pure x))
(<*>) = ap (<*>) = ap
instance Monad SIO where instance Monad SIO where
return x = SIO (const (return x)) return = pure
SIO m1 >>= xm2 = SIO $ \ h -> m1 h >>= \ x -> unS (xm2 x) h SIO m1 >>= xm2 = SIO $ \ h -> m1 h >>= \ x -> unS (xm2 x) h
instance Fail.MonadFail SIO where instance Fail.MonadFail SIO where

View File

@@ -32,15 +32,17 @@ import qualified Text.ParserCombinators.ReadP as RP
import System.Directory({-getCurrentDirectory,-}getAppUserDataDirectory) import System.Directory({-getCurrentDirectory,-}getAppUserDataDirectory)
import Control.Exception(SomeException,fromException,evaluate,try) import Control.Exception(SomeException,fromException,evaluate,try)
import Control.Monad.State hiding (void) import Control.Monad.State hiding (void)
import Control.Monad (join, when, (<=<))
import qualified GF.System.Signal as IO(runInterruptibly) import qualified GF.System.Signal as IO(runInterruptibly)
#ifdef SERVER_MODE #ifdef SERVER_MODE
import GF.Server(server) import GF.Server(server)
#endif #endif
import GF.Command.Messages(welcome) import GF.Command.Messages(welcome)
import GF.Infra.UseIO (Output) #if !(MIN_VERSION_base(4,9,0))
-- Provides an orphan instance of MonadFail for StateT in ghc versions < 8 -- Needed to make it compile on GHC < 8
import Control.Monad.Trans.Instances () import Control.Monad.Trans.Instances ()
#endif
-- | Run the GF Shell in quiet mode (@gf -run@). -- | Run the GF Shell in quiet mode (@gf -run@).
mainRunGFI :: Options -> [FilePath] -> IO () mainRunGFI :: Options -> [FilePath] -> IO ()
@@ -56,6 +58,7 @@ mainGFI opts files = do
shell opts files = flip evalStateT (emptyGFEnv opts) $ shell opts files = flip evalStateT (emptyGFEnv opts) $
do mapStateT runSIO $ importInEnv opts files do mapStateT runSIO $ importInEnv opts files
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
loop loop
#ifdef SERVER_MODE #ifdef SERVER_MODE
@@ -433,7 +436,7 @@ wc_type = cmd_name
x2 = takeWhile (\c -> isIdent c || isSpace c || c == '-' || c == '=' || c == '"') x1 x2 = takeWhile (\c -> isIdent c || isSpace c || c == '-' || c == '=' || c == '"') x1
cmd = case [x | (x,cs) <- RP.readP_to_S pCommand x2, all isSpace cs] of cmd = case [x | (x,cs) <- RP.readP_to_S pCommand x2, all isSpace cs] of
[x] -> Just x [x] -> Just x
_ -> Nothing _ -> Nothing
isIdent c = c == '_' || c == '\'' || isAlphaNum c isIdent c = c == '_' || c == '\'' || isAlphaNum c

View File

@@ -12,7 +12,7 @@ import GF.Command.Abstract
import GF.Command.Parse(readCommandLine,pCommand) import GF.Command.Parse(readCommandLine,pCommand)
import GF.Data.Operations (Err(..)) import GF.Data.Operations (Err(..))
import GF.Data.Utilities(whenM,repeatM) import GF.Data.Utilities(whenM,repeatM)
import Control.Monad (join, when, (<=<))
import GF.Infra.UseIO(ioErrorText,putStrLnE) import GF.Infra.UseIO(ioErrorText,putStrLnE)
import GF.Infra.SIO import GF.Infra.SIO
import GF.Infra.Option import GF.Infra.Option
@@ -58,6 +58,7 @@ mainGFI opts files = do
shell opts files = flip evalStateT (emptyGFEnv opts) $ shell opts files = flip evalStateT (emptyGFEnv opts) $
do mapStateT runSIO $ importInEnv opts files do mapStateT runSIO $ importInEnv opts files
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
loop loop
{- {-
@@ -101,7 +102,7 @@ timeIt act =
-- | Optionally show how much CPU time was used to run an IO action -- | Optionally show how much CPU time was used to run an IO action
optionallyShowCPUTime :: (Monad m,MonadSIO m) => Options -> m a -> m a optionallyShowCPUTime :: (Monad m,MonadSIO m) => Options -> m a -> m a
optionallyShowCPUTime opts act optionallyShowCPUTime opts act
| not (verbAtLeast opts Normal) = act | not (verbAtLeast opts Normal) = act
| otherwise = do (dt,r) <- timeIt act | otherwise = do (dt,r) <- timeIt act
liftSIO $ putStrLnFlush $ show (dt `div` 1000000000) ++ " msec" liftSIO $ putStrLnFlush $ show (dt `div` 1000000000) ++ " msec"
@@ -358,7 +359,7 @@ wordCompletion gfenv (left,right) = do
CmplIdent _ pref CmplIdent _ pref
-> case mb_pgf of -> case mb_pgf of
Just pgf -> ret (length pref) Just pgf -> ret (length pref)
[Haskeline.simpleCompletion name [Haskeline.simpleCompletion name
| name <- C.functions pgf, | name <- C.functions pgf,
isPrefixOf pref name] isPrefixOf pref name]
_ -> ret (length pref) [] _ -> ret (length pref) []
@@ -369,7 +370,7 @@ wordCompletion gfenv (left,right) = do
cmdEnv = commandenv gfenv cmdEnv = commandenv gfenv
{- {-
optLang opts = valStrOpts "lang" (head $ Map.keys (concretes cmdEnv)) opts optLang opts = valStrOpts "lang" (head $ Map.keys (concretes cmdEnv)) opts
optType opts = optType opts =
let str = valStrOpts "cat" (H.showCId $ H.lookStartCat pgf) opts let str = valStrOpts "cat" (H.showCId $ H.lookStartCat pgf) opts
in case H.readType str of in case H.readType str of
Just ty -> ty Just ty -> ty
@@ -416,7 +417,7 @@ wc_type = cmd_name
option x y (c :cs) option x y (c :cs)
| isIdent c = option x y cs | isIdent c = option x y cs
| otherwise = cmd x cs | otherwise = cmd x cs
optValue x y ('"':cs) = str x y cs optValue x y ('"':cs) = str x y cs
optValue x y cs = cmd x cs optValue x y cs = cmd x cs
@@ -434,9 +435,9 @@ wc_type = cmd_name
where where
x1 = take (length x - length y - d) x x1 = take (length x - length y - d) x
x2 = takeWhile (\c -> isIdent c || isSpace c || c == '-' || c == '=' || c == '"') x1 x2 = takeWhile (\c -> isIdent c || isSpace c || c == '-' || c == '=' || c == '"') x1
cmd = case [x | (x,cs) <- RP.readP_to_S pCommand x2, all isSpace cs] of cmd = case [x | (x,cs) <- RP.readP_to_S pCommand x2, all isSpace cs] of
[x] -> Just x [x] -> Just x
_ -> Nothing _ -> Nothing
isIdent c = c == '_' || c == '\'' || isAlphaNum c isIdent c = c == '_' || c == '\'' || isAlphaNum c

View File

@@ -16,18 +16,21 @@ import Data.Version
import System.Directory import System.Directory
import System.Environment (getArgs) import System.Environment (getArgs)
import System.Exit import System.Exit
import GF.System.Console (setConsoleEncoding) import GHC.IO.Encoding
-- import GF.System.Console (setConsoleEncoding)
-- | Run the GF main program, taking arguments from the command line. -- | Run the GF main program, taking arguments from the command line.
-- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.) -- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.)
-- Run @gf --help@ for usage info. -- Run @gf --help@ for usage info.
main :: IO () main :: IO ()
main = do main = do
--setConsoleEncoding setLocaleEncoding utf8
-- setConsoleEncoding
uncurry mainOpts =<< getOptions uncurry mainOpts =<< getOptions
-- | Get and parse GF command line arguments. Fix relative paths. -- | Get and parse GF command line arguments. Fix relative paths.
-- Calls 'getArgs' and 'parseOptions'. -- Calls 'getArgs' and 'parseOptions'.
getOptions :: IO (Options, [FilePath])
getOptions = do getOptions = do
args <- getArgs args <- getArgs
case parseOptions args of case parseOptions args of
@@ -43,9 +46,12 @@ getOptions = do
-- the options it invokes 'mainGFC', 'mainGFI', 'mainRunGFI', 'mainServerGFI', -- the options it invokes 'mainGFC', 'mainGFI', 'mainRunGFI', 'mainServerGFI',
-- or it just prints version/usage info. -- or it just prints version/usage info.
mainOpts :: Options -> [FilePath] -> IO () mainOpts :: Options -> [FilePath] -> IO ()
mainOpts opts files = mainOpts opts files =
case flag optMode opts of case flag optMode opts of
ModeVersion -> putStrLn $ "Grammatical Framework (GF) version " ++ showVersion version ++ "\n" ++ buildInfo ModeVersion -> do datadir <- getDataDir
putStrLn $ "Grammatical Framework (GF) version " ++ showVersion version ++ "\n" ++
buildInfo ++ "\n" ++
"Shared folder: " ++ datadir
ModeHelp -> putStrLn helpMessage ModeHelp -> putStrLn helpMessage
ModeServer port -> GFI1.mainServerGFI opts port files ModeServer port -> GFI1.mainServerGFI opts port files
ModeCompiler -> mainGFC opts files ModeCompiler -> mainGFC opts files

View File

@@ -5,37 +5,37 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/11/10 16:43:44 $ -- > CVS $Date: 2005/11/10 16:43:44 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.16 $ -- > CVS $Revision: 1.16 $
-- --
-- A simple finite state network module. -- A simple finite state network module.
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Speech.FiniteState (FA(..), State, NFA, DFA, module GF.Speech.FiniteState (FA(..), State, NFA, DFA,
startState, finalStates, startState, finalStates,
states, transitions, states, transitions,
isInternal, isInternal,
newFA, newFA_, newFA, newFA_,
addFinalState, addFinalState,
newState, newStates, newState, newStates,
newTransition, newTransitions, newTransition, newTransitions,
insertTransitionWith, insertTransitionsWith, insertTransitionWith, insertTransitionsWith,
mapStates, mapTransitions, mapStates, mapTransitions,
modifyTransitions, modifyTransitions,
nonLoopTransitionsTo, nonLoopTransitionsFrom, nonLoopTransitionsTo, nonLoopTransitionsFrom,
loops, loops,
removeState, removeState,
oneFinalState, oneFinalState,
insertNFA, insertNFA,
onGraph, onGraph,
moveLabelsToNodes, removeTrivialEmptyNodes, moveLabelsToNodes, removeTrivialEmptyNodes,
minimize, minimize,
dfa2nfa, dfa2nfa,
unusedNames, renameStates, unusedNames, renameStates,
prFAGraphviz, faToGraphviz) where prFAGraphviz, faToGraphviz) where
import Data.List import Data.List
import Data.Maybe import Data.Maybe
--import Data.Map (Map) --import Data.Map (Map)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Set (Set) import Data.Set (Set)
@@ -98,13 +98,13 @@ newTransition f t l = onGraph (newEdge (f,t,l))
newTransitions :: [(n, n, b)] -> FA n a b -> FA n a b newTransitions :: [(n, n, b)] -> FA n a b -> FA n a b
newTransitions es = onGraph (newEdges es) newTransitions es = onGraph (newEdges es)
insertTransitionWith :: Eq n => insertTransitionWith :: Eq n =>
(b -> b -> b) -> (n, n, b) -> FA n a b -> FA n a b (b -> b -> b) -> (n, n, b) -> FA n a b -> FA n a b
insertTransitionWith f t = onGraph (insertEdgeWith f t) insertTransitionWith f t = onGraph (insertEdgeWith f t)
insertTransitionsWith :: Eq n => insertTransitionsWith :: Eq n =>
(b -> b -> b) -> [(n, n, b)] -> FA n a b -> FA n a b (b -> b -> b) -> [(n, n, b)] -> FA n a b -> FA n a b
insertTransitionsWith f ts fa = insertTransitionsWith f ts fa =
foldl' (flip (insertTransitionWith f)) fa ts foldl' (flip (insertTransitionWith f)) fa ts
mapStates :: (a -> c) -> FA n a b -> FA n c b mapStates :: (a -> c) -> FA n a b -> FA n c b
@@ -128,11 +128,11 @@ unusedNames (FA (Graph names _ _) _ _) = names
-- | Gets all incoming transitions to a given state, excluding -- | Gets all incoming transitions to a given state, excluding
-- transtions from the state itself. -- transtions from the state itself.
nonLoopTransitionsTo :: Eq n => n -> FA n a b -> [(n,b)] nonLoopTransitionsTo :: Eq n => n -> FA n a b -> [(n,b)]
nonLoopTransitionsTo s fa = nonLoopTransitionsTo s fa =
[(f,l) | (f,t,l) <- transitions fa, t == s && f /= s] [(f,l) | (f,t,l) <- transitions fa, t == s && f /= s]
nonLoopTransitionsFrom :: Eq n => n -> FA n a b -> [(n,b)] nonLoopTransitionsFrom :: Eq n => n -> FA n a b -> [(n,b)]
nonLoopTransitionsFrom s fa = nonLoopTransitionsFrom s fa =
[(t,l) | (f,t,l) <- transitions fa, f == s && t /= s] [(t,l) | (f,t,l) <- transitions fa, f == s && t /= s]
loops :: Eq n => n -> FA n a b -> [b] loops :: Eq n => n -> FA n a b -> [b]
@@ -145,7 +145,7 @@ renameStates :: Ord x => [y] -- ^ Infinite supply of new names
renameStates supply (FA g s fs) = FA (renameNodes newName rest g) s' fs' renameStates supply (FA g s fs) = FA (renameNodes newName rest g) s' fs'
where (ns,rest) = splitAt (length (nodes g)) supply where (ns,rest) = splitAt (length (nodes g)) supply
newNodes = Map.fromList (zip (map fst (nodes g)) ns) newNodes = Map.fromList (zip (map fst (nodes g)) ns)
newName n = Map.findWithDefault (error "FiniteState.newName") n newNodes newName n = Map.findWithDefault (error "FiniteState.newName") n newNodes
s' = newName s s' = newName s
fs' = map newName fs fs' = map newName fs
@@ -154,9 +154,9 @@ insertNFA :: NFA a -- ^ NFA to insert into
-> (State, State) -- ^ States to insert between -> (State, State) -- ^ States to insert between
-> NFA a -- ^ NFA to insert. -> NFA a -- ^ NFA to insert.
-> NFA a -> NFA a
insertNFA (FA g1 s1 fs1) (f,t) (FA g2 s2 fs2) insertNFA (FA g1 s1 fs1) (f,t) (FA g2 s2 fs2)
= FA (newEdges es g') s1 fs1 = FA (newEdges es g') s1 fs1
where where
es = (f,ren s2,Nothing):[(ren f2,t,Nothing) | f2 <- fs2] es = (f,ren s2,Nothing):[(ren f2,t,Nothing) | f2 <- fs2]
(g',ren) = mergeGraphs g1 g2 (g',ren) = mergeGraphs g1 g2
@@ -182,9 +182,9 @@ oneFinalState nl el fa =
moveLabelsToNodes :: (Ord n,Eq a) => FA n () (Maybe a) -> FA n (Maybe a) () moveLabelsToNodes :: (Ord n,Eq a) => FA n () (Maybe a) -> FA n (Maybe a) ()
moveLabelsToNodes = onGraph f moveLabelsToNodes = onGraph f
where f g@(Graph c _ _) = Graph c' ns (concat ess) where f g@(Graph c _ _) = Graph c' ns (concat ess)
where is = [ ((n,l),inc) | (n, (l,inc,_)) <- Map.toList (nodeInfo g)] where is = [ ((n,l),inc) | (n, (l,inc,_)) <- Map.toList (nodeInfo g)]
(c',is') = mapAccumL fixIncoming c is (c',is') = mapAccumL fixIncoming c is
(ns,ess) = unzip (concat is') (ns,ess) = unzip (concat is')
-- | Remove empty nodes which are not start or final, and have -- | Remove empty nodes which are not start or final, and have
@@ -196,12 +196,12 @@ removeTrivialEmptyNodes = pruneUnusable . skipSimpleEmptyNodes
-- This is not done if the pointed-to node is a final node. -- This is not done if the pointed-to node is a final node.
skipSimpleEmptyNodes :: (Eq a, Ord n) => FA n (Maybe a) () -> FA n (Maybe a) () skipSimpleEmptyNodes :: (Eq a, Ord n) => FA n (Maybe a) () -> FA n (Maybe a) ()
skipSimpleEmptyNodes fa = onGraph og fa skipSimpleEmptyNodes fa = onGraph og fa
where where
og g@(Graph c ns es) = if es' == es then g else og (Graph c ns es') og g@(Graph c ns es) = if es' == es then g else og (Graph c ns es')
where where
es' = concatMap changeEdge es es' = concatMap changeEdge es
info = nodeInfo g info = nodeInfo g
changeEdge e@(f,t,()) changeEdge e@(f,t,())
| isNothing (getNodeLabel info t) | isNothing (getNodeLabel info t)
-- && (i * o <= i + o) -- && (i * o <= i + o)
&& not (isFinal fa t) && not (isFinal fa t)
@@ -223,28 +223,28 @@ pruneUnusable fa = onGraph f fa
where where
f g = if Set.null rns then g else f (removeNodes rns g) f g = if Set.null rns then g else f (removeNodes rns g)
where info = nodeInfo g where info = nodeInfo g
rns = Set.fromList [ n | (n,_) <- nodes g, rns = Set.fromList [ n | (n,_) <- nodes g,
isInternal fa n, isInternal fa n,
inDegree info n == 0 inDegree info n == 0
|| outDegree info n == 0] || outDegree info n == 0]
fixIncoming :: (Ord n, Eq a) => [n] fixIncoming :: (Ord n, Eq a) => [n]
-> (Node n (),[Edge n (Maybe a)]) -- ^ A node and its incoming edges -> (Node n (),[Edge n (Maybe a)]) -- ^ A node and its incoming edges
-> ([n],[(Node n (Maybe a),[Edge n ()])]) -- ^ Replacement nodes with their -> ([n],[(Node n (Maybe a),[Edge n ()])]) -- ^ Replacement nodes with their
-- incoming edges. -- incoming edges.
fixIncoming cs c@((n,()),es) = (cs'', ((n,Nothing),es'):newContexts) fixIncoming cs c@((n,()),es) = (cs'', ((n,Nothing),es'):newContexts)
where ls = nub $ map edgeLabel es where ls = nub $ map edgeLabel es
(cs',cs'') = splitAt (length ls) cs (cs',cs'') = splitAt (length ls) cs
newNodes = zip cs' ls newNodes = zip cs' ls
es' = [ (x,n,()) | x <- map fst newNodes ] es' = [ (x,n,()) | x <- map fst newNodes ]
-- separate cyclic and non-cyclic edges -- separate cyclic and non-cyclic edges
(cyc,ncyc) = partition (\ (f,_,_) -> f == n) es (cyc,ncyc) = partition (\ (f,_,_) -> f == n) es
-- keep all incoming non-cyclic edges with the right label -- keep all incoming non-cyclic edges with the right label
to (x,l) = [ (f,x,()) | (f,_,l') <- ncyc, l == l'] to (x,l) = [ (f,x,()) | (f,_,l') <- ncyc, l == l']
-- for each cyclic edge with the right label, -- for each cyclic edge with the right label,
-- add an edge from each of the new nodes (including this one) -- add an edge from each of the new nodes (including this one)
++ [ (y,x,()) | (f,_,l') <- cyc, l == l', (y,_) <- newNodes] ++ [ (y,x,()) | (f,_,l') <- cyc, l == l', (y,_) <- newNodes]
newContexts = [ (v, to v) | v <- newNodes ] newContexts = [ (v, to v) | v <- newNodes ]
--alphabet :: Eq b => Graph n a (Maybe b) -> [b] --alphabet :: Eq b => Graph n a (Maybe b) -> [b]
--alphabet = nub . catMaybes . map edgeLabel . edges --alphabet = nub . catMaybes . map edgeLabel . edges
@@ -254,19 +254,19 @@ determinize (FA g s f) = let (ns,es) = h (Set.singleton start) Set.empty Set.emp
(ns',es') = (Set.toList ns, Set.toList es) (ns',es') = (Set.toList ns, Set.toList es)
final = filter isDFAFinal ns' final = filter isDFAFinal ns'
fa = FA (Graph undefined [(n,()) | n <- ns'] es') start final fa = FA (Graph undefined [(n,()) | n <- ns'] es') start final
in renameStates [0..] fa in renameStates [0..] fa
where info = nodeInfo g where info = nodeInfo g
-- reach = nodesReachable out -- reach = nodesReachable out
start = closure info $ Set.singleton s start = closure info $ Set.singleton s
isDFAFinal n = not (Set.null (Set.fromList f `Set.intersection` n)) isDFAFinal n = not (Set.null (Set.fromList f `Set.intersection` n))
h currentStates oldStates es h currentStates oldStates es
| Set.null currentStates = (oldStates,es) | Set.null currentStates = (oldStates,es)
| otherwise = ((h $! uniqueNewStates) $! allOldStates) $! es' | otherwise = ((h $! uniqueNewStates) $! allOldStates) $! es'
where where
allOldStates = oldStates `Set.union` currentStates allOldStates = oldStates `Set.union` currentStates
(newStates,es') = new (Set.toList currentStates) Set.empty es (newStates,es') = new (Set.toList currentStates) Set.empty es
uniqueNewStates = newStates Set.\\ allOldStates uniqueNewStates = newStates Set.\\ allOldStates
-- Get the sets of states reachable from the given states -- Get the sets of states reachable from the given states
-- by consuming one symbol, and the associated edges. -- by consuming one symbol, and the associated edges.
new [] rs es = (rs,es) new [] rs es = (rs,es)
new (n:ns) rs es = new ns rs' es' new (n:ns) rs es = new ns rs' es'
@@ -281,7 +281,7 @@ closure info x = closure_ x x
where closure_ acc check | Set.null check = acc where closure_ acc check | Set.null check = acc
| otherwise = closure_ acc' check' | otherwise = closure_ acc' check'
where where
reach = Set.fromList [y | x <- Set.toList check, reach = Set.fromList [y | x <- Set.toList check,
(_,y,Nothing) <- getOutgoing info x] (_,y,Nothing) <- getOutgoing info x]
acc' = acc `Set.union` reach acc' = acc `Set.union` reach
check' = reach Set.\\ acc check' = reach Set.\\ acc
@@ -296,8 +296,8 @@ reachable1 info ns = Map.fromListWith (++) [(c, [y]) | n <- Set.toList ns, (_,y,
reverseNFA :: NFA a -> NFA a reverseNFA :: NFA a -> NFA a
reverseNFA (FA g s fs) = FA g''' s' [s] reverseNFA (FA g s fs) = FA g''' s' [s]
where g' = reverseGraph g where g' = reverseGraph g
(g'',s') = newNode () g' (g'',s') = newNode () g'
g''' = newEdges [(s',f,Nothing) | f <- fs] g'' g''' = newEdges [(s',f,Nothing) | f <- fs] g''
dfa2nfa :: DFA a -> NFA a dfa2nfa :: DFA a -> NFA a
dfa2nfa = mapTransitions Just dfa2nfa = mapTransitions Just
@@ -313,13 +313,13 @@ prFAGraphviz = Dot.prGraphviz . faToGraphviz
--prFAGraphviz_ = Dot.prGraphviz . faToGraphviz . mapStates show . mapTransitions show --prFAGraphviz_ = Dot.prGraphviz . faToGraphviz . mapStates show . mapTransitions show
faToGraphviz :: (Eq n,Show n) => FA n String String -> Dot.Graph faToGraphviz :: (Eq n,Show n) => FA n String String -> Dot.Graph
faToGraphviz (FA (Graph _ ns es) s f) faToGraphviz (FA (Graph _ ns es) s f)
= Dot.Graph Dot.Directed Nothing [] (map mkNode ns) (map mkEdge es) [] = Dot.Graph Dot.Directed Nothing [] (map mkNode ns) (map mkEdge es) []
where mkNode (n,l) = Dot.Node (show n) attrs where mkNode (n,l) = Dot.Node (show n) attrs
where attrs = [("label",l)] where attrs = [("label",l)]
++ if n == s then [("shape","box")] else [] ++ if n == s then [("shape","box")] else []
++ if n `elem` f then [("style","bold")] else [] ++ if n `elem` f then [("style","bold")] else []
mkEdge (x,y,l) = Dot.Edge (show x) (show y) [("label",l)] mkEdge (x,y,l) = Dot.Edge (show x) (show y) [("label",l)]
-- --
-- * Utilities -- * Utilities

View File

@@ -26,14 +26,14 @@ width = 75
gslPrinter :: Options -> PGF -> CId -> String gslPrinter :: Options -> PGF -> CId -> String
gslPrinter opts pgf cnc = renderStyle st $ prGSL $ makeNonLeftRecursiveSRG opts pgf cnc gslPrinter opts pgf cnc = renderStyle st $ prGSL $ makeNonLeftRecursiveSRG opts pgf cnc
where st = style { lineLength = width } where st = style { lineLength = width }
prGSL :: SRG -> Doc prGSL :: SRG -> Doc
prGSL srg = header $++$ mainCat $++$ foldr ($++$) empty (map prRule (srgRules srg)) prGSL srg = header $++$ mainCat $++$ foldr ($++$) empty (map prRule (srgRules srg))
where where
header = ";GSL2.0" $$ header = ";GSL2.0" $$
comment ("Nuance speech recognition grammar for " ++ srgName srg) $$ comment ("Nuance speech recognition grammar for " ++ srgName srg) $$
comment ("Generated by GF") comment ("Generated by GF")
mainCat = ".MAIN" <+> prCat (srgStartCat srg) mainCat = ".MAIN" <+> prCat (srgStartCat srg)
prRule (SRGRule cat rhs) = prCat cat <+> union (map prAlt rhs) prRule (SRGRule cat rhs) = prCat cat <+> union (map prAlt rhs)
-- FIXME: use the probability -- FIXME: use the probability

View File

@@ -31,7 +31,7 @@ width :: Int
width = 75 width = 75
jsgfPrinter :: Options jsgfPrinter :: Options
-> PGF -> PGF
-> CId -> String -> CId -> String
jsgfPrinter opts pgf cnc = renderStyle st $ prJSGF sisr $ makeNonLeftRecursiveSRG opts pgf cnc jsgfPrinter opts pgf cnc = renderStyle st $ prJSGF sisr $ makeNonLeftRecursiveSRG opts pgf cnc
where st = style { lineLength = width } where st = style { lineLength = width }
@@ -44,7 +44,7 @@ prJSGF sisr srg
header = "#JSGF" <+> "V1.0" <+> "UTF-8" <+> lang <> ';' $$ header = "#JSGF" <+> "V1.0" <+> "UTF-8" <+> lang <> ';' $$
comment ("JSGF speech recognition grammar for " ++ srgName srg) $$ comment ("JSGF speech recognition grammar for " ++ srgName srg) $$
comment "Generated by GF" $$ comment "Generated by GF" $$
("grammar " ++ srgName srg ++ ";") ("grammar " ++ srgName srg ++ ";")
lang = maybe empty pp (srgLanguage srg) lang = maybe empty pp (srgLanguage srg)
mainCat = rule True "MAIN" [prCat (srgStartCat srg)] mainCat = rule True "MAIN" [prCat (srgStartCat srg)]
prRule (SRGRule cat rhs) = rule (isExternalCat srg cat) cat (map prAlt rhs) prRule (SRGRule cat rhs) = rule (isExternalCat srg cat) cat (map prAlt rhs)
@@ -62,7 +62,7 @@ prItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> Doc
prItem sisr t = f 0 prItem sisr t = f 0
where where
f _ (REUnion []) = pp "<VOID>" f _ (REUnion []) = pp "<VOID>"
f p (REUnion xs) f p (REUnion xs)
| not (null es) = brackets (f 0 (REUnion nes)) | not (null es) = brackets (f 0 (REUnion nes))
| otherwise = (if p >= 1 then parens else id) (alts (map (f 1) xs)) | otherwise = (if p >= 1 then parens else id) (alts (map (f 1) xs))
where (es,nes) = partition isEpsilon xs where (es,nes) = partition isEpsilon xs
@@ -110,4 +110,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
($++$) :: Doc -> Doc -> Doc ($++$) :: Doc -> Doc -> Doc
x $++$ y = x $$ emptyLine $$ y x $++$ y = x $$ emptyLine $$ y

View File

@@ -28,7 +28,7 @@ toBNF f pgf cnc = prCFG $ f $ pgfToCFG pgf cnc
type Profile = [Int] type Profile = [Int]
pgfToCFG :: PGF pgfToCFG :: PGF
-> CId -- ^ Concrete syntax name -> CId -- ^ Concrete syntax name
-> CFG -> CFG
pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ concatMap ruleToCFRule rules) pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ concatMap ruleToCFRule rules)
@@ -40,8 +40,8 @@ pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ co
, prod <- Set.toList set] , prod <- Set.toList set]
fcatCats :: Map FId Cat fcatCats :: Map FId Cat
fcatCats = Map.fromList [(fc, showCId c ++ "_" ++ show i) fcatCats = Map.fromList [(fc, showCId c ++ "_" ++ show i)
| (c,CncCat s e lbls) <- Map.toList (cnccats cnc), | (c,CncCat s e lbls) <- Map.toList (cnccats cnc),
(fc,i) <- zip (range (s,e)) [1..]] (fc,i) <- zip (range (s,e)) [1..]]
fcatCat :: FId -> Cat fcatCat :: FId -> Cat
@@ -58,7 +58,7 @@ pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ co
topdownRules cat = f cat [] topdownRules cat = f cat []
where where
f cat rules = maybe rules (Set.foldr g rules) (IntMap.lookup cat (productions cnc)) f cat rules = maybe rules (Set.foldr g rules) (IntMap.lookup cat (productions cnc))
g (PApply funid args) rules = (cncfuns cnc ! funid,args) : rules g (PApply funid args) rules = (cncfuns cnc ! funid,args) : rules
g (PCoerce cat) rules = f cat rules g (PCoerce cat) rules = f cat rules
@@ -67,13 +67,13 @@ pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ co
extCats = Set.fromList $ map ruleLhs startRules extCats = Set.fromList $ map ruleLhs startRules
startRules :: [CFRule] startRules :: [CFRule]
startRules = [Rule (showCId c) [NonTerminal (fcatToCat fc r)] (CFRes 0) startRules = [Rule (showCId c) [NonTerminal (fcatToCat fc r)] (CFRes 0)
| (c,CncCat s e lbls) <- Map.toList (cnccats cnc), | (c,CncCat s e lbls) <- Map.toList (cnccats cnc),
fc <- range (s,e), not (isPredefFId fc), fc <- range (s,e), not (isPredefFId fc),
r <- [0..catLinArity fc-1]] r <- [0..catLinArity fc-1]]
ruleToCFRule :: (FId,Production) -> [CFRule] ruleToCFRule :: (FId,Production) -> [CFRule]
ruleToCFRule (c,PApply funid args) = ruleToCFRule (c,PApply funid args) =
[Rule (fcatToCat c l) (mkRhs row) (profilesToTerm [fixProfile row n | n <- [0..length args-1]]) [Rule (fcatToCat c l) (mkRhs row) (profilesToTerm [fixProfile row n | n <- [0..length args-1]])
| (l,seqid) <- Array.assocs rhs | (l,seqid) <- Array.assocs rhs
, let row = sequences cnc ! seqid , let row = sequences cnc ! seqid
@@ -106,7 +106,7 @@ pgfToCFG pgf lang = mkCFG (showCId (lookStartCat pgf)) extCats (startRules ++ co
fixProfile row i = [k | (k,j) <- nts, j == i] fixProfile row i = [k | (k,j) <- nts, j == i]
where where
nts = zip [0..] [j | nt <- Array.elems row, j <- getPos nt] nts = zip [0..] [j | nt <- Array.elems row, j <- getPos nt]
getPos (SymCat j _) = [j] getPos (SymCat j _) = [j]
getPos (SymLit j _) = [j] getPos (SymLit j _) = [j]
getPos _ = [] getPos _ = []

View File

@@ -2,8 +2,8 @@
-- | -- |
-- Module : SRG -- Module : SRG
-- --
-- Representation of, conversion to, and utilities for -- Representation of, conversion to, and utilities for
-- printing of a general Speech Recognition Grammar. -- printing of a general Speech Recognition Grammar.
-- --
-- FIXME: remove \/ warn \/ fail if there are int \/ string literal -- FIXME: remove \/ warn \/ fail if there are int \/ string literal
-- categories in the grammar -- categories in the grammar
@@ -40,20 +40,20 @@ import qualified Data.Set as Set
--import Debug.Trace --import Debug.Trace
data SRG = SRG { srgName :: String -- ^ grammar name data SRG = SRG { srgName :: String -- ^ grammar name
, srgStartCat :: Cat -- ^ start category name , srgStartCat :: Cat -- ^ start category name
, srgExternalCats :: Set Cat , srgExternalCats :: Set Cat
, srgLanguage :: Maybe String -- ^ The language for which the grammar , srgLanguage :: Maybe String -- ^ The language for which the grammar
-- is intended, e.g. en-UK -- is intended, e.g. en-UK
, srgRules :: [SRGRule] , srgRules :: [SRGRule]
} }
deriving (Eq,Show) deriving (Eq,Show)
data SRGRule = SRGRule Cat [SRGAlt] data SRGRule = SRGRule Cat [SRGAlt]
deriving (Eq,Show) deriving (Eq,Show)
-- | maybe a probability, a rule name and an EBNF right-hand side -- | maybe a probability, a rule name and an EBNF right-hand side
data SRGAlt = SRGAlt (Maybe Double) CFTerm SRGItem data SRGAlt = SRGAlt (Maybe Double) CFTerm SRGItem
deriving (Eq,Show) deriving (Eq,Show)
type SRGItem = RE SRGSymbol type SRGItem = RE SRGSymbol
@@ -65,7 +65,7 @@ type SRGNT = (Cat, Int)
ebnfPrinter :: Options -> PGF -> CId -> String ebnfPrinter :: Options -> PGF -> CId -> String
ebnfPrinter opts pgf cnc = prSRG opts $ makeSRG opts pgf cnc ebnfPrinter opts pgf cnc = prSRG opts $ makeSRG opts pgf cnc
-- | Create a compact filtered non-left-recursive SRG. -- | Create a compact filtered non-left-recursive SRG.
makeNonLeftRecursiveSRG :: Options -> PGF -> CId -> SRG makeNonLeftRecursiveSRG :: Options -> PGF -> CId -> SRG
makeNonLeftRecursiveSRG opts = makeSRG opts' makeNonLeftRecursiveSRG opts = makeSRG opts'
where where
@@ -76,11 +76,11 @@ makeSRG opts = mkSRG cfgToSRG preprocess
where where
cfgToSRG cfg = [cfRulesToSRGRule rs | (_,rs) <- allRulesGrouped cfg] cfgToSRG cfg = [cfRulesToSRGRule rs | (_,rs) <- allRulesGrouped cfg]
preprocess = maybeTransform opts CFGMergeIdentical mergeIdentical preprocess = maybeTransform opts CFGMergeIdentical mergeIdentical
. maybeTransform opts CFGNoLR removeLeftRecursion . maybeTransform opts CFGNoLR removeLeftRecursion
. maybeTransform opts CFGRegular makeRegular . maybeTransform opts CFGRegular makeRegular
. maybeTransform opts CFGTopDownFilter topDownFilter . maybeTransform opts CFGTopDownFilter topDownFilter
. maybeTransform opts CFGBottomUpFilter bottomUpFilter . maybeTransform opts CFGBottomUpFilter bottomUpFilter
. maybeTransform opts CFGRemoveCycles removeCycles . maybeTransform opts CFGRemoveCycles removeCycles
. maybeTransform opts CFGStartCatOnly purgeExternalCats . maybeTransform opts CFGStartCatOnly purgeExternalCats
setDefaultCFGTransform :: Options -> CFGTransform -> Bool -> Options setDefaultCFGTransform :: Options -> CFGTransform -> Bool -> Options
@@ -95,7 +95,7 @@ stats g = "Categories: " ++ show (countCats g)
++ ", External categories: " ++ show (Set.size (cfgExternalCats g)) ++ ", External categories: " ++ show (Set.size (cfgExternalCats g))
++ ", Rules: " ++ show (countRules g) ++ ", Rules: " ++ show (countRules g)
-} -}
makeNonRecursiveSRG :: Options makeNonRecursiveSRG :: Options
-> PGF -> PGF
-> CId -- ^ Concrete syntax name. -> CId -- ^ Concrete syntax name.
-> SRG -> SRG
@@ -111,26 +111,26 @@ makeNonRecursiveSRG opts = mkSRG cfgToSRG id
mkSRG :: (CFG -> [SRGRule]) -> (CFG -> CFG) -> PGF -> CId -> SRG mkSRG :: (CFG -> [SRGRule]) -> (CFG -> CFG) -> PGF -> CId -> SRG
mkSRG mkRules preprocess pgf cnc = mkSRG mkRules preprocess pgf cnc =
SRG { srgName = showCId cnc, SRG { srgName = showCId cnc,
srgStartCat = cfgStartCat cfg, srgStartCat = cfgStartCat cfg,
srgExternalCats = cfgExternalCats cfg, srgExternalCats = cfgExternalCats cfg,
srgLanguage = languageCode pgf cnc, srgLanguage = languageCode pgf cnc,
srgRules = mkRules cfg } srgRules = mkRules cfg }
where cfg = renameCats (showCId cnc) $ preprocess $ pgfToCFG pgf cnc where cfg = renameCats (showCId cnc) $ preprocess $ pgfToCFG pgf cnc
-- | Renames all external cats C to C_cat, and all internal cats C_X (where X is any string), -- | Renames all external cats C to C_cat, and all internal cats C_X (where X is any string),
-- to C_N where N is an integer. -- to C_N where N is an integer.
renameCats :: String -> CFG -> CFG renameCats :: String -> CFG -> CFG
renameCats prefix cfg = mapCFGCats renameCat cfg renameCats prefix cfg = mapCFGCats renameCat cfg
where renameCat c | isExternal c = c ++ "_cat" where renameCat c | isExternal c = c ++ "_cat"
| otherwise = Map.findWithDefault (badCat c) c names | otherwise = Map.findWithDefault (badCat c) c names
isExternal c = c `Set.member` cfgExternalCats cfg isExternal c = c `Set.member` cfgExternalCats cfg
catsByPrefix = buildMultiMap [(takeWhile (/='_') cat, cat) | cat <- allCats' cfg, not (isExternal cat)] catsByPrefix = buildMultiMap [(takeWhile (/='_') cat, cat) | cat <- allCats' cfg, not (isExternal cat)]
names = Map.fromList [(c,pref++"_"++show i) | (pref,cs) <- catsByPrefix, (c,i) <- zip cs [1..]] names = Map.fromList [(c,pref++"_"++show i) | (pref,cs) <- catsByPrefix, (c,i) <- zip cs [1..]]
badCat c = error ("GF.Speech.SRG.renameCats: " ++ c ++ "\n" ++ prCFG cfg) badCat c = error ("GF.Speech.SRG.renameCats: " ++ c ++ "\n" ++ prCFG cfg)
cfRulesToSRGRule :: [CFRule] -> SRGRule cfRulesToSRGRule :: [CFRule] -> SRGRule
cfRulesToSRGRule rs@(r:_) = SRGRule (ruleLhs r) rhs cfRulesToSRGRule rs@(r:_) = SRGRule (ruleLhs r) rhs
where where
alts = [((n,Nothing),mkSRGSymbols 0 ss) | Rule c ss n <- rs] alts = [((n,Nothing),mkSRGSymbols 0 ss) | Rule c ss n <- rs]
rhs = [SRGAlt p n (srgItem sss) | ((n,p),sss) <- buildMultiMap alts ] rhs = [SRGAlt p n (srgItem sss) | ((n,p),sss) <- buildMultiMap alts ]
@@ -153,7 +153,7 @@ srgItem = unionRE . map mergeItems . sortGroupBy (compareBy filterCats)
-- non-optimizing version: -- non-optimizing version:
--srgItem = unionRE . map seqRE --srgItem = unionRE . map seqRE
-- | Merges a list of right-hand sides which all have the same -- | Merges a list of right-hand sides which all have the same
-- sequence of non-terminals. -- sequence of non-terminals.
mergeItems :: [[SRGSymbol]] -> SRGItem mergeItems :: [[SRGSymbol]] -> SRGItem
mergeItems = minimizeRE . ungroupTokens . minimizeRE . unionRE . map seqRE . map groupTokens mergeItems = minimizeRE . ungroupTokens . minimizeRE . unionRE . map seqRE . map groupTokens
@@ -174,16 +174,16 @@ ungroupTokens = joinRE . mapRE (symbol (RESymbol . NonTerminal) (REConcat . map
prSRG :: Options -> SRG -> String prSRG :: Options -> SRG -> String
prSRG opts srg = prProductions $ map prRule $ ext ++ int prSRG opts srg = prProductions $ map prRule $ ext ++ int
where where
sisr = flag optSISR opts sisr = flag optSISR opts
(ext,int) = partition (isExternalCat srg . srgLHSCat) (srgRules srg) (ext,int) = partition (isExternalCat srg . srgLHSCat) (srgRules srg)
prRule (SRGRule c alts) = (c,unwords (intersperse "|" (concatMap prAlt alts))) prRule (SRGRule c alts) = (c,unwords (intersperse "|" (concatMap prAlt alts)))
prAlt (SRGAlt _ t rhs) = prAlt (SRGAlt _ t rhs) =
-- FIXME: hack: we high-jack the --sisr flag to add -- FIXME: hack: we high-jack the --sisr flag to add
-- a simple lambda calculus format for semantic interpretation -- a simple lambda calculus format for semantic interpretation
-- Maybe the --sisr flag should be renamed. -- Maybe the --sisr flag should be renamed.
case sisr of case sisr of
Just _ -> Just _ ->
-- copy tags to each part of a top-level union, -- copy tags to each part of a top-level union,
-- to get simpler output -- to get simpler output
case rhs of case rhs of

View File

@@ -5,7 +5,7 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/11/01 20:09:04 $ -- > CVS $Date: 2005/11/01 20:09:04 $
-- > CVS $Author: bringert $ -- > CVS $Author: bringert $
-- > CVS $Revision: 1.16 $ -- > CVS $Revision: 1.16 $
-- --
@@ -38,7 +38,7 @@ width :: Int
width = 75 width = 75
srgsAbnfPrinter :: Options srgsAbnfPrinter :: Options
-> PGF -> CId -> String -> PGF -> CId -> String
srgsAbnfPrinter opts pgf cnc = showDoc $ prABNF sisr $ makeNonLeftRecursiveSRG opts pgf cnc srgsAbnfPrinter opts pgf cnc = showDoc $ prABNF sisr $ makeNonLeftRecursiveSRG opts pgf cnc
where sisr = flag optSISR opts where sisr = flag optSISR opts
@@ -72,7 +72,7 @@ prItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> Doc
prItem sisr t = f 0 prItem sisr t = f 0
where where
f _ (REUnion []) = pp "$VOID" f _ (REUnion []) = pp "$VOID"
f p (REUnion xs) f p (REUnion xs)
| not (null es) = brackets (f 0 (REUnion nes)) | not (null es) = brackets (f 0 (REUnion nes))
| otherwise = (if p >= 1 then parens else id) (alts (map (f 1) xs)) | otherwise = (if p >= 1 then parens else id) (alts (map (f 1) xs))
where (es,nes) = partition isEpsilon xs where (es,nes) = partition isEpsilon xs
@@ -84,13 +84,13 @@ prItem sisr t = f 0
prSymbol :: Maybe SISRFormat -> CFTerm -> SRGSymbol -> Doc prSymbol :: Maybe SISRFormat -> CFTerm -> SRGSymbol -> Doc
prSymbol sisr cn (NonTerminal n@(c,_)) = prCat c <+> tag sisr (catSISR cn n) prSymbol sisr cn (NonTerminal n@(c,_)) = prCat c <+> tag sisr (catSISR cn n)
prSymbol _ cn (Terminal t) prSymbol _ cn (Terminal t)
| all isPunct t = empty -- removes punctuation | all isPunct t = empty -- removes punctuation
| otherwise = pp t -- FIXME: quote if there is whitespace or odd chars | otherwise = pp t -- FIXME: quote if there is whitespace or odd chars
tag :: Maybe SISRFormat -> (SISRFormat -> SISRTag) -> Doc tag :: Maybe SISRFormat -> (SISRFormat -> SISRTag) -> Doc
tag Nothing _ = empty tag Nothing _ = empty
tag (Just fmt) t = tag (Just fmt) t =
case t fmt of case t fmt of
[] -> empty [] -> empty
-- grr, silly SRGS ABNF does not have an escaping mechanism -- grr, silly SRGS ABNF does not have an escaping mechanism
@@ -125,4 +125,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
($++$) :: Doc -> Doc -> Doc ($++$) :: Doc -> Doc -> Doc
x $++$ y = x $$ emptyLine $$ y x $++$ y = x $$ emptyLine $$ y

View File

@@ -34,13 +34,13 @@ prSrgsXml :: Maybe SISRFormat -> SRG -> String
prSrgsXml sisr srg = showXMLDoc (optimizeSRGS xmlGr) prSrgsXml sisr srg = showXMLDoc (optimizeSRGS xmlGr)
where where
xmlGr = grammar sisr (srgStartCat srg) (srgLanguage srg) $ xmlGr = grammar sisr (srgStartCat srg) (srgLanguage srg) $
[meta "description" [meta "description"
("SRGS XML speech recognition grammar for " ++ srgName srg ++ "."), ("SRGS XML speech recognition grammar for " ++ srgName srg ++ "."),
meta "generator" "Grammatical Framework"] meta "generator" "Grammatical Framework"]
++ map ruleToXML (srgRules srg) ++ map ruleToXML (srgRules srg)
ruleToXML (SRGRule cat alts) = Tag "rule" ([("id",cat)]++pub) (prRhs alts) ruleToXML (SRGRule cat alts) = Tag "rule" ([("id",cat)]++pub) (prRhs alts)
where pub = if isExternalCat srg cat then [("scope","public")] else [] where pub = if isExternalCat srg cat then [("scope","public")] else []
prRhs rhss = [oneOf (map (mkProd sisr) rhss)] prRhs rhss = [oneOf (map (mkProd sisr) rhss)]
mkProd :: Maybe SISRFormat -> SRGAlt -> XML mkProd :: Maybe SISRFormat -> SRGAlt -> XML
mkProd sisr (SRGAlt mp n rhs) = Tag "item" [] (ti ++ [x] ++ tf) mkProd sisr (SRGAlt mp n rhs) = Tag "item" [] (ti ++ [x] ++ tf)
@@ -50,9 +50,9 @@ mkProd sisr (SRGAlt mp n rhs) = Tag "item" [] (ti ++ [x] ++ tf)
mkItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> XML mkItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> XML
mkItem sisr cn = f mkItem sisr cn = f
where where
f (REUnion []) = ETag "ruleref" [("special","VOID")] f (REUnion []) = ETag "ruleref" [("special","VOID")]
f (REUnion xs) f (REUnion xs)
| not (null es) = Tag "item" [("repeat","0-1")] [f (REUnion nes)] | not (null es) = Tag "item" [("repeat","0-1")] [f (REUnion nes)]
| otherwise = oneOf (map f xs) | otherwise = oneOf (map f xs)
where (es,nes) = partition isEpsilon xs where (es,nes) = partition isEpsilon xs
@@ -62,7 +62,7 @@ mkItem sisr cn = f
f (RESymbol s) = symItem sisr cn s f (RESymbol s) = symItem sisr cn s
symItem :: Maybe SISRFormat -> CFTerm -> Symbol SRGNT Token -> XML symItem :: Maybe SISRFormat -> CFTerm -> Symbol SRGNT Token -> XML
symItem sisr cn (NonTerminal n@(c,_)) = symItem sisr cn (NonTerminal n@(c,_)) =
Tag "item" [] $ [ETag "ruleref" [("uri","#" ++ c)]] ++ tag sisr (catSISR cn n) Tag "item" [] $ [ETag "ruleref" [("uri","#" ++ c)]] ++ tag sisr (catSISR cn n)
symItem _ _ (Terminal t) = Tag "item" [] [Data (showToken t)] symItem _ _ (Terminal t) = Tag "item" [] [Data (showToken t)]
@@ -81,12 +81,12 @@ oneOf = Tag "one-of" []
grammar :: Maybe SISRFormat grammar :: Maybe SISRFormat
-> String -- ^ root -> String -- ^ root
-> Maybe String -- ^language -> Maybe String -- ^language
-> [XML] -> XML -> [XML] -> XML
grammar sisr root ml = grammar sisr root ml =
Tag "grammar" $ [("xmlns","http://www.w3.org/2001/06/grammar"), Tag "grammar" $ [("xmlns","http://www.w3.org/2001/06/grammar"),
("version","1.0"), ("version","1.0"),
("mode","voice"), ("mode","voice"),
("root",root)] ("root",root)]
++ (if isJust sisr then [("tag-format","semantics/1.0")] else []) ++ (if isJust sisr then [("tag-format","semantics/1.0")] else [])
++ maybe [] (\l -> [("xml:lang", l)]) ml ++ maybe [] (\l -> [("xml:lang", l)]) ml
@@ -94,7 +94,7 @@ meta :: String -> String -> XML
meta n c = ETag "meta" [("name",n),("content",c)] meta n c = ETag "meta" [("name",n),("content",c)]
optimizeSRGS :: XML -> XML optimizeSRGS :: XML -> XML
optimizeSRGS = bottomUpXML f optimizeSRGS = bottomUpXML f
where f (Tag "item" [] [x@(Tag "item" _ _)]) = x where f (Tag "item" [] [x@(Tag "item" _ _)]) = x
f (Tag "item" [] [x@(Tag "one-of" _ _)]) = x f (Tag "item" [] [x@(Tag "one-of" _ _)]) = x
f (Tag "item" as [Tag "item" [] xs]) = Tag "item" as xs f (Tag "item" as [Tag "item" [] xs]) = Tag "item" as xs

View File

@@ -38,7 +38,7 @@ decodeUnicode :: TextEncoding -> ByteString -> String
decodeUnicode enc bs = unsafePerformIO $ decodeUnicodeIO enc bs decodeUnicode enc bs = unsafePerformIO $ decodeUnicodeIO enc bs
decodeUnicodeIO enc (PS fptr l len) = do decodeUnicodeIO enc (PS fptr l len) = do
let bbuf = Buffer{bufRaw=fptr, bufState=ReadBuffer, bufSize=len, bufL=l, bufR=l+len} let bbuf = (emptyBuffer fptr len ReadBuffer) { bufL=l, bufR=l+len }
cbuf <- newCharBuffer 128 WriteBuffer cbuf <- newCharBuffer 128 WriteBuffer
case enc of case enc of
TextEncoding {mkTextDecoder=mk} -> do decoder <- mk TextEncoding {mkTextDecoder=mk} -> do decoder <- mk

View File

@@ -17,7 +17,7 @@ import qualified Data.Map as Map
-- to add a new one: define the Unicode range and the corresponding ASCII strings, -- to add a new one: define the Unicode range and the corresponding ASCII strings,
-- which may be one or more characters long -- which may be one or more characters long
-- conventions to be followed: -- conventions to be followed:
-- each character is either [letter] or [letter+nonletters] -- each character is either [letter] or [letter+nonletters]
-- when using a sparse range of unicodes, mark missing codes as "-" in transliterations -- when using a sparse range of unicodes, mark missing codes as "-" in transliterations
-- characters can be invisible: ignored in translation to unicode -- characters can be invisible: ignored in translation to unicode
@@ -33,7 +33,7 @@ transliterateWithFile name src isFrom =
(if isFrom then appTransFromUnicode else appTransToUnicode) (getTransliterationFile name src) (if isFrom then appTransFromUnicode else appTransToUnicode) (getTransliterationFile name src)
transliteration :: String -> Maybe Transliteration transliteration :: String -> Maybe Transliteration
transliteration s = Map.lookup s allTransliterations transliteration s = Map.lookup s allTransliterations
allTransliterations = Map.fromList [ allTransliterations = Map.fromList [
("amharic",transAmharic), ("amharic",transAmharic),
@@ -67,25 +67,25 @@ data Transliteration = Trans {
} }
appTransToUnicode :: Transliteration -> String -> String appTransToUnicode :: Transliteration -> String -> String
appTransToUnicode trans = appTransToUnicode trans =
concat . concat .
map (\c -> maybe c (return . toEnum) $ map (\c -> maybe c (return . toEnum) $
Map.lookup c (trans_to_unicode trans) Map.lookup c (trans_to_unicode trans)
) . ) .
filter (flip notElem (invisible_chars trans)) . filter (flip notElem (invisible_chars trans)) .
unchar unchar
appTransFromUnicode :: Transliteration -> String -> String appTransFromUnicode :: Transliteration -> String -> String
appTransFromUnicode trans = appTransFromUnicode trans =
concat . concat .
map (\c -> maybe [toEnum c] id $ map (\c -> maybe [toEnum c] id $
Map.lookup c (trans_from_unicode trans) Map.lookup c (trans_from_unicode trans)
) . ) .
map fromEnum map fromEnum
mkTransliteration :: String -> [String] -> [Int] -> Transliteration mkTransliteration :: String -> [String] -> [Int] -> Transliteration
mkTransliteration name ts us = mkTransliteration name ts us =
Trans (Map.fromList (tzip ts us)) (Map.fromList (uzip us ts)) [] name Trans (Map.fromList (tzip ts us)) (Map.fromList (uzip us ts)) [] name
where where
tzip ts us = [(t,u) | (t,u) <- zip ts us, t /= "-"] tzip ts us = [(t,u) | (t,u) <- zip ts us, t /= "-"]
@@ -102,7 +102,7 @@ getTransliterationFile name = uncurry (mkTransliteration name) . codes
unchar :: String -> [String] unchar :: String -> [String]
unchar s = case s of unchar s = case s of
c:d:cs c:d:cs
| isAlpha d -> [c] : unchar (d:cs) | isAlpha d -> [c] : unchar (d:cs)
| isSpace d -> [c]:[d]: unchar cs | isSpace d -> [c]:[d]: unchar cs
| otherwise -> let (ds,cs2) = break (\x -> isAlpha x || isSpace x) cs in | otherwise -> let (ds,cs2) = break (\x -> isAlpha x || isSpace x) cs in
@@ -122,8 +122,8 @@ transThai = mkTransliteration "Thai" allTrans allCodes where
allCodes = [0x0e00 .. 0x0e7f] allCodes = [0x0e00 .. 0x0e7f]
transDevanagari :: Transliteration transDevanagari :: Transliteration
transDevanagari = transDevanagari =
(mkTransliteration "Devanagari" (mkTransliteration "Devanagari"
allTransUrduHindi allCodes){invisible_chars = ["a"]} where allTransUrduHindi allCodes){invisible_chars = ["a"]} where
allCodes = [0x0900 .. 0x095f] ++ [0x0966 .. 0x096f] allCodes = [0x0900 .. 0x095f] ++ [0x0966 .. 0x096f]
@@ -136,13 +136,13 @@ allTransUrduHindi = words $
"- - - - - - - - q x g. z R R' f - " ++ "- - - - - - - - q x g. z R R' f - " ++
"N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 " "N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 "
transUrdu :: Transliteration transUrdu :: Transliteration
transUrdu = transUrdu =
(mkTransliteration "Urdu" allTrans allCodes) where (mkTransliteration "Urdu" allTrans allCodes) where
allCodes = [0x0622 .. 0x062f] ++ [0x0630 .. 0x063a] ++ [0x0641,0x0642] ++ [0x06A9] ++ [0x0644 .. 0x0648] ++ allCodes = [0x0622 .. 0x062f] ++ [0x0630 .. 0x063a] ++ [0x0641,0x0642] ++ [0x06A9] ++ [0x0644 .. 0x0648] ++
[0x0654,0x0658,0x0679,0x067e,0x0686,0x0688,0x0691,0x0698,0x06af,0x06c1,0x06c3,0x06cc,0x06ba,0x06be,0x06d2] ++ [0x0654,0x0658,0x0679,0x067e,0x0686,0x0688,0x0691,0x0698,0x06af,0x06c1,0x06c3,0x06cc,0x06ba,0x06be,0x06d2] ++
[0x06f0 .. 0x06f9] ++ [0x061f,0x06D4] [0x06f0 .. 0x06f9] ++ [0x061f,0x06D4]
allTrans = words $ allTrans = words $
"A - w^ - y^ a b - t C j H K d " ++ -- 0622 - 062f "A - w^ - y^ a b - t C j H K d " ++ -- 0622 - 062f
"Z r z s X S Z- t- z- e G " ++ -- 0630 - 063a "Z r z s X S Z- t- z- e G " ++ -- 0630 - 063a
@@ -151,22 +151,22 @@ transUrdu =
"N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 " ++ "? ." "N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 " ++ "? ."
transSindhi :: Transliteration transSindhi :: Transliteration
transSindhi = transSindhi =
(mkTransliteration "Sindhi" allTrans allCodes) where (mkTransliteration "Sindhi" allTrans allCodes) where
allCodes = [0x062e] ++ [0x0627 .. 0x062f] ++ [0x0630 .. 0x063a] ++ [0x0641 .. 0x0648] ++ allCodes = [0x062e] ++ [0x0627 .. 0x062f] ++ [0x0630 .. 0x063a] ++ [0x0641 .. 0x0648] ++
[0x067a,0x067b,0x067d,0x067e,0x067f] ++ [0x0680 .. 0x068f] ++ [0x067a,0x067b,0x067d,0x067e,0x067f] ++ [0x0680 .. 0x068f] ++
[0x0699,0x0918,0x06a6,0x061d,0x06a9,0x06af,0x06b3,0x06bb,0x06be,0x06f6,0x064a,0x06b1, 0x06aa, 0x06fd, 0x06fe] ++ [0x0699,0x0918,0x06a6,0x061d,0x06a9,0x06af,0x06b3,0x06bb,0x06be,0x06f6,0x064a,0x06b1, 0x06aa, 0x06fd, 0x06fe] ++
[0x06f0 .. 0x06f9] ++ [0x061f,0x06D4] [0x06f0 .. 0x06f9] ++ [0x061f,0x06D4]
allTrans = words $ allTrans = words $
"K a b - t C j H - d " ++ -- 0626 - 062f "K a b - t C j H - d " ++ -- 0626 - 062f
"Z r z s X S Z- t- z- e G " ++ -- 0630 - 063a "Z r z s X S Z- t- z- e G " ++ -- 0630 - 063a
"f q - L m n - W " ++ -- 0641 - 0648 "f q - L m n - W " ++ -- 0641 - 0648
"T! B T p T' " ++ -- 067a,067b,067d,067e,067f "T! B T p T' " ++ -- 067a,067b,067d,067e,067f
"B' - - Y' J' - c c' - - d! - d' D - D' " ++ -- 0680 - 068f "B' - - Y' J' - c c' - - d! - d' D - D' " ++ -- 0680 - 068f
"R - F' - k' g G' t' h' e' y c! k A M " ++ -- 0699, 0918, 06a6, 061d, 06a9,06af,06b3,06bb,06be,06f6,06cc,06b1 "R - F' - k' g G' t' h' e' y c! k A M " ++ -- 0699, 0918, 06a6, 061d, 06a9,06af,06b3,06bb,06be,06f6,06cc,06b1
"N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 " ++ "? ." "N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 " ++ "? ."
transArabic :: Transliteration transArabic :: Transliteration
transArabic = mkTransliteration "Arabic" allTrans allCodes where transArabic = mkTransliteration "Arabic" allTrans allCodes where
@@ -175,8 +175,8 @@ transArabic = mkTransliteration "Arabic" allTrans allCodes where
"W r z s C S D T Z c G " ++ -- 0630 - 063a "W r z s C S D T Z c G " ++ -- 0630 - 063a
" f q k l m n h w y. y a. u. i. a u " ++ -- 0641 - 064f " f q k l m n h w y. y a. u. i. a u " ++ -- 0641 - 064f
"i v2 o a: V+ V- i: a+ " ++ -- 0650 - 0657 "i v2 o a: V+ V- i: a+ " ++ -- 0650 - 0657
"A* q?" -- 0671 (used by AED) "A* q?" -- 0671 (used by AED)
allCodes = [0x0621..0x062f] ++ [0x0630..0x063a] ++ allCodes = [0x0621..0x062f] ++ [0x0630..0x063a] ++
[0x0641..0x064f] ++ [0x0650..0x0657] ++ [0x0671,0x061f] [0x0641..0x064f] ++ [0x0650..0x0657] ++ [0x0671,0x061f]
@@ -193,16 +193,16 @@ transPersian = (mkTransliteration "Persian/Farsi" allTrans allCodes)
" V A: A? w? A- y? A b t. t t- j H K d " ++ -- 0621 - 062f " V A: A? w? A- y? A b t. t t- j H K d " ++ -- 0621 - 062f
"W r z s C S D T Z c G " ++ -- 0630 - 063a "W r z s C S D T Z c G " ++ -- 0630 - 063a
" f q - l m n h v - y. a. u. i. a u " ++ -- 0640 - 064f " f q - l m n h v - y. a. u. i. a u " ++ -- 0640 - 064f
"i v2 o a: V+ V- i: a+ " ++ -- 0650 - 0657 "i v2 o a: V+ V- i: a+ " ++ -- 0650 - 0657
"p c^ J k g y q? Z0" "p c^ J k g y q? Z0"
allCodes = [0x0621..0x062f] ++ [0x0630..0x063a] ++ allCodes = [0x0621..0x062f] ++ [0x0630..0x063a] ++
[0x0641..0x064f] ++ [0x0650..0x0657] ++ [0x0641..0x064f] ++ [0x0650..0x0657] ++
[0x067e,0x0686,0x0698,0x06a9,0x06af,0x06cc,0x061f,0x200c] [0x067e,0x0686,0x0698,0x06a9,0x06af,0x06cc,0x061f,0x200c]
transNepali :: Transliteration transNepali :: Transliteration
transNepali = mkTransliteration "Nepali" allTrans allCodes where transNepali = mkTransliteration "Nepali" allTrans allCodes where
allTrans = words $ allTrans = words $
"z+ z= " ++ "z+ z= " ++
"- V M h: - H A i: I: f F Z - - - e: " ++ "- V M h: - H A i: I: f F Z - - - e: " ++
"E: - - O W k K g G n: C c j J Y q " ++ "E: - - O W k K g G n: C c j J Y q " ++
"Q x X N t T d D n - p P b B m y " ++ "Q x X N t T d D n - p P b B m y " ++
@@ -241,7 +241,7 @@ transGreek = mkTransliteration "modern Greek" allTrans allCodes where
"i= A B G D E Z H V I K L M N X O " ++ "i= A B G D E Z H V I K L M N X O " ++
"P R - S T Y F C Q W I- Y- a' e' h' i' " ++ "P R - S T Y F C Q W I- Y- a' e' h' i' " ++
"y= a b g d e z h v i k l m n x o " ++ "y= a b g d e z h v i k l m n x o " ++
"p r s* s t y f c q w i- y- o' y' w' - " "p r s* s t y f c q w i- y- o' y' w' - "
allCodes = [0x0380 .. 0x03cf] allCodes = [0x0380 .. 0x03cf]
transAncientGreek :: Transliteration transAncientGreek :: Transliteration
@@ -261,32 +261,32 @@ transAncientGreek = mkTransliteration "ancient Greek" allTrans allCodes where
"y) y( y)` y(` y)' y(' y)~ y(~ - Y( - Y(` - Y(' - Y(~ " ++ "y) y( y)` y(` y)' y(' y)~ y(~ - Y( - Y(` - Y(' - Y(~ " ++
"w) w( w)` w(` w)' w(' w)~ w(~ W) W( W)` W(` W)' W(' W)~ W(~ " ++ "w) w( w)` w(` w)' w(' w)~ w(~ W) W( W)` W(` W)' W(' W)~ W(~ " ++
"a` a' e` e' h` h' i` i' o` o' y` y' w` w' - - " ++ "a` a' e` e' h` h' i` i' o` o' y` y' w` w' - - " ++
"a|) a|( a|)` a|(` a|)' a|(' a|)~ a|(~ - - - - - - - - " ++ -- 1f80- "a|) a|( a|)` a|(` a|)' a|(' a|)~ a|(~ - - - - - - - - " ++ -- 1f80-
"h|) h|( h|)` h|(` h|)' h|(' h|)~ h|(~ - - - - - - - - " ++ -- 1f90- "h|) h|( h|)` h|(` h|)' h|(' h|)~ h|(~ - - - - - - - - " ++ -- 1f90-
"w|) w|( w|)` w|(` w|)' w|(' w|)~ w|(~ - - - - - - - - " ++ -- 1fa0- "w|) w|( w|)` w|(` w|)' w|(' w|)~ w|(~ - - - - - - - - " ++ -- 1fa0-
"a. a_ a|` a| a|' - a~ a|~ - - - - - - - - " ++ -- 1fb0- "a. a_ a|` a| a|' - a~ a|~ - - - - - - - - " ++ -- 1fb0-
"- - h|` h| h|' - h~ h|~ - - - - - - - - " ++ -- 1fc0- "- - h|` h| h|' - h~ h|~ - - - - - - - - " ++ -- 1fc0-
"i. i_ i=` i=' - - i~ i=~ - - - - - - - - " ++ -- 1fd0- "i. i_ i=` i=' - - i~ i=~ - - - - - - - - " ++ -- 1fd0-
"y. y_ y=` y=' r) r( y~ y=~ - - - - - - - - " ++ -- 1fe0- "y. y_ y=` y=' r) r( y~ y=~ - - - - - - - - " ++ -- 1fe0-
"- - w|` w| w|' - w~ w|~ - - - - - - - - " ++ -- 1ff0- "- - w|` w| w|' - w~ w|~ - - - - - - - - " ++ -- 1ff0-
-- HL, Private Use Area Code Points (New Athena Unicode, Cardo, ALPHABETUM, Antioch) -- HL, Private Use Area Code Points (New Athena Unicode, Cardo, ALPHABETUM, Antioch)
-- see: http://apagreekkeys.org/technicalDetails.html -- see: http://apagreekkeys.org/technicalDetails.html
-- GreekKeys Support by Donald Mastronarde -- GreekKeys Support by Donald Mastronarde
"- - - - - - - - - e. o. R) Y) Y)` Y)' Y)~ " ++ -- e1a0-e1af "- - - - - - - - - e. o. R) Y) Y)` Y)' Y)~ " ++ -- e1a0-e1af
"e~ e)~ e(~ e_ e_' e_` e_) e_( e_)` e_(` e_)' e_(' E)~ E(~ E_ E. " ++ -- e1b0-e1bf "e~ e)~ e(~ e_ e_' e_` e_) e_( e_)` e_(` e_)' e_(' E)~ E(~ E_ E. " ++ -- e1b0-e1bf
"o~ o)~ o(~ o_ o_' o_` o_) o_( o_)` o_(` o_)' o_(' O)~ O(~ O_ O. " ++ -- e1c0-e1cf "o~ o)~ o(~ o_ o_' o_` o_) o_( o_)` o_(` o_)' o_(' O)~ O(~ O_ O. " ++ -- e1c0-e1cf
"a_` - a_~ a_)` a_(` a_)~ a_(~ - a.` a.) a.)` a.(' a.(` - - - " ++ -- eaf0-eaff "a_` - a_~ a_)` a_(` a_)~ a_(~ - a.` a.) a.)` a.(' a.(` - - - " ++ -- eaf0-eaff
"a_' - - - a_) a_( - a_)' - a_(' a.' a.( a.)' - - - " ++ -- eb00-eb0f "a_' - - - a_) a_( - a_)' - a_(' a.' a.( a.)' - - - " ++ -- eb00-eb0f
"e_)~ e_(~ - - - - - e_~ - - - - - - - - " ++ -- eb20-eb2f "e_)~ e_(~ - - - - - e_~ - - - - - - - - " ++ -- eb20-eb2f
"- - - - - - i_~ - i_` i_' - - i_) i_)' i_( i_(' " ++ -- eb30-eb3f "- - - - - - i_~ - i_` i_' - - i_) i_)' i_( i_(' " ++ -- eb30-eb3f
"i.' i.) i.)' i.( i.` i.)` - i.(' i.(` - - - - - - - " ++ -- eb40-eb4f "i.' i.) i.)' i.( i.` i.)` - i.(' i.(` - - - - - - - " ++ -- eb40-eb4f
"- - - - i_)` i_(` - i_)~ i_(~ - o_~ o_)~ o_(~ - - - " ++ -- eb50-eb5f "- - - - i_)` i_(` - i_)~ i_(~ - o_~ o_)~ o_(~ - - - " ++ -- eb50-eb5f
"y_` " ++ -- eb6f "y_` " ++ -- eb6f
"y_~ y_)` - - - y_(` - y_)~ y_(~ - y_' - - y_) y_( y_)' " ++ -- eb70-eb7f "y_~ y_)` - - - y_(` - y_)~ y_(~ - y_' - - y_) y_( y_)' " ++ -- eb70-eb7f
"y_(' y.' y.( y.` y.) y.)' - - y.)` y.(' y.(` - - - - - " -- eb80-eb8f "y_(' y.' y.( y.` y.) y.)' - - y.)` y.(' y.(` - - - - - " -- eb80-eb8f
allCodes = -- [0x00B0 .. 0x00Bf] allCodes = -- [0x00B0 .. 0x00Bf]
[0x0380 .. 0x03cf] ++ [0x1f00 .. 0x1fff] [0x0380 .. 0x03cf] ++ [0x1f00 .. 0x1fff]
++ [0xe1a0 .. 0xe1af] ++ [0xe1a0 .. 0xe1af]
++ [0xe1b0 .. 0xe1bf] ++ [0xe1b0 .. 0xe1bf]
++ [0xe1c0 .. 0xe1cf] ++ [0xe1c0 .. 0xe1cf]
++ [0xeaf0 .. 0xeaff] ++ [0xeaf0 .. 0xeaff]
@@ -297,36 +297,34 @@ transAncientGreek = mkTransliteration "ancient Greek" allTrans allCodes where
++ [0xeb50 .. 0xeb5f] ++ [0xeb6f] ++ [0xeb50 .. 0xeb5f] ++ [0xeb6f]
++ [0xeb70 .. 0xeb7f] ++ [0xeb70 .. 0xeb7f]
++ [0xeb80 .. 0xeb8f] ++ [0xeb80 .. 0xeb8f]
transAmharic :: Transliteration transAmharic :: Transliteration
transAmharic = mkTransliteration "Amharic" allTrans allCodes where transAmharic = mkTransliteration "Amharic" allTrans allCodes where
allTrans = words $
allTrans = words $ " h. h- h' h( h) h h? h* l. l- l' l( l) l l? l* "++
" H. H- H' H( H) H H? H* m. m- m' m( m) m m? m* "++
" h. h- h' h( h) h h? h* l. l- l' l( l) l l? l* "++ " s. s- s' s( s) s s? s* r. r- r' r( r) r r? r* "++
" H. H- H' H( H) H H? H* m. m- m' m( m) m m? m* "++ " - - - - - - - - x. x- x' x( x) x x? x* "++
" s. s- s' s( s) s s? s* r. r- r' r( r) r r? r* "++ " q. q- q' q( q) q q? q* - - - - - - - - "++
" - - - - - - - - x. x- x' x( x) x x? x* "++ " - - - - - - - - - - - - - - - - "++
" q. q- q' q( q) q q? q* - - - - - - - - "++ " b. b- b' b( b) b b? b* v. v- v' v( v) v v? v* "++
" - - - - - - - - - - - - - - - - "++ " t. t- t' t( t) t t? t* c. c- c' c( c) c c? c* "++
" b. b- b' b( b) b b? b* v. v- v' v( v) v v? v* "++ " X. X- X' X( X) X X? - - - - X* - - - - "++
" t. t- t' t( t) t t? t* c. c- c' c( c) c c? c* "++ " n. n- n' n( n) n n? n* N. N- N' N( N) N N? N* "++
" X. X- X' X( X) X X? - - - - X* - - - - "++ " a u i A E e o e* k. k- k' k( k) k k? - "++
" n. n- n' n( n) n n? n* N. N- N' N( N) N N? N* "++ " - - - k* - - - - - - - - - - - - "++
" a u i A E e o e* k. k- k' k( k) k k? - "++ " - - - - - - - - w. w- w' w( w) w w? w* "++
" - - - k* - - - - - - - - - - - - "++ " - - - - - - - - z. z- z' z( z) z z? z* "++
" - - - - - - - - w. w- w' w( w) w w? w* "++ " Z. Z- Z' Z( Z) Z Z? Z* y. y- y' y( y) y y? y* "++
" - - - - - - - - z. z- z' z( z) z z? z* "++ " d. d- d' d( d) d d? d* - - - - - - - - "++
" Z. Z- Z' Z( Z) Z Z? Z* y. y- y' y( y) y y? y* "++ " j. j- j' j( j) j j? j* g. g- g' g( g) g g? - "++
" d. d- d' d( d) d d? d* - - - - - - - - "++ " - - - g* - - - - - - - - - - - - "++
" j. j- j' j( j) j j? j* g. g- g' g( g) g g? - "++ " T. T- T' T( T) T T? T* C. C- C' C( C) C C? C* "++
" - - - g* - - - - - - - - - - - - "++ " P. P- P' P( P) P P? P* S. S- S' S( S) S S? S* "++
" T. T- T' T( T) T T? T* C. C- C' C( C) C C? C* "++ " - - - - - - - - f. f- f' f( f) f f? f*"++
" P. P- P' P( P) P P? P* S. S- S' S( S) S S? S* "++ " p. p- p' p( p) p p? p*"
" - - - - - - - - f. f- f' f( f) f f? f*"++ allCodes = [0x1200..0x1357]
" p. p- p' p( p) p p? p*"
allCodes = [0x1200..0x1357]
-- by Prasad 31/5/2013 -- by Prasad 31/5/2013
transSanskrit :: Transliteration transSanskrit :: Transliteration
transSanskrit = (mkTransliteration "Sanskrit" allTrans allCodes) {invisible_chars = ["a"]} where transSanskrit = (mkTransliteration "Sanskrit" allTrans allCodes) {invisible_chars = ["a"]} where

View File

@@ -23,10 +23,10 @@ data Fun = Fun { fname:: FunId, ftype:: Type }
data Concrete = Concrete { langcode:: Id, data Concrete = Concrete { langcode:: Id,
opens:: [ModId], opens:: [ModId],
params:: [Param], params:: [Param],
lincats:: [Lincat], lincats:: [Lincat],
opers:: [Oper], opers:: [Oper],
lins:: [Lin] } lins:: [Lin] }
deriving Show deriving Show
data Param = Param {pname:: Id, prhs:: String} deriving Show data Param = Param {pname:: Id, prhs:: String} deriving Show

View File

@@ -1,3 +1,5 @@
module Main where
import qualified GF import qualified GF
main = GF.main main = GF.main

View File

@@ -14,6 +14,9 @@ For Linux users
You will need the packages: autoconf, automake, libtool, make You will need the packages: autoconf, automake, libtool, make
- On Ubuntu: $ apt-get install autotools-dev
- On Fedora: $ dnf install autoconf automake libtool
The compilation steps are: The compilation steps are:
$ autoreconf -i $ autoreconf -i
@@ -28,7 +31,7 @@ For Mac OSX users
The following is what I did to make it work on MacOSX 10.8: The following is what I did to make it work on MacOSX 10.8:
- Install XCode and XCode command line tools - Install XCode and XCode command line tools
- Install Homebrew: http://mxcl.github.com/homebrew/ - Install Homebrew: https://brew.sh
$ brew install automake autoconf libtool $ brew install automake autoconf libtool
$ glibtoolize $ glibtoolize
@@ -41,7 +44,7 @@ $ make install
For Windows users For Windows users
----------------- -----------------
- Install MinGW: http://www.mingw.org/. From the installer you need - Install MinGW: http://www.mingw-w64.org/. From the installer you need
to select at least the following packages: to select at least the following packages:
- Mingw-developer-toolkit - Mingw-developer-toolkit
- Mingw-base - Mingw-base
@@ -49,7 +52,7 @@ For Windows users
After the installation, don't forget to fix the fstab file. See here: After the installation, don't forget to fix the fstab file. See here:
http://www.mingw.org/wiki/Getting_Started http://www.mingw.org/wiki/Getting_Started
- From the MSYS shell (c:/MinGW/msys/1.0/msys.bat) go to the directory - From the MSYS shell (c:/MinGW/msys/1.0/msys.bat) go to the directory
which contains the INSTALL file and do: which contains the INSTALL file and do:
$ autoreconf -i $ autoreconf -i

View File

@@ -30,6 +30,7 @@ AM_PROG_CC_C_O
-Wall\ -Wall\
-Wextra\ -Wextra\
-Wno-missing-field-initializers\ -Wno-missing-field-initializers\
-fpermissive\
-Wno-unused-parameter\ -Wno-unused-parameter\
-Wno-unused-value" -Wno-unused-value"
fi] fi]
@@ -43,8 +44,10 @@ case "$target_cpu" in
[Define if lightning is targeting the sparc architecture]) ;; [Define if lightning is targeting the sparc architecture]) ;;
powerpc) cpu=ppc; AC_DEFINE(LIGHTNING_PPC, 1, powerpc) cpu=ppc; AC_DEFINE(LIGHTNING_PPC, 1,
[Define if lightning is targeting the powerpc architecture]) ;; [Define if lightning is targeting the powerpc architecture]) ;;
arm*) cpu=arm; AC_DEFINE(LIGHTNING_ARM, 1, arm*) cpu=arm; AC_DEFINE(LIGHTNING_ARM, 1,
[Define if lightning is targeting the arm architecture]) ;; [Define if lightning is targeting the arm architecture]) ;;
aarch64) cpu=aarch64; AC_DEFINE(LIGHTNING_AARCH64, 1,
[Define if lightning is targeting the aarch64 architecture]) ;;
*) AC_MSG_ERROR([cpu $target_cpu not supported]) ;; *) AC_MSG_ERROR([cpu $target_cpu not supported]) ;;
esac esac

View File

@@ -12,17 +12,17 @@ typedef void (*GuFn2)(GuFn* clo, void* arg1, void* arg2);
static inline void static inline void
gu_apply0(GuFn* fn) { gu_apply0(GuFn* fn) {
(*fn)(fn); ((GuFn0)(*fn))(fn);
} }
static inline void static inline void
gu_apply1(GuFn* fn, void* arg1) { gu_apply1(GuFn* fn, void* arg1) {
(*fn)(fn, arg1); ((GuFn1)(*fn))(fn, arg1);
} }
static inline void static inline void
gu_apply2(GuFn* fn, void* arg1, void* arg2) { gu_apply2(GuFn* fn, void* arg1, void* arg2) {
(*fn)(fn, arg1, arg2); ((GuFn2)(*fn))(fn, arg1, arg2);
} }
#define gu_apply(fn_, ...) \ #define gu_apply(fn_, ...) \

3
src/runtime/c/install.sh Executable file
View File

@@ -0,0 +1,3 @@
bash setup.sh configure
bash setup.sh build
bash setup.sh install

View File

@@ -4,10 +4,49 @@
#include <pgf/data.h> #include <pgf/data.h>
#include <pgf/reasoner.h> #include <pgf/reasoner.h>
#include <pgf/reader.h> #include <pgf/reader.h>
#if !defined(__aarch64__)
#include "lightning.h" #include "lightning.h"
#endif
//#define PGF_JIT_DEBUG //#define PGF_JIT_DEBUG
#if defined(EMSCRIPTEN) || defined(__aarch64__)
PGF_INTERNAL PgfJitState*
pgf_new_jit(PgfReader* rdr)
{
return NULL;
}
PGF_INTERNAL PgfEvalGates*
pgf_jit_gates(PgfReader* rdr)
{
PgfEvalGates* gates = gu_new(PgfEvalGates, rdr->opool);
memset(gates, 0, sizeof(*gates));
return gates;
}
PGF_INTERNAL void
pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
PgfAbsCat* abscat)
{
size_t n_funs = pgf_read_len(rdr);
gu_return_on_exn(rdr->err, );
for (size_t i = 0; i < n_funs; i++) {
gu_in_f64be(rdr->in, rdr->err); // ignore
gu_return_on_exn(rdr->err,);
pgf_read_cid(rdr, rdr->tmp_pool);
}
}
PGF_INTERNAL void
pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr)
{
}
#else
struct PgfJitState { struct PgfJitState {
jit_state jit; jit_state jit;
@@ -1329,3 +1368,5 @@ pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr)
jit_flush_code(rdr->jit_state->buf, jit_get_ip().ptr); jit_flush_code(rdr->jit_state->buf, jit_get_ip().ptr);
} }
#endif

View File

@@ -0,0 +1 @@
// DUMMY

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
// DUMMY

View File

@@ -44,6 +44,7 @@ typedef struct {
PgfParseState *before; PgfParseState *before;
PgfParseState *after; PgfParseState *after;
PgfToken prefix; PgfToken prefix;
bool prefix_bind;
PgfTokenProb* tp; PgfTokenProb* tp;
PgfExprEnum en; // enumeration for the generated trees/tokens PgfExprEnum en; // enumeration for the generated trees/tokens
#ifdef PGF_COUNTS_DEBUG #ifdef PGF_COUNTS_DEBUG
@@ -1009,6 +1010,7 @@ pgf_new_parse_state(PgfParsing* ps, size_t start_offset,
(start_offset == end_offset); (start_offset == end_offset);
state->start_offset = start_offset; state->start_offset = start_offset;
state->end_offset = end_offset; state->end_offset = end_offset;
state->viterbi_prob = viterbi_prob; state->viterbi_prob = viterbi_prob;
state->lexicon_idx = state->lexicon_idx =
gu_new_buf(PgfLexiconIdxEntry, ps->pool); gu_new_buf(PgfLexiconIdxEntry, ps->pool);
@@ -1381,20 +1383,30 @@ pgf_parsing_symbol(PgfParsing* ps, PgfItem* item, PgfSymbol sym)
break; break;
} }
case PGF_SYMBOL_BIND: { case PGF_SYMBOL_BIND: {
if (ps->before->start_offset == ps->before->end_offset && if (!ps->prefix_bind && ps->prefix != NULL && *(ps->sentence + ps->before->end_offset) == 0) {
ps->before->needs_bind) { PgfProductionApply* papp = gu_variant_data(item->prod);
PgfParseState* state =
pgf_new_parse_state(ps, ps->before->end_offset, BIND_HARD, ps->tp = gu_new(PgfTokenProb, ps->out_pool);
item->inside_prob+item->conts->outside_prob); ps->tp->tok = NULL;
if (state != NULL) { ps->tp->cat = item->conts->ccat->cnccat->abscat->name;
pgf_item_advance(item, ps->pool); ps->tp->fun = papp->fun->absfun->name;
gu_buf_heap_push(state->agenda, pgf_item_prob_order, &item); ps->tp->prob = item->inside_prob + item->conts->outside_prob;
} else { } else {
pgf_item_free(ps, item); if (ps->before->start_offset == ps->before->end_offset &&
} ps->before->needs_bind) {
} else { PgfParseState* state =
pgf_item_free(ps, item); pgf_new_parse_state(ps, ps->before->end_offset, BIND_HARD,
} item->inside_prob+item->conts->outside_prob);
if (state != NULL) {
pgf_item_advance(item, ps->pool);
gu_buf_heap_push(state->agenda, pgf_item_prob_order, &item);
} else {
pgf_item_free(ps, item);
}
} else {
pgf_item_free(ps, item);
}
}
break; break;
} }
case PGF_SYMBOL_SOFT_BIND: case PGF_SYMBOL_SOFT_BIND:
@@ -2337,7 +2349,8 @@ pgf_parser_completions_next(GuEnum* self, void* to, GuPool* pool)
PGF_API GuEnum* PGF_API GuEnum*
pgf_complete(PgfConcr* concr, PgfType* type, GuString sentence, pgf_complete(PgfConcr* concr, PgfType* type, GuString sentence,
GuString prefix, GuExn *err, GuPool* pool) GuString prefix, bool prefix_bind,
GuExn *err, GuPool* pool)
{ {
if (concr->sequences == NULL || if (concr->sequences == NULL ||
concr->cnccats == NULL) { concr->cnccats == NULL) {
@@ -2377,6 +2390,7 @@ pgf_complete(PgfConcr* concr, PgfType* type, GuString sentence,
// Now begin enumerating the completions // Now begin enumerating the completions
ps->en.next = pgf_parser_completions_next; ps->en.next = pgf_parser_completions_next;
ps->prefix = prefix; ps->prefix = prefix;
ps->prefix_bind = prefix_bind;
ps->tp = NULL; ps->tp = NULL;
return &ps->en; return &ps->en;
} }

View File

@@ -251,7 +251,8 @@ typedef struct {
PGF_API_DECL GuEnum* PGF_API_DECL GuEnum*
pgf_complete(PgfConcr* concr, PgfType* type, GuString string, pgf_complete(PgfConcr* concr, PgfType* type, GuString string,
GuString prefix, GuExn* err, GuPool* pool); GuString prefix, bool prefix_bind,
GuExn* err, GuPool* pool);
typedef struct PgfLiteralCallback PgfLiteralCallback; typedef struct PgfLiteralCallback PgfLiteralCallback;

View File

@@ -1026,7 +1026,10 @@ complete lang (Type ctype _) sent pfx =
touchConcr lang touchConcr lang
return [] return []
else do else do
tok <- peekUtf8CString =<< (#peek PgfTokenProb, tok) cmpEntry p_tok <- (#peek PgfTokenProb, tok) cmpEntry
tok <- if p_tok == nullPtr
then return "&+"
else peekUtf8CString p_tok
cat <- peekUtf8CString =<< (#peek PgfTokenProb, cat) cmpEntry cat <- peekUtf8CString =<< (#peek PgfTokenProb, cat) cmpEntry
fun <- peekUtf8CString =<< (#peek PgfTokenProb, fun) cmpEntry fun <- peekUtf8CString =<< (#peek PgfTokenProb, fun) cmpEntry
prob <- (#peek PgfTokenProb, prob) cmpEntry prob <- (#peek PgfTokenProb, prob) cmpEntry

Some files were not shown because too many files have changed in this diff Show More