This commit is contained in:
krangelov
2020-10-02 19:55:24 +02:00
40 changed files with 333 additions and 81 deletions

View File

@@ -0,0 +1,95 @@
# Based on the template here: https://kodimensional.dev/github-actions
name: Build with stack and cabal
# Trigger the workflow on push or pull request, but only for the master branch
on:
pull_request:
push:
branches: [master]
jobs:
cabal:
name: ${{ matrix.os }} / ghc ${{ matrix.ghc }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
cabal: ["3.2"]
ghc:
- "8.6.5"
- "8.8.3"
- "8.10.1"
exclude:
- os: macOS-latest
ghc: 8.8.3
- os: macOS-latest
ghc: 8.6.5
- os: windows-latest
ghc: 8.8.3
- os: windows-latest
ghc: 8.6.5
steps:
- uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- uses: actions/setup-haskell@v1.1.1
id: setup-haskell-cabal
name: Setup Haskell
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: ${{ matrix.cabal }}
- name: Freeze
run: |
cabal freeze
- uses: actions/cache@v1
name: Cache ~/.cabal/store
with:
path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
key: ${{ runner.os }}-${{ matrix.ghc }}
# key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
- name: Build
run: |
cabal configure --enable-tests --enable-benchmarks --test-show-details=direct
cabal build all
# - name: Test
# run: |
# cabal test all
stack:
name: stack / ghc ${{ matrix.ghc }}
runs-on: ubuntu-latest
strategy:
matrix:
stack: ["2.3.3"]
ghc: ["7.10.3","8.0.2", "8.2.2", "8.4.4", "8.6.5", "8.8.4"]
# ghc: ["8.8.3"]
steps:
- uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- uses: actions/setup-haskell@v1.1
name: Setup Haskell Stack
with:
# ghc-version: ${{ matrix.ghc }}
stack-version: ${{ matrix.stack }}
- uses: actions/cache@v1
name: Cache ~/.stack
with:
path: ~/.stack
key: ${{ runner.os }}-${{ matrix.ghc }}-stack
- name: Build
run: |
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml
# stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
# - name: Test
# run: |
# stack test --system-ghc

View File

@@ -18,6 +18,7 @@ jobs:
- name: Install build tools - name: Install build tools
run: | run: |
sudo apt update
sudo apt install -y \ sudo apt install -y \
make \ make \
dpkg-dev \ dpkg-dev \

1
.gitignore vendored
View File

@@ -6,6 +6,7 @@
*.gfo *.gfo
*.pgf *.pgf
dist/ dist/
dist-newstyle/
src/runtime/c/.libs/ src/runtime/c/.libs/
src/runtime/c/Makefile src/runtime/c/Makefile
src/runtime/c/Makefile.in src/runtime/c/Makefile.in

View File

@@ -19,7 +19,6 @@ main = defaultMainWithHooks simpleUserHooks
, preInst = gfPreInst , preInst = gfPreInst
, postInst = gfPostInst , postInst = gfPostInst
, postCopy = gfPostCopy , postCopy = gfPostCopy
, sDistHook = gfSDist
} }
where where
gfPreBuild args = gfPre args . buildDistPref gfPreBuild args = gfPre args . buildDistPref

View File

@@ -82,9 +82,10 @@ $body$
<li><a href="http://cloud.grammaticalframework.org/">GF Cloud</a></li> <li><a href="http://cloud.grammaticalframework.org/">GF Cloud</a></li>
<li> <li>
<a href="$rel-root$/doc/tutorial/gf-tutorial.html">Tutorial</a> <a href="$rel-root$/doc/tutorial/gf-tutorial.html">Tutorial</a>
/ ·
<a href="$rel-root$/lib/doc/rgl-tutorial/index.html">RGL Tutorial</a> <a href="$rel-root$/lib/doc/rgl-tutorial/index.html">RGL Tutorial</a>
</li> </li>
<li><a href="$rel-root$/doc/gf-video-tutorials.html">Video Tutorials</a></li>
<li><a href="$rel-root$/download"><strong>Download GF</strong></a></li> <li><a href="$rel-root$/download"><strong>Download GF</strong></a></li>
</ul> </ul>
</div> </div>

35
doc/gf-video-tutorials.md Normal file
View File

@@ -0,0 +1,35 @@
---
title: "Video tutorials"
---
The GF [YouTube channel](https://www.youtube.com/channel/UCZ96DechSUVcXAhtOId9VVA) keeps a playlist of [all GF videos](https://www.youtube.com/playlist?list=PLrgqBB5thLeT15fUtJ8_Dtk8ppdtH90MK), and more specific playlists for narrower topics.
If you make a video about GF, let us know and we'll add it to the suitable playlist(s)!
- [General introduction to GF](#general-introduction-to-gf)
- [Beginner resources](#beginner-resources)
- [Resource grammar tutorials](#resource-grammar-tutorials)
## General introduction to GF
These videos introduce GF at a high level, and present some use cases.
__Grammatical Framework: Formalizing the Grammars of the World__
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/x1LFbDQhbso" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
__Aarne Ranta: Automatic Translation for Consumers and Producers__
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/An-AmFScw1o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Beginner resources
These videos show how to install GF on your computer (Mac or Windows), and how to play with simple grammars in a [Jupyter notebook](https://github.com/GrammaticalFramework/gf-binder) (any platform, hosted at [mybinder.org](https://mybinder.org)).
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/videoseries?list=PLrgqBB5thLeRa8eViJJnjT8jBhxqCPMF2" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Resource grammar tutorials
These videos show incremental improvements to a [miniature version of the resource grammar](https://github.com/inariksit/comp-syntax-2020/tree/master/lab2/grammar/dummy#readme).
They assume some prior knowledge of GF, roughly lessons 1-3 from the [GF tutorial](http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html).
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/videoseries?list=PLrgqBB5thLeTPkp88lnOmRtprCa8g0wX2" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

View File

@@ -898,7 +898,7 @@ Parentheses are only needed for grouping.
Parsing something that is not in grammar will fail: Parsing something that is not in grammar will fail:
``` ```
> parse "hello dad" > parse "hello dad"
Unknown words: dad The parser failed at token 2: "dad"
> parse "world hello" > parse "world hello"
no tree found no tree found
@@ -2948,7 +2948,7 @@ We need the following combinations:
``` ```
We also need **lexical insertion**, to form phrases from single words: We also need **lexical insertion**, to form phrases from single words:
``` ```
mkCN : N -> NP ; mkCN : N -> CN ;
mkAP : A -> AP ; mkAP : A -> AP ;
``` ```
Naming convention: to construct a //C//, use a function ``mk``//C//. Naming convention: to construct a //C//, use a function ``mk``//C//.
@@ -2969,7 +2969,7 @@ can be built as follows:
``` ```
mkCl mkCl
(mkNP these_Det (mkNP these_Det
(mkCN (mkAP very_AdA (mkAP warm_A)) (mkCN pizza_CN))) (mkCN (mkAP very_AdA (mkAP warm_A)) (mkCN pizza_N)))
(mkAP italian_AP) (mkAP italian_AP)
``` ```
The task now: to define the concrete syntax of ``Foods`` so that The task now: to define the concrete syntax of ``Foods`` so that
@@ -3718,49 +3718,25 @@ Concrete syntax does not know if a category is a dependent type.
``` ```
Notice that the ``Kind`` argument is suppressed in linearization. Notice that the ``Kind`` argument is suppressed in linearization.
Parsing with dependent types is performed in two phases: Parsing with dependent types consists of two phases:
+ context-free parsing + context-free parsing
+ filtering through type checker + filtering through type checker
Parsing a type-correct command works as expected:
By just doing the first phase, the ``kind`` argument is not found:
``` ```
> parse "dim the light" > parse "dim the light"
CAction ? dim (DKindOne light)
```
Moreover, type-incorrect commands are not rejected:
```
> parse "dim the fan"
CAction ? dim (DKindOne fan)
```
The term ``?`` is a **metavariable**, returned by the parser
for any subtree that is suppressed by a linearization rule.
These are the same kind of metavariables as were used #Rsecediting
to mark incomplete parts of trees in the syntax editor.
#NEW
===Solving metavariables===
Use the command ``put_tree = pt`` with the option ``-typecheck``:
```
> parse "dim the light" | put_tree -typecheck
CAction light dim (DKindOne light) CAction light dim (DKindOne light)
``` ```
The ``typecheck`` process may fail, in which case an error message However, type-incorrect commands are rejected by the typecheck:
is shown and no tree is returned:
``` ```
> parse "dim the fan" | put_tree -typecheck > parse "dim the fan"
The parsing is successful but the type checking failed with error(s):
Error in tree UCommand (CAction ? 0 dim (DKindOne fan)) : Couldn't match expected type Device light
(? 0 <> fan) (? 0 <> light) against the interred type Device fan
In the expression: DKindOne fan
``` ```
#NEW #NEW
==Polymorphism== ==Polymorphism==
@@ -3786,23 +3762,19 @@ to express Haskell-type library functions:
\_,_,_,f,x,y -> f y x ; \_,_,_,f,x,y -> f y x ;
``` ```
#NEW #NEW
===Dependent types: exercises=== ===Dependent types: exercises===
1. Write an abstract syntax module with above contents 1. Write an abstract syntax module with above contents
and an appropriate English concrete syntax. Try to parse the commands and an appropriate English concrete syntax. Try to parse the commands
//dim the light// and //dim the fan//, with and without ``solve`` filtering. //dim the light// and //dim the fan//.
2. Perform random and exhaustive generation.
2. Perform random and exhaustive generation, with and without
``solve`` filtering.
3. Add some device kinds and actions to the grammar. 3. Add some device kinds and actions to the grammar.
#NEW #NEW
==Proof objects== ==Proof objects==
@@ -3912,7 +3884,6 @@ fun
Classes for new actions can be added incrementally. Classes for new actions can be added incrementally.
#NEW #NEW
==Variable bindings== ==Variable bindings==
@@ -4200,6 +4171,7 @@ We construct a calculator with addition, subtraction, multiplication, and
division of integers. division of integers.
``` ```
abstract Calculator = { abstract Calculator = {
flags startcat = Exp ;
cat Exp ; cat Exp ;
@@ -4226,7 +4198,7 @@ We begin with a
concrete syntax that always uses parentheses around binary concrete syntax that always uses parentheses around binary
operator applications: operator applications:
``` ```
concrete CalculatorP of Calculator = { concrete CalculatorP of Calculator = open Prelude in {
lincat lincat
Exp = SS ; Exp = SS ;

View File

@@ -82,6 +82,10 @@ Library
pretty, pretty,
mtl, mtl,
exceptions, exceptions,
fail,
-- For compatability with ghc < 8
-- We need transformers-compat >= 0.6.3, but that is only in newer snapshots where it is redundant.
transformers-compat,
ghc-prim ghc-prim
hs-source-dirs: src/runtime/haskell hs-source-dirs: src/runtime/haskell
@@ -98,8 +102,6 @@ Library
--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
if impl(ghc>=8.6)
Default-extensions: NoMonadFailDesugaring
exposed-modules: exposed-modules:
PGF PGF

View File

@@ -39,7 +39,7 @@
/ /
<a href="lib/doc/rgl-tutorial/index.html">RGL Tutorial</a> <a href="lib/doc/rgl-tutorial/index.html">RGL Tutorial</a>
</li> </li>
<li><a href="https://www.youtube.com/playlist?list=PL4L18Hhub0qFgLgFmzE4h-FxqemBcvWSW">Video Tutorial</a></li> <li><a href="doc/gf-video-tutorials.html">Video Tutorials</a></li>
</ul> </ul>
<a href="download/index.html" class="btn btn-primary ml-3"> <a href="download/index.html" class="btn btn-primary ml-3">
@@ -56,6 +56,7 @@
<li><a href="doc/gf-refman.html">Reference Manual</a></li> <li><a href="doc/gf-refman.html">Reference Manual</a></li>
<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>
</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">
@@ -173,6 +174,7 @@ least one, it may help you to get a first idea of what GF is.
<li>macOS</li> <li>macOS</li>
<li>Windows</li> <li>Windows</li>
<li>Android mobile platform (via Java; runtime)</li> <li>Android mobile platform (via Java; runtime)</li>
<li>iOS mobile platform (iPhone, iPad)</li>
<li>via compilation to JavaScript, almost any platform that has a web browser (runtime)</li> <li>via compilation to JavaScript, almost any platform that has a web browser (runtime)</li>
</ul> </ul>
@@ -226,6 +228,10 @@ least one, it may help you to get a first idea of what GF is.
<h2>News</h2> <h2>News</h2>
<dl class="row"> <dl class="row">
<dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt>
<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.
</dd>
<dt class="col-sm-3 text-center text-nowrap">2020-03-29</dt> <dt class="col-sm-3 text-center text-nowrap">2020-03-29</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
<a href="//school.grammaticalframework.org/2020/">Seventh GF Summer School</a> in Singapore has been postponed because of the corona pandemic. <a href="//school.grammaticalframework.org/2020/">Seventh GF Summer School</a> in Singapore has been postponed because of the corona pandemic.

View File

@@ -34,6 +34,7 @@ import Data.Maybe
import qualified Data.Map as Map import qualified Data.Map as Map
import GF.Text.Pretty import GF.Text.Pretty
import Data.List (sort) import Data.List (sort)
import qualified Control.Monad.Fail as Fail
--import Debug.Trace --import Debug.Trace
@@ -44,7 +45,7 @@ pgfEnv pgf = Env pgf mos
class (Functor m,Monad m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv class (Functor m,Monad m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv
instance (Monad m,HasPGFEnv m) => TypeCheckArg m where instance (Monad m,HasPGFEnv m,Fail.MonadFail m) => TypeCheckArg m where
typeCheckArg e = (either (fail . render . ppTcError) (return . fst) typeCheckArg e = (either (fail . render . ppTcError) (return . fst)
. flip inferExpr e . pgf) =<< getPGFEnv . flip inferExpr e . pgf) =<< getPGFEnv

View File

@@ -18,6 +18,7 @@ import Data.Maybe
import qualified Data.Map as Map import qualified Data.Map as Map
import GF.Text.Pretty import GF.Text.Pretty
import Control.Monad(mplus) import Control.Monad(mplus)
import qualified Control.Monad.Fail as Fail
data PGFEnv = Env {pgf::Maybe PGF,concs::Map.Map ConcName Concr} data PGFEnv = Env {pgf::Maybe PGF,concs::Map.Map ConcName Concr}
@@ -25,7 +26,7 @@ data PGFEnv = Env {pgf::Maybe PGF,concs::Map.Map ConcName Concr}
pgfEnv pgf = Env (Just pgf) (languages pgf) pgfEnv pgf = Env (Just pgf) (languages pgf)
emptyPGFEnv = Env Nothing Map.empty emptyPGFEnv = Env Nothing Map.empty
class (Monad m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv class (Fail.MonadFail m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv
instance (Monad m,HasPGFEnv m) => TypeCheckArg m where instance (Monad m,HasPGFEnv m) => TypeCheckArg m where
typeCheckArg e = do env <- getPGFEnv typeCheckArg e = do env <- getPGFEnv

View File

@@ -11,6 +11,8 @@ import GF.Infra.UseIO(putStrLnE)
import Control.Monad(when) import Control.Monad(when)
import qualified Data.Map as Map import qualified Data.Map as Map
import GF.Infra.UseIO (Output)
import qualified Control.Monad.Fail as Fail
data CommandEnv m = CommandEnv { data CommandEnv m = CommandEnv {
commands :: Map.Map String (CommandInfo m), commands :: Map.Map String (CommandInfo m),
@@ -22,6 +24,7 @@ data CommandEnv m = CommandEnv {
mkCommandEnv cmds = CommandEnv cmds Map.empty Map.empty mkCommandEnv cmds = CommandEnv cmds Map.empty Map.empty
--interpretCommandLine :: CommandEnv -> String -> SIO () --interpretCommandLine :: CommandEnv -> String -> SIO ()
interpretCommandLine :: (Fail.MonadFail m, Output m, TypeCheckArg m) => CommandEnv m -> String -> m ()
interpretCommandLine env line = interpretCommandLine env line =
case readCommandLine line of case readCommandLine line of
Just [] -> return () Just [] -> return ()

View File

@@ -41,6 +41,7 @@ import Control.Monad
import Control.Monad.Identity import Control.Monad.Identity
--import Control.Exception --import Control.Exception
--import Debug.Trace(trace) --import Debug.Trace(trace)
import qualified Control.Monad.Fail as Fail
---------------------------------------------------------------------- ----------------------------------------------------------------------
-- main conversion function -- main conversion function
@@ -196,6 +197,9 @@ newtype CnvMonad a = CM {unCM :: SourceGrammar
-> ([ProtoFCat],[Symbol]) -> ([ProtoFCat],[Symbol])
-> Branch b} -> Branch b}
instance Fail.MonadFail CnvMonad where
fail = bug
instance Applicative CnvMonad where instance Applicative CnvMonad where
pure = return pure = return
(<*>) = ap (<*>) = ap

View File

@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
module GF.Compile.TypeCheck.ConcreteNew( checkLType, inferLType ) where module GF.Compile.TypeCheck.ConcreteNew( checkLType, inferLType ) where
-- The code here is based on the paper: -- The code here is based on the paper:
@@ -19,6 +20,7 @@ import GF.Text.Pretty
import Data.List (nub, (\\), tails) import Data.List (nub, (\\), tails)
import qualified Data.IntMap as IntMap import qualified Data.IntMap as IntMap
import Data.Maybe(fromMaybe,isNothing) import Data.Maybe(fromMaybe,isNothing)
import qualified Control.Monad.Fail as Fail
checkLType :: GlobalEnv -> Term -> Type -> Check (Term, Type) checkLType :: GlobalEnv -> Term -> Type -> Check (Term, Type)
checkLType ge t ty = runTcM $ do checkLType ge t ty = runTcM $ do
@@ -646,8 +648,16 @@ instance Monad TcM where
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)
#if !(MIN_VERSION_base(4,13,0))
-- Monad(fail) will be removed in GHC 8.8+
fail = Fail.fail
#endif
instance Fail.MonadFail TcM where
fail = tcError . pp fail = tcError . pp
instance Applicative TcM where instance Applicative TcM where
pure = return pure = return
(<*>) = ap (<*>) = ap

View File

@@ -27,9 +27,10 @@ import Data.List
import qualified Data.Map as Map import qualified Data.Map as Map
import Control.Monad import Control.Monad
import GF.Text.Pretty import GF.Text.Pretty
import qualified Control.Monad.Fail as Fail
-- | combine a list of definitions into a balanced binary search tree -- | combine a list of definitions into a balanced binary search tree
buildAnyTree :: Monad m => ModuleName -> [(Ident,Info)] -> m (Map.Map Ident Info) buildAnyTree :: Fail.MonadFail m => ModuleName -> [(Ident,Info)] -> m (Map.Map Ident Info)
buildAnyTree m = go Map.empty buildAnyTree m = go Map.empty
where where
go map [] = return map go map [] = return map

View File

@@ -20,6 +20,8 @@ import GF.Infra.Ident(moduleNameS)
import GF.Text.Pretty import GF.Text.Pretty
import GF.System.Console(TermColors(..),getTermColors) import GF.System.Console(TermColors(..),getTermColors)
import qualified Data.ByteString.Lazy as BS import qualified Data.ByteString.Lazy as BS
-- Control.Monad.Fail import will become redundant in GHC 8.8+
import qualified Control.Monad.Fail as Fail
-- | Compile the given grammar files and everything they depend on, -- | Compile the given grammar files and everything they depend on,
-- like 'batchCompile'. This function compiles modules in parallel. -- like 'batchCompile'. This function compiles modules in parallel.
@@ -256,6 +258,9 @@ instance Output m => Output (CollectOutput m) where
putStrLnE s = CO (return (putStrLnE s,())) putStrLnE s = CO (return (putStrLnE s,()))
putStrE s = CO (return (putStrE s,())) putStrE s = CO (return (putStrE s,()))
instance Fail.MonadFail m => Fail.MonadFail (CollectOutput m) where
fail = CO . fail
instance ErrorMonad m => ErrorMonad (CollectOutput m) where instance ErrorMonad m => ErrorMonad (CollectOutput m) where
raise e = CO (raise e) raise e = CO (raise e)
handle (CO m) h = CO $ handle m (unCO . h) handle (CO m) h = CO $ handle m (unCO . h)

View File

@@ -30,12 +30,13 @@ import qualified Data.Map as Map
import GF.Text.Pretty(render,(<+>),($$)) --Doc, import GF.Text.Pretty(render,(<+>),($$)) --Doc,
import GF.System.Console(TermColors(..),getTermColors) import GF.System.Console(TermColors(..),getTermColors)
import Control.Monad((<=<)) import Control.Monad((<=<))
import qualified Control.Monad.Fail as Fail
type OneOutput = (Maybe FullPath,CompiledModule) type OneOutput = (Maybe FullPath,CompiledModule)
type CompiledModule = Module type CompiledModule = Module
compileOne, reuseGFO, useTheSource :: compileOne, reuseGFO, useTheSource ::
(Output m,ErrorMonad m,MonadIO m) => (Output m,ErrorMonad m,MonadIO m, Fail.MonadFail m) =>
Options -> Grammar -> FullPath -> m OneOutput Options -> Grammar -> FullPath -> m OneOutput
-- | Compile a given source file (or just load a .gfo file), -- | Compile a given source file (or just load a .gfo file),

View File

@@ -13,6 +13,7 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
{-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleInstances #-} {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleInstances #-}
{-# LANGUAGE CPP #-}
module GF.Data.BacktrackM ( module GF.Data.BacktrackM (
-- * the backtracking state monad -- * the backtracking state monad
BacktrackM, BacktrackM,
@@ -32,6 +33,7 @@ import Data.List
import Control.Applicative import Control.Applicative
import Control.Monad import Control.Monad
import Control.Monad.State.Class import Control.Monad.State.Class
import qualified Control.Monad.Fail as Fail
---------------------------------------------------------------------- ----------------------------------------------------------------------
-- Combining endomorphisms and continuations -- Combining endomorphisms and continuations
@@ -69,6 +71,12 @@ instance Monad (BacktrackM s) where
return a = BM (\c s b -> c a s b) return a = BM (\c s b -> c a s b)
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))
fail = Fail.fail
#endif
instance Fail.MonadFail (BacktrackM s) where
fail _ = mzero fail _ = mzero
instance Functor (BacktrackM s) where instance Functor (BacktrackM s) where

View File

@@ -12,10 +12,12 @@
-- hack for BNFC generated files. AR 21/9/2003 -- hack for BNFC generated files. AR 21/9/2003
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
{-# LANGUAGE CPP #-}
module GF.Data.ErrM where module GF.Data.ErrM where
import Control.Monad (MonadPlus(..),ap) import Control.Monad (MonadPlus(..),ap)
import Control.Applicative import Control.Applicative
import qualified Control.Monad.Fail as Fail
-- | Like 'Maybe' type with error msgs -- | Like 'Maybe' type with error msgs
data Err a = Ok a | Bad String data Err a = Ok a | Bad String
@@ -33,10 +35,19 @@ fromErr a = err (const a) id
instance Monad Err where instance Monad Err where
return = Ok return = Ok
fail = Bad
Ok a >>= f = f a Ok a >>= f = f a
Bad s >>= f = Bad s Bad s >>= f = Bad s
#if !(MIN_VERSION_base(4,13,0))
-- Monad(fail) will be removed in GHC 8.8+
fail = Fail.fail
#endif
instance Fail.MonadFail Err where
fail = Bad
-- | added 2\/10\/2003 by PEB -- | added 2\/10\/2003 by PEB
instance Functor Err where instance Functor Err where
fmap f (Ok a) = Ok (f a) fmap f (Ok a) = Ok (f a)

View File

@@ -53,6 +53,7 @@ import Control.Monad (liftM,liftM2) --,ap
import GF.Data.ErrM import GF.Data.ErrM
import GF.Data.Relation import GF.Data.Relation
import qualified Control.Monad.Fail as Fail
infixr 5 +++ infixr 5 +++
infixr 5 ++- infixr 5 ++-
@@ -88,10 +89,10 @@ checkUnique ss = ["overloaded" +++ show s | s <- nub overloads] where
overloaded s = length (filter (==s) ss) > 1 overloaded s = length (filter (==s) ss) > 1
-- | this is what happens when matching two values in the same module -- | this is what happens when matching two values in the same module
unifyMaybe :: (Eq a, Monad m) => Maybe a -> Maybe a -> m (Maybe a) unifyMaybe :: (Eq a, Fail.MonadFail m) => Maybe a -> Maybe a -> m (Maybe a)
unifyMaybe = unifyMaybeBy id unifyMaybe = unifyMaybeBy id
unifyMaybeBy :: (Eq b, Monad m) => (a->b) -> Maybe a -> Maybe a -> m (Maybe a) unifyMaybeBy :: (Eq b, Fail.MonadFail m) => (a->b) -> Maybe a -> Maybe a -> m (Maybe a)
unifyMaybeBy f (Just p1) (Just p2) unifyMaybeBy f (Just p1) (Just p2)
| f p1==f p2 = return (Just p1) | f p1==f p2 = return (Just p1)
| otherwise = fail "" | otherwise = fail ""

View File

@@ -6,6 +6,7 @@ import Text.JSON
import Control.Applicative ((<|>)) import Control.Applicative ((<|>))
import Data.Ratio (denominator, numerator) import Data.Ratio (denominator, numerator)
import GF.Grammar.Canonical import GF.Grammar.Canonical
import Control.Monad (guard)
encodeJSON :: FilePath -> Grammar -> IO () encodeJSON :: FilePath -> Grammar -> IO ()
@@ -126,10 +127,10 @@ instance JSON LinType where
-- records are encoded as records: -- records are encoded as records:
showJSON (RecordType rows) = showJSON rows showJSON (RecordType rows) = showJSON rows
readJSON o = do "Str" <- readJSON o; return StrType readJSON o = StrType <$ parseString "Str" o
<|> do "Float" <- readJSON o; return FloatType <|> FloatType <$ parseString "Float" o
<|> do "Int" <- readJSON o; return IntType <|> IntType <$ parseString "Int" o
<|> do ptype <- readJSON o; return (ParamType ptype) <|> ParamType <$> readJSON o
<|> TableType <$> o!".tblarg" <*> o!".tblval" <|> TableType <$> o!".tblarg" <*> o!".tblval"
<|> TupleType <$> o!".tuple" <|> TupleType <$> o!".tuple"
<|> RecordType <$> readJSON o <|> RecordType <$> readJSON o
@@ -186,7 +187,7 @@ instance JSON LinPattern where
-- and records as records: -- and records as records:
showJSON (RecordPattern r) = showJSON r showJSON (RecordPattern r) = showJSON r
readJSON o = do "_" <- readJSON o; return WildPattern readJSON o = do p <- parseString "_" o; return WildPattern
<|> do p <- readJSON o; return (ParamPattern (Param p [])) <|> do p <- readJSON o; return (ParamPattern (Param p []))
<|> ParamPattern <$> readJSON o <|> ParamPattern <$> readJSON o
<|> RecordPattern <$> readJSON o <|> RecordPattern <$> readJSON o
@@ -237,7 +238,7 @@ instance JSON VarId where
showJSON Anonymous = showJSON "_" showJSON Anonymous = showJSON "_"
showJSON (VarId x) = showJSON x showJSON (VarId x) = showJSON x
readJSON o = do "_" <- readJSON o; return Anonymous readJSON o = do parseString "_" o; return Anonymous
<|> VarId <$> readJSON o <|> VarId <$> readJSON o
instance JSON QualId where instance JSON QualId where
@@ -268,6 +269,9 @@ instance JSON FlagValue where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- ** Convenience functions -- ** Convenience functions
parseString :: String -> JSValue -> Result ()
parseString s o = guard . (== s) =<< readJSON o
(!) :: JSON a => JSValue -> String -> Result a (!) :: JSON a => JSValue -> String -> Result a
obj ! key = maybe (fail $ "CanonicalJSON.(!): Could not find key: " ++ show key) obj ! key = maybe (fail $ "CanonicalJSON.(!): Could not find key: " ++ show key)
readJSON readJSON

View File

@@ -1,5 +1,6 @@
-- -*- haskell -*- -- -*- haskell -*-
{ {
{-# LANGUAGE CPP #-}
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
@@ -18,6 +19,7 @@ import qualified Data.Map as Map
import Data.Word(Word8) import Data.Word(Word8)
import Data.Char(readLitChar) import Data.Char(readLitChar)
--import Debug.Trace(trace) --import Debug.Trace(trace)
import qualified Control.Monad.Fail as Fail
} }
@@ -282,8 +284,12 @@ instance Monad P where
(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
instance Fail.MonadFail P where
fail msg = P $ \(_,AI posn _ _) -> PFailed posn msg fail msg = P $ \(_,AI posn _ _) -> PFailed posn msg
runP :: P a -> BS.ByteString -> Either (Posn,String) a runP :: P a -> BS.ByteString -> Either (Posn,String) a
runP p bs = snd <$> runP' p (Pn 1 0,bs) runP p bs = snd <$> runP' p (Pn 1 0,bs)

View File

@@ -32,6 +32,7 @@ import Control.Monad (liftM, liftM2, liftM3)
import Data.List (sortBy,nub) import Data.List (sortBy,nub)
import Data.Monoid import Data.Monoid
import GF.Text.Pretty(render,(<+>),hsep,fsep) import GF.Text.Pretty(render,(<+>),hsep,fsep)
import qualified Control.Monad.Fail as Fail
-- ** Functions for constructing and analysing source code terms. -- ** Functions for constructing and analysing source code terms.
@@ -237,7 +238,7 @@ isPredefConstant t = case t of
Q (mod,_) | mod == cPredef || mod == cPredefAbs -> True Q (mod,_) | mod == cPredef || mod == cPredefAbs -> True
_ -> False _ -> False
checkPredefError :: Monad m => Term -> m Term checkPredefError :: Fail.MonadFail m => Term -> m Term
checkPredefError t = checkPredefError t =
case t of case t of
Error s -> fail ("Error: "++s) Error s -> fail ("Error: "++s)

View File

@@ -32,6 +32,7 @@ import System.FilePath(makeRelative)
import Control.Parallel.Strategies(parList,rseq,using) import Control.Parallel.Strategies(parList,rseq,using)
import Control.Monad(liftM,ap) import Control.Monad(liftM,ap)
import Control.Applicative(Applicative(..)) import Control.Applicative(Applicative(..))
import qualified Control.Monad.Fail as Fail
type Message = Doc type Message = Doc
type Error = Message type Error = Message
@@ -53,6 +54,9 @@ instance Monad Check where
(ws,Success x) -> unCheck (g x) {-ctxt-} ws (ws,Success x) -> unCheck (g x) {-ctxt-} ws
(ws,Fail msg) -> (ws,Fail msg) (ws,Fail msg) -> (ws,Fail msg)
instance Fail.MonadFail Check where
fail = raise
instance Applicative Check where instance Applicative Check where
pure = return pure = return
(<*>) = ap (<*>) = ap

View File

@@ -44,6 +44,7 @@ import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import PGF.Internal(Literal(..)) import PGF.Internal(Literal(..))
import qualified Control.Monad.Fail as Fail
usageHeader :: String usageHeader :: String
usageHeader = unlines usageHeader = unlines
@@ -548,7 +549,7 @@ lookupShow xs z = fromMaybe "lookupShow" $ lookup z [(y,x) | (x,y) <- xs]
lookupReadsPrec :: [(String,a)] -> Int -> ReadS a lookupReadsPrec :: [(String,a)] -> Int -> ReadS a
lookupReadsPrec xs _ s = [(z,rest) | (x,rest) <- lex s, (y,z) <- xs, y == x] lookupReadsPrec xs _ s = [(z,rest) | (x,rest) <- lex s, (y,z) <- xs, y == x]
onOff :: Monad m => (Bool -> m a) -> Bool -> ArgDescr (m a) onOff :: Fail.MonadFail m => (Bool -> m a) -> Bool -> ArgDescr (m a)
onOff f def = OptArg g "[on,off]" onOff f def = OptArg g "[on,off]"
where g ma = maybe (return def) readOnOff ma >>= f where g ma = maybe (return def) readOnOff ma >>= f
readOnOff x = case map toLower x of readOnOff x = case map toLower x of
@@ -556,7 +557,7 @@ onOff f def = OptArg g "[on,off]"
"off" -> return False "off" -> return False
_ -> fail $ "Expected [on,off], got: " ++ show x _ -> fail $ "Expected [on,off], got: " ++ show x
readOutputFormat :: Monad m => String -> m OutputFormat readOutputFormat :: Fail.MonadFail m => String -> m OutputFormat
readOutputFormat s = readOutputFormat s =
maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats

View File

@@ -42,6 +42,7 @@ import qualified GF.Command.Importing as GF(importGrammar, importSource)
#ifdef C_RUNTIME #ifdef C_RUNTIME
import qualified PGF2 import qualified PGF2
#endif #endif
import qualified Control.Monad.Fail as Fail
-- * The SIO monad -- * The SIO monad
@@ -58,6 +59,9 @@ instance Monad SIO where
return x = SIO (const (return x)) return x = SIO (const (return x))
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
fail = liftSIO . fail
instance Output SIO where instance Output SIO where
ePutStr = lift0 . ePutStr ePutStr = lift0 . ePutStr
ePutStrLn = lift0 . ePutStrLn ePutStrLn = lift0 . ePutStrLn

View File

@@ -159,6 +159,9 @@ instance ErrorMonad IO where
then h (ioeGetErrorString e) then h (ioeGetErrorString e)
else ioError e else ioError e
{- {-
-- Control.Monad.Fail import will become redundant in GHC 8.8+
import qualified Control.Monad.Fail as Fail
instance Functor IOE where fmap = liftM instance Functor IOE where fmap = liftM
instance Applicative IOE where instance Applicative IOE where
@@ -170,7 +173,15 @@ instance Monad IOE where
IOE c >>= f = IOE $ do IOE c >>= f = IOE $ do
x <- c -- Err a x <- c -- Err a
appIOE $ err raise f x -- f :: a -> IOE a appIOE $ err raise f x -- f :: a -> IOE a
#if !(MIN_VERSION_base(4,13,0))
fail = raise fail = raise
#endif
instance Fail.MonadFail IOE where
fail = raise
-} -}
-- | Print the error message and return a default value if the IO operation 'fail's -- | Print the error message and return a default value if the IO operation 'fail's

View File

@@ -38,6 +38,9 @@ import GF.Server(server)
#endif #endif
import GF.Command.Messages(welcome) import GF.Command.Messages(welcome)
import GF.Infra.UseIO (Output)
-- Provides an orphan instance of MonadFail for StateT in ghc versions < 8
import Control.Monad.Trans.Instances ()
-- | 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 ()

View File

@@ -1,3 +1,8 @@
## 1.2.1
- Remove deprecated pgf_print_expr_tuple
- Added an API for cloning expressions/types/literals
## 1.2.0 ## 1.2.0
- Stop `pgf-shell` from being built by default. - Stop `pgf-shell` from being built by default.

View File

@@ -0,0 +1,10 @@
# Instructions for uploading to Hackage
You will need a Hackage account for steps 4 & 5.
1. Bump the version number in `pgf2.cabal`
2. Add details in `CHANGELOG.md`
3. Run `stack sdist` (or `cabal sdist`)
4. Visit `https://hackage.haskell.org/upload` and upload the file `./.stack-work/dist/x86_64-osx/Cabal-2.2.0.1/pgf2-x.y.z.tar.gz` (or Cabal equivalent)
5. If successful, upload documentation with `./stack-haddock-upload.sh pgf2 x.y.z` (compilation on Hackage's servers will fail because of missing C libraries)
6. Commit and push to this repository (`gf-core`)

View File

@@ -1,5 +1,5 @@
name: pgf2 name: pgf2
version: 1.2.0 version: 1.2.1
synopsis: Bindings to the C version of the PGF runtime synopsis: Bindings to the C version of the PGF runtime
description: description:
GF, Grammatical Framework, is a programming language for multilingual grammar applications. GF, Grammatical Framework, is a programming language for multilingual grammar applications.

View File

@@ -101,6 +101,10 @@ import GHC.Word
--import GHC.Int --import GHC.Int
#endif #endif
-- Control.Monad.Fail import will become redundant in GHC 8.8+
import qualified Control.Monad.Fail as Fail
-- | The parse state -- | The parse state
data S = S {-# UNPACK #-} !B.ByteString -- current chunk data S = S {-# UNPACK #-} !B.ByteString -- current chunk
L.ByteString -- the rest of the input L.ByteString -- the rest of the input
@@ -126,6 +130,11 @@ instance Monad Get where
(a, s') -> unGet (k a) s') (a, s') -> unGet (k a) s')
{-# INLINE (>>=) #-} {-# INLINE (>>=) #-}
#if !(MIN_VERSION_base(4,13,0))
fail = failDesc
#endif
instance Fail.MonadFail Get where
fail = failDesc fail = failDesc
instance MonadFix Get where instance MonadFix Get where

View File

@@ -4,7 +4,7 @@ import Network.CGI as C(
CGI,ContentType(..),Accept(..),Language(..), CGI,ContentType(..),Accept(..),Language(..),
getVarWithDefault,readInput,negotiate,requestAcceptLanguage,getInput, getVarWithDefault,readInput,negotiate,requestAcceptLanguage,getInput,
setHeader,output,outputFPS,outputError, setHeader,output,outputFPS,outputError,
handleErrors,catchCGI,throwCGI, handleErrors,
liftIO) liftIO)
import Network.CGI.Protocol as C(CGIResult(..),CGIRequest(..),Input(..), import Network.CGI.Protocol as C(CGIResult(..),CGIRequest(..),Input(..),
Headers,HeaderName(..)) Headers,HeaderName(..))

View File

@@ -15,11 +15,14 @@ import System.Posix
#endif #endif
import CGI(CGI,CGIResult,setHeader,output,outputFPS,outputError, import CGI(CGI,CGIResult,setHeader,output,outputFPS,outputError,
getInput,catchCGI,throwCGI) getInput)
import Text.JSON import Text.JSON
import qualified Codec.Binary.UTF8.String as UTF8 (encodeString) import qualified Codec.Binary.UTF8.String as UTF8 (encodeString)
import qualified Data.ByteString.Lazy as BS import qualified Data.ByteString.Lazy as BS
import Control.Monad.Catch (MonadThrow(throwM))
import Network.CGI.Monad (catchCGI)
import Control.Monad.Catch (MonadCatch(catch))
-- * Logging -- * Logging
@@ -53,11 +56,11 @@ instance Exception CGIError where
fromException (SomeException e) = cast e fromException (SomeException e) = cast e
throwCGIError :: Int -> String -> [String] -> CGI a throwCGIError :: Int -> String -> [String] -> CGI a
throwCGIError c m t = throwCGI $ toException $ CGIError c m t throwCGIError c m t = throwM $ toException $ CGIError c m t
handleCGIErrors :: CGI CGIResult -> CGI CGIResult handleCGIErrors :: CGI CGIResult -> CGI CGIResult
handleCGIErrors x = handleCGIErrors x =
x `catchCGI` \e -> case fromException e of x `catch` \e -> case fromException e of
Nothing -> throw e Nothing -> throw e
Just (CGIError c m t) -> do setXO; outputError c m t Just (CGIError c m t) -> do setXO; outputError c m t

View File

@@ -4,6 +4,10 @@
-- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE. -- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE.
module GFCC.ErrM where module GFCC.ErrM where
-- Control.Monad.Fail import will become redundant in GHC 8.8+
import qualified Control.Monad.Fail as Fail
-- the Error monad: like Maybe type with error msgs -- the Error monad: like Maybe type with error msgs
data Err a = Ok a | Bad String data Err a = Ok a | Bad String
@@ -11,6 +15,13 @@ data Err a = Ok a | Bad String
instance Monad Err where instance Monad Err where
return = Ok return = Ok
fail = Bad
Ok a >>= f = f a Ok a >>= f = f a
Bad s >>= f = Bad s Bad s >>= f = Bad s
#if !(MIN_VERSION_base(4,13,0))
fail = Bad
#endif
instance Fail.MonadFail Err where
fail = Bad

View File

@@ -1 +1,12 @@
resolver: lts-6.35 # ghc 7.10.3 resolver: lts-6.35 # ghc 7.10.3
extra-deps:
- happy-1.19.9
- alex-3.2.4
- transformers-compat-0.6.5
allow-newer: true
flags:
transformers-compat:
four: true

View File

@@ -1,5 +1,6 @@
resolver: lts-14.3 # ghc 8.6.5 resolver: lts-14.27 # ghc 8.6.5
extra-deps: extra-deps:
- network-2.6.3.6 - network-2.6.3.6
- httpd-shed-0.4.0.3 - httpd-shed-0.4.0.3
- cgi-3001.5.0.0

9
stack-ghc8.8.4.yaml Normal file
View File

@@ -0,0 +1,9 @@
resolver: lts-16.13 # ghc 8.8.4
extra-deps:
- network-2.6.3.6
- httpd-shed-0.4.0.3
- cgi-3001.5.0.0@sha256:3d1193a328d5f627a021a0ef3927c1ae41dd341e32dba612fed52d0e3a6df056,2990
- json-0.10@sha256:d9fc6b07ce92b8894825a17d2cf14799856767eb30c8bf55962baa579207d799,3210
- multipart-0.2.0@sha256:b8770e3ff6089be4dd089a8250894b31287cca671f3d258190a505f9351fa8a9,1084

View File

@@ -1,9 +1,9 @@
# This default stack file is a copy of stack-ghc8.2.2.yaml # This default stack file is a copy of stack-ghc8.6.5.yaml
# But committing a symlink is probably a bad idea, so it's a real copy # But committing a symlink is probably a bad idea, so it's a real copy
resolver: lts-11.22 # ghc 8.2.2 resolver: lts-14.27 # ghc 8.6.5
extra-deps: extra-deps:
- cgi-3001.3.0.3 - network-2.6.3.6
- httpd-shed-0.4.0.3 - httpd-shed-0.4.0.3
- exceptions-0.10.2 - cgi-3001.5.0.0

View File

@@ -1,6 +1,7 @@
import Data.List(partition) import Data.List(partition)
import System.IO import System.IO
import Distribution.Simple.BuildPaths(exeExtension) import Distribution.Simple.BuildPaths(exeExtension)
import Distribution.System ( buildPlatform )
import System.Process(readProcess) import System.Process(readProcess)
import System.Directory(doesFileExist,getDirectoryContents) import System.Directory(doesFileExist,getDirectoryContents)
import System.FilePath((</>),(<.>),takeExtension) import System.FilePath((</>),(<.>),takeExtension)
@@ -71,7 +72,7 @@ main =
-- Should consult the Cabal configuration! -- Should consult the Cabal configuration!
run_gf = readProcess default_gf ["-run","-gf-lib-path="++gf_lib_path] run_gf = readProcess default_gf ["-run","-gf-lib-path="++gf_lib_path]
default_gf = "dist/build/gf/gf"<.>exeExtension default_gf = "dist/build/gf/gf"<.>exeExtension buildPlatform
gf_lib_path = "dist/build/rgl" gf_lib_path = "dist/build/rgl"
-- | List files, excluding "." and ".." -- | List files, excluding "." and ".."