From bfcab16de603a33ffef7f3da1174844f0ab11daa Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Sat, 6 Jun 2020 11:35:05 +0200 Subject: [PATCH 01/75] Hotfix for https://github.com/GrammaticalFramework/gf-core/issues/56 --- src/compiler/GF/Compile/Rename.hs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/compiler/GF/Compile/Rename.hs b/src/compiler/GF/Compile/Rename.hs index 5eb83cd4b..c12fd862c 100644 --- a/src/compiler/GF/Compile/Rename.hs +++ b/src/compiler/GF/Compile/Rename.hs @@ -39,6 +39,7 @@ import GF.Data.Operations import Control.Monad import Data.List (nub,(\\)) +import qualified Data.List as L import qualified Data.Map as Map import Data.Maybe(mapMaybe) import GF.Text.Pretty @@ -105,7 +106,26 @@ renameIdentTerm' env@(act,imps) t0 = ts@(t:_) -> do checkWarn ("atomic term" <+> ppTerm Qualified 0 t0 $$ "conflict" <+> hsep (punctuate ',' (map (ppTerm Qualified 0) ts)) $$ "given" <+> fsep (punctuate ',' (map fst qualifs))) - return t + return (bestTerm ts) -- Heuristic for resource grammar. Returns t for all others. + where + -- Hotfix for https://github.com/GrammaticalFramework/gf-core/issues/56 + -- Real bug is probably somewhere deeper in recognising excluded functions. /IL 2020-06-06 + notFromCommonModule :: Term -> Bool + notFromCommonModule term = + let t = render $ ppTerm Qualified 0 term :: String + in not $ any (\moduleName -> moduleName `L.isPrefixOf` t) + ["CommonX", "ConstructX", "ExtendFunctor" + ,"MarkHTMLX", "ParamX", "TenseX", "TextX"] + + -- If one of the terms comes from the common modules, + -- we choose the other one, because that's defined in the grammar. + bestTerm :: [Term] -> Term + bestTerm [] = error "constant not found" -- not reached: bestTerm is only called for case ts@(t:_) + bestTerm ts@(t:_) = + let notCommon = [t | t <- ts, notFromCommonModule t] + in case notCommon of + [] -> t -- All terms are from common modules, return first of original list + (u:_) -> u -- ≥1 terms are not from common modules, return first of those info2status :: Maybe ModuleName -> Ident -> Info -> StatusInfo info2status mq c i = case i of From ac81b418d61e150376485a5956421e8e6967a651 Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 16:57:33 +0800 Subject: [PATCH 02/75] Added readJSON error messages --- src/compiler/SimpleEditor/JSON.hs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/compiler/SimpleEditor/JSON.hs b/src/compiler/SimpleEditor/JSON.hs index 8f607dc84..06586c5eb 100644 --- a/src/compiler/SimpleEditor/JSON.hs +++ b/src/compiler/SimpleEditor/JSON.hs @@ -9,14 +9,24 @@ instance JSON Grammar where showJSON (Grammar name extends abstract concretes) = makeObj ["basename".=name, "extends".=extends, "abstract".=abstract, "concretes".=concretes] + readJSON = error "Grammar.readJSON intentionally not defined" instance JSON Abstract where showJSON (Abstract startcat cats funs) = makeObj ["startcat".=startcat, "cats".=cats, "funs".=funs] + readJSON = error "Abstract.readJSON intentionally not defined" -instance JSON Fun where showJSON (Fun name typ) = signature name typ -instance JSON Param where showJSON (Param name rhs) = definition name rhs -instance JSON Oper where showJSON (Oper name rhs) = definition name rhs +instance JSON Fun where + showJSON (Fun name typ) = signature name typ + readJSON = error "Fun.readJSON intentionally not defined" + +instance JSON Param where + showJSON (Param name rhs) = definition name rhs + readJSON = error "Param.readJSON intentionally not defined" + +instance JSON Oper where + showJSON (Oper name rhs) = definition name rhs + readJSON = error "Oper.readJSON intentionally not defined" signature name typ = makeObj ["name".=name,"type".=typ] definition name rhs = makeObj ["name".=name,"rhs".=rhs] @@ -26,12 +36,15 @@ instance JSON Concrete where makeObj ["langcode".=langcode, "opens".=opens, "params".=params, "opers".=opers, "lincats".=lincats, "lins".=lins] + readJSON = error "Concrete.readJSON intentionally not defined" instance JSON Lincat where showJSON (Lincat cat lintype) = makeObj ["cat".=cat, "type".=lintype] + readJSON = error "Lincat.readJSON intentionally not defined" instance JSON Lin where showJSON (Lin fun args lin) = makeObj ["fun".=fun, "args".=args, "lin".=lin] + readJSON = error "Lin.readJSON intentionally not defined" infix 1 .= name .= v = (name,showJSON v) From dc6dd988bc77bc95bc5a5855e1031f4169c1b4b8 Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:01:47 +0800 Subject: [PATCH 03/75] Replaced inlinePerformIO with accursedUnutterablePerformIO --- src/runtime/haskell/Data/Binary/Builder.hs | 4 ++-- src/runtime/haskell/Data/Binary/Get.hs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/runtime/haskell/Data/Binary/Builder.hs b/src/runtime/haskell/Data/Binary/Builder.hs index b69371f0e..a74428f20 100644 --- a/src/runtime/haskell/Data/Binary/Builder.hs +++ b/src/runtime/haskell/Data/Binary/Builder.hs @@ -68,7 +68,7 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString.Base (inlinePerformIO) import qualified Data.ByteString.Base as S #else -import Data.ByteString.Internal (inlinePerformIO) +import Data.ByteString.Internal (accursedUnutterablePerformIO) import qualified Data.ByteString.Internal as S --import qualified Data.ByteString.Lazy.Internal as L #endif @@ -199,7 +199,7 @@ defaultSize = 32 * k - overhead -- | Sequence an IO operation on the buffer unsafeLiftIO :: (Buffer -> IO Buffer) -> Builder -unsafeLiftIO f = Builder $ \ k buf -> inlinePerformIO $ do +unsafeLiftIO f = Builder $ \ k buf -> accursedUnutterablePerformIO $ do buf' <- f buf return (k buf') {-# INLINE unsafeLiftIO #-} diff --git a/src/runtime/haskell/Data/Binary/Get.hs b/src/runtime/haskell/Data/Binary/Get.hs index 01561d7d9..54f17ae95 100644 --- a/src/runtime/haskell/Data/Binary/Get.hs +++ b/src/runtime/haskell/Data/Binary/Get.hs @@ -423,7 +423,7 @@ readN n f = fmap f $ getBytes n getPtr :: Storable a => Int -> Get a getPtr n = do (fp,o,_) <- readN n B.toForeignPtr - return . B.inlinePerformIO $ withForeignPtr fp $ \p -> peek (castPtr $ p `plusPtr` o) + return . B.accursedUnutterablePerformIO $ withForeignPtr fp $ \p -> peek (castPtr $ p `plusPtr` o) {- INLINE getPtr -} ------------------------------------------------------------------------ From 33aad1b8de0b8387426155870c98adf35e400962 Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:06:35 +0800 Subject: [PATCH 04/75] Deleted redundant pattern match --- src/compiler/GF/Grammar/Canonical.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/GF/Grammar/Canonical.hs b/src/compiler/GF/Grammar/Canonical.hs index 4adff02f2..0df3236ff 100644 --- a/src/compiler/GF/Grammar/Canonical.hs +++ b/src/compiler/GF/Grammar/Canonical.hs @@ -265,7 +265,6 @@ instance PPA LinPattern where RecordPattern r -> block r TuplePattern ps -> "<"<>punctuate "," ps<>">" WildPattern -> pp "_" - _ -> parens p instance RhsSeparator LinPattern where rhsSep _ = pp "=" From 4364b1d9fb62551fb6361be36cf2563e6d2d93a5 Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:11:41 +0800 Subject: [PATCH 05/75] Replaced Control.Monad.Error with Control.Monad.Except --- src/runtime/haskell/PGF/TypeCheck.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/haskell/PGF/TypeCheck.hs b/src/runtime/haskell/PGF/TypeCheck.hs index 5db4ef439..c5cc44b4e 100644 --- a/src/runtime/haskell/PGF/TypeCheck.hs +++ b/src/runtime/haskell/PGF/TypeCheck.hs @@ -41,7 +41,7 @@ import Control.Applicative import Control.Monad --import Control.Monad.Identity import Control.Monad.State -import Control.Monad.Error +import Control.Monad.Except import Text.PrettyPrint ----------------------------------------------------- From 1f7584bf98346c6d044df631a82353fd1c5972af Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:14:31 +0800 Subject: [PATCH 06/75] Added explicit implementation for 'fromValue' in instance declaration for 'Predef Bool' --- src/compiler/GF/Compile/Compute/Predef.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/GF/Compile/Compute/Predef.hs b/src/compiler/GF/Compile/Compute/Predef.hs index 609a17798..69df3792c 100644 --- a/src/compiler/GF/Compile/Compute/Predef.hs +++ b/src/compiler/GF/Compile/Compute/Predef.hs @@ -27,6 +27,7 @@ instance Predef Int where instance Predef Bool where toValue = boolV + fromValue boolV = return (boolV == boolV) instance Predef String where toValue = string From 8ca4baf470da2fd607d89e7679f7376a56b3f8fb Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:15:20 +0800 Subject: [PATCH 07/75] Deleted redundant pattern match --- src/compiler/GF/Compile/Compute/ConcreteNew.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/GF/Compile/Compute/ConcreteNew.hs b/src/compiler/GF/Compile/Compute/ConcreteNew.hs index ea55e77cb..6f00c45e1 100644 --- a/src/compiler/GF/Compile/Compute/ConcreteNew.hs +++ b/src/compiler/GF/Compile/Compute/ConcreteNew.hs @@ -528,7 +528,7 @@ value2term' stop loc xs v0 = -- VGlue v1 v2 -> Glue (v2t v1) (v2t v2) -- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2) VError err -> return (Error err) - _ -> bug ("value2term "++show loc++" : "++show v0) + where v2t = v2txs xs v2txs = value2term' stop loc From 54e5fb6645d4c99900136e7c909ca7905e441912 Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:19:18 +0800 Subject: [PATCH 08/75] Added explicit implementation for 'readJSON' in the instance declaration for 'JSON PGF.Trie' --- src/server/PGFService.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs index e30ff8652..7edfa9c44 100644 --- a/src/server/PGFService.hs +++ b/src/server/PGFService.hs @@ -1024,6 +1024,7 @@ instance JSON PGF.Trie where showJSON (PGF.Ap f [[]]) = makeObj ["fun".=f] -- leaf -- showJSON (PGF.Ap f [es]) = makeObj ["fun".=f,"children".=es] -- one alternative showJSON (PGF.Ap f alts) = makeObj ["fun".=f,"alts".=alts] + readJSON = error "PGF.Trie.readJSON intentionally not defined" instance JSON PGF.CId where readJSON x = readJSON x >>= maybe (fail "Bad language.") return . PGF.readLanguage From 9b02385e3efcadf39a171f65eaba871b1897360e Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:26:56 +0800 Subject: [PATCH 09/75] Removed fromValue for boolV --- src/compiler/GF/Compile/Compute/Predef.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/GF/Compile/Compute/Predef.hs b/src/compiler/GF/Compile/Compute/Predef.hs index 69df3792c..609a17798 100644 --- a/src/compiler/GF/Compile/Compute/Predef.hs +++ b/src/compiler/GF/Compile/Compute/Predef.hs @@ -27,7 +27,6 @@ instance Predef Int where instance Predef Bool where toValue = boolV - fromValue boolV = return (boolV == boolV) instance Predef String where toValue = string From 2dc179239f915420a5e9485d87a2fa1adb413e4e Mon Sep 17 00:00:00 2001 From: Liyana Date: Tue, 10 Nov 2020 17:32:43 +0800 Subject: [PATCH 10/75] Replaced Control.Monad.Error with Control.Monad.Except --- src/compiler/GF/Server.hs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/compiler/GF/Server.hs b/src/compiler/GF/Server.hs index c287e8001..d930d277c 100644 --- a/src/compiler/GF/Server.hs +++ b/src/compiler/GF/Server.hs @@ -6,7 +6,7 @@ import qualified Data.Map as M import Control.Applicative -- for GHC<7.10 import Control.Monad(when) import Control.Monad.State(StateT(..),get,gets,put) -import Control.Monad.Error(ErrorT(..),Error(..)) +import Control.Monad.Except(ExceptT(..),Except(..),runExceptT) import System.Random(randomRIO) --import System.IO(stderr,hPutStrLn) import GF.System.Catch(try) @@ -108,9 +108,9 @@ handle_fcgi execute1 state0 stateM cache = -- * Request handler -- | Handler monad -type HM s a = StateT (Q,s) (ErrorT Response IO) a +type HM s a = StateT (Q,s) (ExceptT Response IO) a run :: HM s Response -> (Q,s) -> IO (s,Response) -run m s = either bad ok =<< runErrorT (runStateT m s) +run m s = either bad ok =<< runExceptT (runStateT m s) where bad resp = return (snd s,resp) ok (resp,(qs,state)) = return (state,resp) @@ -123,12 +123,12 @@ put_qs qs = do state <- get_state; put (qs,state) put_state state = do qs <- get_qs; put (qs,state) err :: Response -> HM s a -err e = StateT $ \ s -> ErrorT $ return $ Left e +err e = StateT $ \ s -> ExceptT $ return $ Left e hmbracket_ :: IO () -> IO () -> HM s a -> HM s a hmbracket_ pre post m = do s <- get - e <- liftIO $ bracket_ pre post $ runErrorT $ runStateT m s + e <- liftIO $ bracket_ pre post $ runExceptT $ runStateT m s case e of Left resp -> err resp Right (a,s) -> do put s;return a @@ -407,9 +407,6 @@ resp404 path = Response 404 [plain,xo] $ "Not found: "++path++"\n" resp500 msg = Response 500 [plain,xo] $ "Internal error: "++msg++"\n" resp501 msg = Response 501 [plain,xo] $ "Not implemented: "++msg++"\n" -instance Error Response where - noMsg = resp500 "no message" - strMsg = resp500 -- * Content types plain = ct "text/plain" "" From 1740181daf0d3b4724f71a0818ea038133610580 Mon Sep 17 00:00:00 2001 From: Ruslan Khafizov Date: Tue, 10 Nov 2020 19:15:57 +0800 Subject: [PATCH 11/75] Enable tests --- gf.cabal | 1 + testsuite/run.hs | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gf.cabal b/gf.cabal index 0076e7638..731e2e2e7 100644 --- a/gf.cabal +++ b/gf.cabal @@ -352,4 +352,5 @@ test-suite gf-tests main-is: run.hs hs-source-dirs: testsuite build-depends: base>=4.3 && <5, Cabal>=1.8, directory, filepath, process + build-tool-depends: gf:gf default-language: Haskell2010 diff --git a/testsuite/run.hs b/testsuite/run.hs index 6bf3c8158..7f377af79 100644 --- a/testsuite/run.hs +++ b/testsuite/run.hs @@ -14,7 +14,7 @@ main = ok = length good fail = okexeExtension buildPlatform -gf_lib_path = "dist/build/rgl" +run_gf = readProcess default_gf +default_gf = "gf"<.>exeExtension buildPlatform -- | List files, excluding "." and ".." ls path = filter (`notElem` [".",".."]) `fmap` getDirectoryContents path From 76bec6d71e7c4fdffa2e618ec6578e0858166465 Mon Sep 17 00:00:00 2001 From: Liyana Date: Thu, 12 Nov 2020 09:48:15 +0800 Subject: [PATCH 12/75] Omitted import Except(..) --- src/compiler/GF/Server.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/GF/Server.hs b/src/compiler/GF/Server.hs index d930d277c..2e8b8b056 100644 --- a/src/compiler/GF/Server.hs +++ b/src/compiler/GF/Server.hs @@ -6,7 +6,7 @@ import qualified Data.Map as M import Control.Applicative -- for GHC<7.10 import Control.Monad(when) import Control.Monad.State(StateT(..),get,gets,put) -import Control.Monad.Except(ExceptT(..),Except(..),runExceptT) +import Control.Monad.Except(ExceptT(..),runExceptT) import System.Random(randomRIO) --import System.IO(stderr,hPutStrLn) import GF.System.Catch(try) From 91278e2b4b4b2c6fcb8e17682238a1a80a4239cd Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Fri, 30 Apr 2021 13:39:15 +0200 Subject: [PATCH 13/75] Remove notice about example grammars not being included anymore from build scripts --- WebSetup.hs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/WebSetup.hs b/WebSetup.hs index fd55439b4..fa8c5787f 100644 --- a/WebSetup.hs +++ b/WebSetup.hs @@ -26,6 +26,14 @@ import Distribution.PackageDescription(PackageDescription(..)) so users won't see this message unless they check the log.) -} +-- | Notice about contrib grammars +noContribMsg :: IO () +noContribMsg = putStr $ unlines + [ "Example grammars are no longer included in the main GF repository, but have moved to gf-contrib." + , "If you want them to be built, clone the following repository in the same directory as gf-core:" + , "https://github.com/GrammaticalFramework/gf-contrib.git" + ] + example_grammars :: [(String, String, [String])] -- [(pgf, subdir, source modules)] example_grammars = [("Letter.pgf","letter",letterSrc) @@ -50,11 +58,8 @@ buildWeb gf flags (pkg,lbi) = do contrib_exists <- doesDirectoryExist contrib_dir if contrib_exists then mapM_ build_pgf example_grammars - else putStr $ unlines - [ "Example grammars are no longer included in the main GF repository, but have moved to gf-contrib." - , "If you want these example grammars to be built, clone this repository in the same top-level directory as GF:" - , "https://github.com/GrammaticalFramework/gf-contrib.git" - ] + -- else noContribMsg + else return () where gfo_dir = buildDir lbi "examples" From 60bc752a6f705cca1edcd0e48bcfe947fd98b4b5 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Fri, 30 Apr 2021 14:59:20 +0200 Subject: [PATCH 14/75] Add note about type-checking dynamic expressions in PGF2 Haddock Closes #72 --- src/runtime/haskell-bind/PGF2.hsc | 48 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc index 5681f0f86..4204867f1 100644 --- a/src/runtime/haskell-bind/PGF2.hsc +++ b/src/runtime/haskell-bind/PGF2.hsc @@ -50,6 +50,8 @@ module PGF2 (-- * PGF mkType, unType, -- ** Type checking + -- | Dynamically-built expressions should always be type-checked before using in other functions, + -- as the exceptions thrown by using invalid expressions may not catchable. checkExpr, inferExpr, checkType, -- ** Computing @@ -180,7 +182,7 @@ languageCode c = unsafePerformIO (peekUtf8CString =<< pgf_language_code (concr c -- | Generates an exhaustive possibly infinite list of --- all abstract syntax expressions of the given type. +-- all abstract syntax expressions of the given type. -- The expressions are ordered by their probability. generateAll :: PGF -> Type -> [(Expr,Float)] generateAll p (Type ctype _) = @@ -469,21 +471,21 @@ newGraphvizOptions pool opts = do -- Functions using Concr -- Morpho analyses, parsing & linearization --- | This triple is returned by all functions that deal with +-- | This triple is returned by all functions that deal with -- the grammar's lexicon. Its first element is the name of an abstract --- lexical function which can produce a given word or +-- lexical function which can produce a given word or -- a multiword expression (i.e. this is the lemma). --- After that follows a string which describes +-- After that follows a string which describes -- the particular inflection form. -- -- The last element is a logarithm from the --- the probability of the function. The probability is not +-- the probability of the function. The probability is not -- conditionalized on the category of the function. This makes it -- possible to compare the likelihood of two functions even if they --- have different types. +-- have different types. type MorphoAnalysis = (Fun,String,Float) --- | 'lookupMorpho' takes a string which must be a single word or +-- | 'lookupMorpho' takes a string which must be a single word or -- a multiword expression. It then computes the list of all possible -- morphological analyses. lookupMorpho :: Concr -> String -> [MorphoAnalysis] @@ -541,12 +543,12 @@ lookupCohorts lang@(Concr concr master) sent = return ((start,tok,ans,end):cohs) filterBest :: [(Int,String,[MorphoAnalysis],Int)] -> [(Int,String,[MorphoAnalysis],Int)] -filterBest ans = +filterBest ans = reverse (iterate (maxBound :: Int) [(0,0,[],ans)] [] []) where iterate v0 [] [] res = res iterate v0 [] new res = iterate v0 new [] res - iterate v0 ((_,v,conf, []):old) new res = + iterate v0 ((_,v,conf, []):old) new res = case compare v0 v of LT -> res EQ -> iterate v0 old new (merge conf res) @@ -649,7 +651,7 @@ getAnalysis ref self c_lemma c_anal prob exn = do data ParseOutput a = ParseFailed Int String -- ^ The integer is the position in number of unicode characters where the parser failed. -- The string is the token where the parser have failed. - | ParseOk a -- ^ If the parsing and the type checking are successful + | ParseOk a -- ^ If the parsing and the type checking are successful -- we get the abstract syntax trees as either a list or a chart. | ParseIncomplete -- ^ The sentence is not complete. @@ -659,9 +661,9 @@ parse lang ty sent = parseWithHeuristics lang ty sent (-1.0) [] parseWithHeuristics :: Concr -- ^ the language with which we parse -> Type -- ^ the start category -> String -- ^ the input sentence - -> Double -- ^ the heuristic factor. - -- A negative value tells the parser - -- to lookup up the default from + -> Double -- ^ the heuristic factor. + -- A negative value tells the parser + -- to lookup up the default from -- the grammar flags -> [(Cat, String -> Int -> Maybe (Expr,Float,Int))] -- ^ a list of callbacks for literal categories. @@ -715,9 +717,9 @@ parseWithHeuristics lang (Type ctype touchType) sent heuristic callbacks = parseToChart :: Concr -- ^ the language with which we parse -> Type -- ^ the start category -> String -- ^ the input sentence - -> Double -- ^ the heuristic factor. - -- A negative value tells the parser - -- to lookup up the default from + -> Double -- ^ the heuristic factor. + -- A negative value tells the parser + -- to lookup up the default from -- the grammar flags -> [(Cat, String -> Int -> Maybe (Expr,Float,Int))] -- ^ a list of callbacks for literal categories. @@ -886,7 +888,7 @@ lookupSentence lang (Type ctype _) sent = -- | The oracle is a triple of functions. -- The first two take a category name and a linearization field name --- and they should return True/False when the corresponding +-- and they should return True/False when the corresponding -- prediction or completion is appropriate. The third function -- is the oracle for literals. type Oracle = (Maybe (Cat -> String -> Int -> Bool) @@ -1047,7 +1049,7 @@ linearizeAll lang e = unsafePerformIO $ -- | Generates a table of linearizations for an expression tabularLinearize :: Concr -> Expr -> [(String, String)] -tabularLinearize lang e = +tabularLinearize lang e = case tabularLinearizeAll lang e of (lins:_) -> lins _ -> [] @@ -1138,7 +1140,7 @@ data BracketedString -- the phrase. The 'FId' is an unique identifier for -- every phrase in the sentence. For context-free grammars -- i.e. without discontinuous constituents this identifier - -- is also unique for every bracket. When there are discontinuous + -- is also unique for every bracket. When there are discontinuous -- phrases then the identifiers are unique for every phrase but -- not for every bracket since the bracket represents a constituent. -- The different constituents could still be distinguished by using @@ -1148,7 +1150,7 @@ data BracketedString -- The second 'CId' is the name of the abstract function that generated -- this phrase. --- | Renders the bracketed string as a string where +-- | Renders the bracketed string as a string where -- the brackets are shown as @(S ...)@ where -- @S@ is the category. showBracketedString :: BracketedString -> String @@ -1166,7 +1168,7 @@ flattenBracketedString (Bracket _ _ _ _ bss) = concatMap flattenBracketedString bracketedLinearize :: Concr -> Expr -> [BracketedString] bracketedLinearize lang e = unsafePerformIO $ - withGuPool $ \pl -> + withGuPool $ \pl -> do exn <- gu_new_exn pl cts <- pgf_lzr_concretize (concr lang) (expr e) exn pl failed <- gu_exn_is_raised exn @@ -1192,7 +1194,7 @@ bracketedLinearize lang e = unsafePerformIO $ bracketedLinearizeAll :: Concr -> Expr -> [[BracketedString]] bracketedLinearizeAll lang e = unsafePerformIO $ - withGuPool $ \pl -> + withGuPool $ \pl -> do exn <- gu_new_exn pl cts <- pgf_lzr_concretize (concr lang) (expr e) exn pl failed <- gu_exn_is_raised exn @@ -1467,7 +1469,7 @@ type LiteralCallback = literalCallbacks :: [(AbsName,[(Cat,LiteralCallback)])] literalCallbacks = [("App",[("PN",nerc),("Symb",chunk)])] --- | Named entity recognition for the App grammar +-- | Named entity recognition for the App grammar -- (based on ../java/org/grammaticalframework/pgf/NercLiteralCallback.java) nerc :: LiteralCallback nerc pgf (lang,concr) sentence lin_idx offset = From 4729d22c3669da9aa0fed87edfb721fc5ee6ff19 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 10:24:26 +0200 Subject: [PATCH 15/75] Make stack.yaml an actual symlink to stack-ghc8.6.5.yaml. Add some commented flags in stack files. --- stack-ghc7.10.3.yaml | 7 ++++++- stack-ghc8.0.2.yaml | 6 ++++++ stack-ghc8.2.2.yaml | 6 ++++++ stack-ghc8.4.4.yaml | 6 ++++++ stack-ghc8.6.5.yaml | 6 ++++++ stack-ghc8.8.4.yaml | 5 +++++ stack.yaml | 10 +--------- 7 files changed, 36 insertions(+), 10 deletions(-) mode change 100644 => 120000 stack.yaml diff --git a/stack-ghc7.10.3.yaml b/stack-ghc7.10.3.yaml index 0761b54af..751e87fe6 100644 --- a/stack-ghc7.10.3.yaml +++ b/stack-ghc7.10.3.yaml @@ -9,4 +9,9 @@ allow-newer: true flags: transformers-compat: - four: true \ No newline at end of file + four: true +# gf: +# c-runtime: true +# +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack-ghc8.0.2.yaml b/stack-ghc8.0.2.yaml index af08206d9..f98141b0b 100644 --- a/stack-ghc8.0.2.yaml +++ b/stack-ghc8.0.2.yaml @@ -1 +1,7 @@ resolver: lts-9.21 # ghc 8.0.2 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack-ghc8.2.2.yaml b/stack-ghc8.2.2.yaml index c33c53b33..4fd9ce775 100644 --- a/stack-ghc8.2.2.yaml +++ b/stack-ghc8.2.2.yaml @@ -4,3 +4,9 @@ extra-deps: - cgi-3001.3.0.3 - httpd-shed-0.4.0.3 - exceptions-0.10.2 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack-ghc8.4.4.yaml b/stack-ghc8.4.4.yaml index c1a68e2d5..c1f059090 100644 --- a/stack-ghc8.4.4.yaml +++ b/stack-ghc8.4.4.yaml @@ -2,3 +2,9 @@ resolver: lts-12.26 # ghc 8.4.4 extra-deps: - cgi-3001.3.0.3 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack-ghc8.6.5.yaml b/stack-ghc8.6.5.yaml index 2e66c7bf6..20bc53b55 100644 --- a/stack-ghc8.6.5.yaml +++ b/stack-ghc8.6.5.yaml @@ -4,3 +4,9 @@ extra-deps: - network-2.6.3.6 - httpd-shed-0.4.0.3 - cgi-3001.5.0.0 + +flags: + gf: + c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack-ghc8.8.4.yaml b/stack-ghc8.8.4.yaml index a62db170b..95c807937 100644 --- a/stack-ghc8.8.4.yaml +++ b/stack-ghc8.8.4.yaml @@ -7,3 +7,8 @@ extra-deps: - json-0.10@sha256:d9fc6b07ce92b8894825a17d2cf14799856767eb30c8bf55962baa579207d799,3210 - multipart-0.2.0@sha256:b8770e3ff6089be4dd089a8250894b31287cca671f3d258190a505f9351fa8a9,1084 +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack.yaml b/stack.yaml deleted file mode 100644 index f5d21085c..000000000 --- a/stack.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# 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 - -resolver: lts-14.27 # ghc 8.6.5 - -extra-deps: -- network-2.6.3.6 -- httpd-shed-0.4.0.3 -- cgi-3001.5.0.0 \ No newline at end of file diff --git a/stack.yaml b/stack.yaml new file mode 120000 index 000000000..84f47e45a --- /dev/null +++ b/stack.yaml @@ -0,0 +1 @@ +stack-ghc8.6.5.yaml \ No newline at end of file From 07fd41294a408591fbdd30ce8bbb063b68117d00 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 10:33:36 +0200 Subject: [PATCH 16/75] Comment out c-runtime flag by default --- stack-ghc8.6.5.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stack-ghc8.6.5.yaml b/stack-ghc8.6.5.yaml index 20bc53b55..1895acca0 100644 --- a/stack-ghc8.6.5.yaml +++ b/stack-ghc8.6.5.yaml @@ -5,8 +5,8 @@ extra-deps: - httpd-shed-0.4.0.3 - cgi-3001.5.0.0 -flags: - gf: - c-runtime: true +# flags: +# gf: +# c-runtime: true # extra-lib-dirs: # - /usr/local/lib From 450368f9bbf2948365953ae35069b5039ba38a28 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 13:19:08 +0200 Subject: [PATCH 17/75] First attempt at adding support for complete in PGF2 (gives segmentation faults) --- src/runtime/haskell-bind/CHANGELOG.md | 8 ++++-- src/runtime/haskell-bind/PGF2.hsc | 36 +++++++++++++++++++++++---- src/runtime/haskell-bind/PGF2/FFI.hsc | 7 ++++-- src/runtime/haskell-bind/pgf2.cabal | 2 +- src/runtime/haskell-bind/test.hs | 12 +++++++++ 5 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 src/runtime/haskell-bind/test.hs diff --git a/src/runtime/haskell-bind/CHANGELOG.md b/src/runtime/haskell-bind/CHANGELOG.md index aed2d9c4f..570c7fd73 100644 --- a/src/runtime/haskell-bind/CHANGELOG.md +++ b/src/runtime/haskell-bind/CHANGELOG.md @@ -1,7 +1,11 @@ +## 1.3.0 + +- Add completion support. + ## 1.2.1 -- Remove deprecated pgf_print_expr_tuple -- Added an API for cloning expressions/types/literals +- Remove deprecated `pgf_print_expr_tuple`. +- Added an API for cloning expressions/types/literals. ## 1.2.0 diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc index 4204867f1..bd7cf2fe9 100644 --- a/src/runtime/haskell-bind/PGF2.hsc +++ b/src/runtime/haskell-bind/PGF2.hsc @@ -43,32 +43,28 @@ module PGF2 (-- * PGF mkCId, exprHash, exprSize, exprFunctions, exprSubstitute, treeProbability, - -- ** Types Type, Hypo, BindType(..), startCat, readType, showType, showContext, mkType, unType, - -- ** Type checking -- | Dynamically-built expressions should always be type-checked before using in other functions, -- as the exceptions thrown by using invalid expressions may not catchable. checkExpr, inferExpr, checkType, - -- ** Computing compute, -- * Concrete syntax ConcName,Concr,languages,concreteName,languageCode, - -- ** Linearization linearize,linearizeAll,tabularLinearize,tabularLinearizeAll,bracketedLinearize,bracketedLinearizeAll, FId, BracketedString(..), showBracketedString, flattenBracketedString, printName, categoryFields, - alignWords, -- ** Parsing ParseOutput(..), parse, parseWithHeuristics, parseToChart, PArg(..), + complete, -- ** Sentence Lookup lookupSentence, -- ** Generation @@ -976,6 +972,36 @@ parseWithOracle lang cat sent (predict,complete,literal) = return ep Nothing -> do return nullPtr +complete :: Concr -- ^ the language with which we parse + -> Type -- ^ the start category + -> String -- ^ the input sentence + -> String -- ^ prefix (?) + -> Maybe Int -- ^ maximum number of results + -> ParseOutput [(Expr,Float)] +complete lang (Type ctype _) sent pfx mn = + unsafePerformIO $ do + parsePl <- gu_new_pool + exprPl <- gu_new_pool + exn <- gu_new_exn parsePl + + sent <- newUtf8CString sent parsePl + pfx <- newUtf8CString pfx parsePl + + enum <- pgf_complete (concr lang) ctype sent pfx exn parsePl + failed <- gu_exn_is_raised exn + if failed + then do + is_parse_error <- gu_exn_caught exn gu_exn_type_PgfParseError + if is_parse_error + then return (ParseFailed 0 "") + else throwIO (PGFError "Some other error") + -- TODO cleanup!!! + else do + parseFPl <- newForeignPtr gu_pool_finalizer parsePl + exprFPl <- newForeignPtr gu_pool_finalizer exprPl + exprs <- fromPgfExprEnum enum parseFPl (touchConcr lang >> touchForeignPtr exprFPl) + return (ParseOk exprs) + -- | Returns True if there is a linearization defined for that function in that language hasLinearization :: Concr -> Fun -> Bool hasLinearization lang id = unsafePerformIO $ diff --git a/src/runtime/haskell-bind/PGF2/FFI.hsc b/src/runtime/haskell-bind/PGF2/FFI.hsc index c72c48e3b..04952f2d8 100644 --- a/src/runtime/haskell-bind/PGF2/FFI.hsc +++ b/src/runtime/haskell-bind/PGF2/FFI.hsc @@ -103,7 +103,7 @@ foreign import ccall unsafe "gu/file.h gu_file_in" foreign import ccall safe "gu/enum.h gu_enum_next" gu_enum_next :: Ptr a -> Ptr (Ptr b) -> Ptr GuPool -> IO () - + foreign import ccall unsafe "gu/string.h gu_string_buf_freeze" gu_string_buf_freeze :: Ptr GuStringBuf -> Ptr GuPool -> IO CString @@ -241,7 +241,7 @@ newSequence elem_size pokeElem values pool = do type FId = Int data PArg = PArg [FId] {-# UNPACK #-} !FId deriving (Eq,Ord,Show) -peekFId :: Ptr a -> IO FId +peekFId :: Ptr a -> IO FId peekFId c_ccat = do c_fid <- (#peek PgfCCat, fid) c_ccat return (fromIntegral (c_fid :: CInt)) @@ -422,6 +422,9 @@ foreign import ccall foreign import ccall "pgf/pgf.h pgf_parse_with_oracle" pgf_parse_with_oracle :: Ptr PgfConcr -> CString -> CString -> Ptr PgfOracleCallback -> Ptr GuExn -> Ptr GuPool -> Ptr GuPool -> IO (Ptr GuEnum) +foreign import ccall "pgf/pgf.h pgf_complete" + pgf_complete :: Ptr PgfConcr -> PgfType -> CString -> CString -> Ptr GuExn -> Ptr GuPool -> IO (Ptr GuEnum) + foreign import ccall "pgf/pgf.h pgf_lookup_morpho" pgf_lookup_morpho :: Ptr PgfConcr -> CString -> Ptr PgfMorphoCallback -> Ptr GuExn -> IO () diff --git a/src/runtime/haskell-bind/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal index 4ef9ed4f0..91e77c77b 100644 --- a/src/runtime/haskell-bind/pgf2.cabal +++ b/src/runtime/haskell-bind/pgf2.cabal @@ -1,5 +1,5 @@ name: pgf2 -version: 1.2.1 +version: 1.3.0 synopsis: Bindings to the C version of the PGF runtime description: GF, Grammatical Framework, is a programming language for multilingual grammar applications. diff --git a/src/runtime/haskell-bind/test.hs b/src/runtime/haskell-bind/test.hs new file mode 100644 index 000000000..16e7ff7cb --- /dev/null +++ b/src/runtime/haskell-bind/test.hs @@ -0,0 +1,12 @@ +import PGF2 +import qualified Data.Map as M + +main :: IO () +main = do + pgf <- readPGF "/Users/john/repositories/GF/contrib/foods/Foods.pgf" + let Just concr = M.lookup "FoodsEng" (languages pgf) + let pr = complete concr (startCat pgf) "this" "wi" Nothing + case pr of + ParseOk x -> print (head x) + ParseFailed _ _ -> putStrLn "parse failed" + ParseIncomplete -> putStrLn "input incomplete" From e56d1b29593bef6ea3a70b50287df3e3438207d7 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 14:25:35 +0200 Subject: [PATCH 18/75] Second attempt. Reading enum is closer to working but all strings are empty. --- src/runtime/haskell-bind/PGF2.hsc | 32 ++++++++++++++++++++++--------- src/runtime/haskell-bind/test.hs | 4 ++-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc index bd7cf2fe9..21e8693eb 100644 --- a/src/runtime/haskell-bind/PGF2.hsc +++ b/src/runtime/haskell-bind/PGF2.hsc @@ -977,30 +977,44 @@ complete :: Concr -- ^ the language with which we parse -> String -- ^ the input sentence -> String -- ^ prefix (?) -> Maybe Int -- ^ maximum number of results - -> ParseOutput [(Expr,Float)] + -> ParseOutput [String] complete lang (Type ctype _) sent pfx mn = unsafePerformIO $ do parsePl <- gu_new_pool - exprPl <- gu_new_pool exn <- gu_new_exn parsePl - sent <- newUtf8CString sent parsePl pfx <- newUtf8CString pfx parsePl - enum <- pgf_complete (concr lang) ctype sent pfx exn parsePl failed <- gu_exn_is_raised exn if failed then do + -- TODO better error handling, cleanup is_parse_error <- gu_exn_caught exn gu_exn_type_PgfParseError if is_parse_error then return (ParseFailed 0 "") else throwIO (PGFError "Some other error") - -- TODO cleanup!!! else do - parseFPl <- newForeignPtr gu_pool_finalizer parsePl - exprFPl <- newForeignPtr gu_pool_finalizer exprPl - exprs <- fromPgfExprEnum enum parseFPl (touchConcr lang >> touchForeignPtr exprFPl) - return (ParseOk exprs) + fpl <- newForeignPtr gu_pool_finalizer parsePl + ParseOk <$> fromCompletions enum fpl + where + fromCompletions :: Ptr GuEnum -> ForeignPtr GuPool -> IO [String] + fromCompletions enum fpl = + withGuPool $ \tmpPl -> do + cmpEntry <- alloca $ \ptr -> + withForeignPtr fpl $ \pl -> + do gu_enum_next enum ptr pl + peek ptr + if cmpEntry == nullPtr + then do + finalizeForeignPtr fpl + touchConcr lang + return [] + else do + (sb,out) <- newOut tmpPl + cstr <- gu_string_buf_freeze sb tmpPl + tok <- peekUtf8CString cstr + toks <- unsafeInterleaveIO (fromCompletions enum fpl) + return (tok : toks) -- | Returns True if there is a linearization defined for that function in that language hasLinearization :: Concr -> Fun -> Bool diff --git a/src/runtime/haskell-bind/test.hs b/src/runtime/haskell-bind/test.hs index 16e7ff7cb..26836445f 100644 --- a/src/runtime/haskell-bind/test.hs +++ b/src/runtime/haskell-bind/test.hs @@ -5,8 +5,8 @@ main :: IO () main = do pgf <- readPGF "/Users/john/repositories/GF/contrib/foods/Foods.pgf" let Just concr = M.lookup "FoodsEng" (languages pgf) - let pr = complete concr (startCat pgf) "this" "wi" Nothing + let pr = complete concr (startCat pgf) "" "th" Nothing case pr of - ParseOk x -> print (head x) + ParseOk x -> print x ParseFailed _ _ -> putStrLn "parse failed" ParseIncomplete -> putStrLn "input incomplete" From 437bd8e7f956ec645aa5261cbb9085741c8398cd Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 20:36:31 +0200 Subject: [PATCH 19/75] Add proper error handling in complete --- src/runtime/haskell-bind/PGF2.hsc | 22 +++++++++++++++++++--- src/runtime/haskell-bind/test.hs | 18 ++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc index 21e8693eb..b3b349ee1 100644 --- a/src/runtime/haskell-bind/PGF2.hsc +++ b/src/runtime/haskell-bind/PGF2.hsc @@ -988,11 +988,27 @@ complete lang (Type ctype _) sent pfx mn = failed <- gu_exn_is_raised exn if failed then do - -- TODO better error handling, cleanup is_parse_error <- gu_exn_caught exn gu_exn_type_PgfParseError if is_parse_error - then return (ParseFailed 0 "") - else throwIO (PGFError "Some other error") + then do + c_err <- (#peek GuExn, data.data) exn + c_offset <- (#peek PgfParseError, offset) c_err + token_ptr <- (#peek PgfParseError, token_ptr) c_err + token_len <- (#peek PgfParseError, token_len) c_err + tok <- peekUtf8CStringLen token_ptr token_len + gu_pool_free parsePl + return (ParseFailed (fromIntegral (c_offset :: CInt)) tok) + else do + is_exn <- gu_exn_caught exn gu_exn_type_PgfExn + if is_exn + then do + c_msg <- (#peek GuExn, data.data) exn + msg <- peekUtf8CString c_msg + gu_pool_free parsePl + throwIO (PGFError msg) + else do + gu_pool_free parsePl + throwIO (PGFError "Parsing failed") else do fpl <- newForeignPtr gu_pool_finalizer parsePl ParseOk <$> fromCompletions enum fpl diff --git a/src/runtime/haskell-bind/test.hs b/src/runtime/haskell-bind/test.hs index 26836445f..4d345c90c 100644 --- a/src/runtime/haskell-bind/test.hs +++ b/src/runtime/haskell-bind/test.hs @@ -4,9 +4,15 @@ import qualified Data.Map as M main :: IO () main = do pgf <- readPGF "/Users/john/repositories/GF/contrib/foods/Foods.pgf" - let Just concr = M.lookup "FoodsEng" (languages pgf) - let pr = complete concr (startCat pgf) "" "th" Nothing - case pr of - ParseOk x -> print x - ParseFailed _ _ -> putStrLn "parse failed" - ParseIncomplete -> putStrLn "input incomplete" + let + Just concr = M.lookup "FoodsEng" (languages pgf) + loop = do + putStr "> " + tks <- words <$> getLine + let pr = complete concr (startCat pgf) (unwords (init tks)) (last tks) Nothing + case pr of + ParseOk x -> print x + ParseFailed x s -> putStrLn $ "parse failed at " ++ show x ++ " " ++ s + ParseIncomplete -> putStrLn "input incomplete" + loop + loop From 588cd6ddb16350ed947a975a28315806164fe651 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 20:51:24 +0200 Subject: [PATCH 20/75] Improvement to test script, distinguishes when input ends with whitespace --- src/runtime/haskell-bind/test.hs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/runtime/haskell-bind/test.hs b/src/runtime/haskell-bind/test.hs index 4d345c90c..1c0c9fa87 100644 --- a/src/runtime/haskell-bind/test.hs +++ b/src/runtime/haskell-bind/test.hs @@ -1,4 +1,6 @@ import PGF2 +import qualified Data.Char as C +import qualified Data.List as L import qualified Data.Map as M main :: IO () @@ -8,8 +10,13 @@ main = do Just concr = M.lookup "FoodsEng" (languages pgf) loop = do putStr "> " - tks <- words <$> getLine - let pr = complete concr (startCat pgf) (unwords (init tks)) (last tks) Nothing + input <- getLine + let + (sent,pfx) = + if C.isSpace (last input) + then (input, "") + else let toks = words input in (unwords (init toks), last toks) + let pr = complete concr (startCat pgf) sent pfx Nothing case pr of ParseOk x -> print x ParseFailed x s -> putStrLn $ "parse failed at " ++ show x ++ " " ++ s From 84fd431afd54644bbe4bfc2c09c444f5a99e35cb Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 3 May 2021 22:28:48 +0200 Subject: [PATCH 21/75] Manage to get completion working in PGF2 --- src/runtime/haskell-bind/PGF2.hsc | 23 ++++++++++++----------- src/runtime/haskell-bind/PGF2/FFI.hsc | 1 + src/runtime/haskell-bind/test.hs | 25 ------------------------- 3 files changed, 13 insertions(+), 36 deletions(-) delete mode 100644 src/runtime/haskell-bind/test.hs diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc index b3b349ee1..38fae67ef 100644 --- a/src/runtime/haskell-bind/PGF2.hsc +++ b/src/runtime/haskell-bind/PGF2.hsc @@ -972,13 +972,13 @@ parseWithOracle lang cat sent (predict,complete,literal) = return ep Nothing -> do return nullPtr +-- | Returns possible completions of the current partial input. complete :: Concr -- ^ the language with which we parse - -> Type -- ^ the start category - -> String -- ^ the input sentence - -> String -- ^ prefix (?) - -> Maybe Int -- ^ maximum number of results - -> ParseOutput [String] -complete lang (Type ctype _) sent pfx mn = + -> Type -- ^ the start category + -> String -- ^ the input sentence (excluding token being completed) + -> String -- ^ prefix (partial token being completed) + -> ParseOutput [(String, CId, CId, Float)] -- ^ (token, category, function, probability) +complete lang (Type ctype _) sent pfx = unsafePerformIO $ do parsePl <- gu_new_pool exn <- gu_new_exn parsePl @@ -1013,7 +1013,7 @@ complete lang (Type ctype _) sent pfx mn = fpl <- newForeignPtr gu_pool_finalizer parsePl ParseOk <$> fromCompletions enum fpl where - fromCompletions :: Ptr GuEnum -> ForeignPtr GuPool -> IO [String] + fromCompletions :: Ptr GuEnum -> ForeignPtr GuPool -> IO [(String, CId, CId, Float)] fromCompletions enum fpl = withGuPool $ \tmpPl -> do cmpEntry <- alloca $ \ptr -> @@ -1026,11 +1026,12 @@ complete lang (Type ctype _) sent pfx mn = touchConcr lang return [] else do - (sb,out) <- newOut tmpPl - cstr <- gu_string_buf_freeze sb tmpPl - tok <- peekUtf8CString cstr + tok <- peekUtf8CString =<< (#peek PgfTokenProb, tok) cmpEntry + cat <- peekUtf8CString =<< (#peek PgfTokenProb, cat) cmpEntry + fun <- peekUtf8CString =<< (#peek PgfTokenProb, fun) cmpEntry + prob <- (#peek PgfTokenProb, prob) cmpEntry toks <- unsafeInterleaveIO (fromCompletions enum fpl) - return (tok : toks) + return ((tok, cat, fun, prob) : toks) -- | Returns True if there is a linearization defined for that function in that language hasLinearization :: Concr -> Fun -> Bool diff --git a/src/runtime/haskell-bind/PGF2/FFI.hsc b/src/runtime/haskell-bind/PGF2/FFI.hsc index 04952f2d8..16f9ad46d 100644 --- a/src/runtime/haskell-bind/PGF2/FFI.hsc +++ b/src/runtime/haskell-bind/PGF2/FFI.hsc @@ -256,6 +256,7 @@ data PgfApplication data PgfConcr type PgfExpr = Ptr () data PgfExprProb +data PgfTokenProb data PgfExprParser data PgfFullFormEntry data PgfMorphoCallback diff --git a/src/runtime/haskell-bind/test.hs b/src/runtime/haskell-bind/test.hs deleted file mode 100644 index 1c0c9fa87..000000000 --- a/src/runtime/haskell-bind/test.hs +++ /dev/null @@ -1,25 +0,0 @@ -import PGF2 -import qualified Data.Char as C -import qualified Data.List as L -import qualified Data.Map as M - -main :: IO () -main = do - pgf <- readPGF "/Users/john/repositories/GF/contrib/foods/Foods.pgf" - let - Just concr = M.lookup "FoodsEng" (languages pgf) - loop = do - putStr "> " - input <- getLine - let - (sent,pfx) = - if C.isSpace (last input) - then (input, "") - else let toks = words input in (unwords (init toks), last toks) - let pr = complete concr (startCat pgf) sent pfx Nothing - case pr of - ParseOk x -> print x - ParseFailed x s -> putStrLn $ "parse failed at " ++ show x ++ " " ++ s - ParseIncomplete -> putStrLn "input incomplete" - loop - loop From eeda03e9b065ee74905b6d593aa88912c78ef8bb Mon Sep 17 00:00:00 2001 From: krangelov Date: Wed, 5 May 2021 15:04:15 +0200 Subject: [PATCH 22/75] added news --- index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.html b/index.html index 857f6b153..c8a990fd6 100644 --- a/index.html +++ b/index.html @@ -228,6 +228,10 @@ least one, it may help you to get a first idea of what GF is.

News

+
2021-05-05
+
+ GF WordNet now supports languages for which there are no other WordNets. New additions: Afrikaans, German, Korean, Maltese, Polish, Somali, Swahili. +
2021-03-01
Seventh GF Summer School, in Singapore and online, 26 July – 8 August 2021. From af1360d37e2e94e257f866b99f3fd41a37162a03 Mon Sep 17 00:00:00 2001 From: krangelov Date: Thu, 27 May 2021 11:45:31 +0200 Subject: [PATCH 23/75] allow parameter cat in the Web API for parsing --- src/server/PGFService.hs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs index e30ff8652..3f5307571 100644 --- a/src/server/PGFService.hs +++ b/src/server/PGFService.hs @@ -151,29 +151,37 @@ getFile get path = cpgfMain qsem command (t,(pgf,pc)) = case command of "c-parse" -> withQSem qsem $ - out t=<< join (parse # input % start % limit % treeopts) + out t=<< join (parse # input % cat % start % limit % treeopts) "c-parseToChart"-> withQSem qsem $ - out t=<< join (parseToChart # input % limit) + out t=<< join (parseToChart # input % cat % limit) "c-linearize" -> out t=<< lin # tree % to "c-bracketedLinearize" -> out t=<< bracketedLin # tree % to "c-linearizeAll"-> out t=<< linAll # tree % to "c-translate" -> withQSem qsem $ - out t=< out t=<< morpho # from1 % textInput "c-lookupcohorts"->out t=<< cohorts # from1 % getInput "filter" % textInput "c-flush" -> out t=<< flush "c-grammar" -> out t grammar "c-abstrtree" -> outputGraphviz=<< C.graphvizAbstractTree pgf C.graphvizDefaults # tree "c-parsetree" -> outputGraphviz=<< (\cnc -> C.graphvizParseTree cnc C.graphvizDefaults) . snd # from1 %tree - "c-wordforword" -> out t =<< wordforword # input % to + "c-wordforword" -> out t =<< wordforword # input % cat % to _ -> badRequest "Unknown command" command where flush = liftIO $ do --modifyMVar_ pc $ const $ return Map.empty performGC return $ showJSON () - cat = C.startCat pgf + cat :: CGI C.Type + cat = + do mcat <- getInput1 "cat" + case mcat of + Nothing -> return (C.startCat pgf) + Just cat -> case C.readType cat of + Nothing -> badRequest "Bad category" cat + Just typ -> return typ + langs = C.languages pgf grammar = showJSON $ makeObj @@ -184,8 +192,8 @@ cpgfMain qsem command (t,(pgf,pc)) = where languages = [makeObj ["name".= l] | (l,_)<-Map.toList langs] - parse input@((from,_),_) start mlimit (trie,json) = - do r <- parse' start mlimit input + parse input@((from,_),_) cat start mlimit (trie,json) = + do r <- parse' cat start mlimit input return $ showJSON [makeObj ("from".=from:jsonParseResult json r)] jsonParseResult json = either bad good @@ -195,7 +203,7 @@ cpgfMain qsem command (t,(pgf,pc)) = tp (tree,prob) = makeObj (addTree json tree++["prob".=prob]) -- Without caching parse results: - parse' start mlimit ((from,concr),input) = + parse' cat start mlimit ((from,concr),input) = case C.parseWithHeuristics concr cat input (-1) callbacks of C.ParseOk ts -> return (Right (maybe id take mlimit (drop start ts))) C.ParseFailed _ tok -> return (Left tok) @@ -221,7 +229,7 @@ cpgfMain qsem command (t,(pgf,pc)) = -- remove unused parse results after 2 minutes -} - parseToChart ((from,concr),input) mlimit = + parseToChart ((from,concr),input) cat mlimit = do r <- case C.parseToChart concr cat input (-1) callbacks (fromMaybe 5 mlimit) of C.ParseOk chart -> return (good chart) C.ParseFailed _ tok -> return (bad tok) @@ -262,8 +270,8 @@ cpgfMain qsem command (t,(pgf,pc)) = bracketedLin' tree (tos,unlex) = [makeObj ["to".=to,"brackets".=showJSON (C.bracketedLinearize c tree)]|(to,c)<-tos] - trans input@((from,_),_) to start mlimit (trie,jsontree) = - do parses <- parse' start mlimit input + trans input@((from,_),_) cat to start mlimit (trie,jsontree) = + do parses <- parse' cat start mlimit input return $ showJSON [ makeObj ["from".=from, "translations".= jsonParses parses]] @@ -297,7 +305,7 @@ cpgfMain qsem command (t,(pgf,pc)) = _ -> id) (C.lookupCohorts concr input)] - wordforword input@((from,_),_) = jsonWFW from . wordforword' input + wordforword input@((from,_),_) cat = jsonWFW from . wordforword' input cat jsonWFW from rs = showJSON @@ -307,7 +315,7 @@ cpgfMain qsem command (t,(pgf,pc)) = [makeObj["to".=to,"text".=text] | (to,text)<-rs]]]]] - wordforword' inp@((from,concr),input) (tos,unlex) = + wordforword' inp@((from,concr),input) cat (tos,unlex) = [(to,unlex . unwords $ map (lin_word' c) pws) |let pws=map parse_word' (words input),(to,c)<-tos] where From 098541dda21cc10d6a4062e8aa1617d75b10bdd3 Mon Sep 17 00:00:00 2001 From: Jacob Tan En Date: Wed, 9 Jun 2021 18:31:16 +0800 Subject: [PATCH 24/75] Update index-3.11.md `Cabal install` is fragile and can fail if the GHC on path is of an incompatible version. Use ghcup to use a GHC version that is known to work. --- download/index-3.11.md | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/download/index-3.11.md b/download/index-3.11.md index c128e77ce..0ebf0f031 100644 --- a/download/index-3.11.md +++ b/download/index-3.11.md @@ -49,15 +49,17 @@ 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). -## Installing the latest release from source +## Installing the latest Hackage release (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: -1. Install a recent version of the [Haskell Platform](http://hackage.haskell.org/platform) (see note below) -2. `cabal update` -3. On Linux: install some C libraries from your Linux distribution (see note below) -4. `cabal install gf` +1. Install ghcup https://www.haskell.org/ghcup/ +2. `ghcup install ghc 8.10.4` +3. `ghcup set ghc 8.10.4` +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**. @@ -74,17 +76,6 @@ so you might want to add this directory to your path (in `.bash_profile` or simi PATH=$HOME/.cabal/bin:$PATH ``` -**Build tools** - -In order to compile GF you need the build tools **Alex** and **Happy**. -These can be installed via Cabal, e.g.: - -``` -cabal install alex happy -``` - -or obtained by other means, depending on your OS. - **Haskeline** GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which From de8b23c0146499a83338c03fe0e4e262b2799786 Mon Sep 17 00:00:00 2001 From: Jacob Tan En Date: Wed, 9 Jun 2021 19:56:08 +0800 Subject: [PATCH 25/75] Update gf.cabal `cabal install` needs this --- gf.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/gf.cabal b/gf.cabal index 0076e7638..b29972509 100644 --- a/gf.cabal +++ b/gf.cabal @@ -14,6 +14,7 @@ maintainer: Thomas Hallgren tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3 data-dir: src +extra-source-files: WebSetup.hs data-files: www/*.html www/*.css From e5b8fa095b9209d2265f409362035e447caf96b6 Mon Sep 17 00:00:00 2001 From: Tristan Koh Date: Thu, 10 Jun 2021 12:00:57 +0800 Subject: [PATCH 26/75] changed build wheels repo link from master to main --- .github/workflows/build-python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index 6326821dc..67cbba6dd 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -25,7 +25,7 @@ jobs: - name: Install cibuildwheel run: | - python -m pip install git+https://github.com/joerick/cibuildwheel.git@master + python -m pip install git+https://github.com/joerick/cibuildwheel.git@main - name: Install build tools for OSX if: startsWith(matrix.os, 'macos') From 67fcf215779fae4d030da5f2236c89ad27731bc1 Mon Sep 17 00:00:00 2001 From: 1Regina <46968488+1Regina@users.noreply.github.com> Date: Fri, 11 Jun 2021 11:43:41 +0800 Subject: [PATCH 27/75] remove testsuite/libraries --- testsuite/libraries/exx-resource.gfs | 226 ----- testsuite/libraries/exx-resource.gfs.gold | 1032 --------------------- 2 files changed, 1258 deletions(-) delete mode 100644 testsuite/libraries/exx-resource.gfs delete mode 100644 testsuite/libraries/exx-resource.gfs.gold diff --git a/testsuite/libraries/exx-resource.gfs b/testsuite/libraries/exx-resource.gfs deleted file mode 100644 index 31163a1bd..000000000 --- a/testsuite/libraries/exx-resource.gfs +++ /dev/null @@ -1,226 +0,0 @@ -se utf8 -i alltenses/LangEng.gfo -i alltenses/LangSwe.gfo -i alltenses/LangBul.gfo --- Adjective - -l -treebank PositA warm_A -l -treebank ComparA warm_A (UsePron i_Pron) -l -treebank ComplA2 married_A2 (UsePron she_Pron) -l -treebank ComplA2 married_A2 (DetNP (DetQuant (PossPron she_Pron) NumPl)) -l -treebank ComplA2 married_A2 (DetNP (DetQuant (PossPron she_Pron) NumSg)) -l -treebank ReflA2 married_A2 -l -treebank PositA (UseA2 married_A2) -l -treebank SentAP (PositA good_A) (EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseComp (CompAdv here_Adv))))) -l -treebank AdAP very_AdA (PositA warm_A) - - --- Adverb - -l -treebank PositAdvAdj warm_A -l -treebank PrepNP in_Prep (DetCN (DetQuant DefArt NumSg) (UseN house_N)) -l -treebank ComparAdvAdj more_CAdv warm_A (UsePN john_PN) -l -treebank ComparAdvAdjS more_CAdv warm_A (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV run_V))) -l -treebank SubjS when_Subj (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) -l -treebank AdNum (AdnCAdv more_CAdv) (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))) - - --- Conjunction - -l -treebank ConjS and_Conj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV walk_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -l -treebank ConjAP and_Conj (BaseAP (PositA cold_A) (PositA warm_A)) -l -treebank ConjNP or_Conj (BaseNP (UsePron she_Pron) (UsePron we_Pron)) -l -treebank ConjAdv or_Conj (BaseAdv here_Adv there_Adv) -l -treebank ConjS either7or_DConj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV walk_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -l -treebank ConjAP both7and_DConj (BaseAP (PositA warm_A) (PositA cold_A)) -l -treebank ConjNP either7or_DConj (BaseNP (UsePron he_Pron) (UsePron she_Pron)) -l -treebank ConjAdv both7and_DConj (BaseAdv here_Adv there_Adv) - --- Idiom - -l -treebank ImpersCl (UseComp (CompAP (PositA hot_A))) -l -treebank GenericCl (UseV sleep_V) -l -treebank CleftNP (UsePron i_Pron) (UseRCl (TTAnt TPast ASimul) PPos (RelVP IdRP (ComplSlash (SlashV2a do_V2) (UsePron it_Pron)))) -l -treebank CleftAdv here_Adv (UseCl (TTAnt TPast ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) -l -treebank ExistNP (DetCN (DetQuant IndefArt NumSg) (UseN house_N)) -l -treebank ExistIP (IdetCN (IdetQuant which_IQuant NumPl) (UseN house_N)) -l -treebank PredVP (UsePron i_Pron) (ProgrVP (UseV sleep_V)) -l -treebank ImpPl1 (UseV go_V) - --- Noun - -l -treebank DetCN (DetQuant DefArt NumSg) (UseN man_N) -l -treebank UsePN john_PN -l -treebank UsePron he_Pron -l -treebank PredetNP only_Predet (DetCN (DetQuant DefArt NumSg) (UseN man_N)) -l -treebank PPartNP (DetCN (DetQuant DefArt NumSg) (UseN man_N)) see_V2 -l -treebank AdvNP (UsePN paris_PN) today_Adv -l -treebank RelNP (UsePN paris_PN) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (UseComp (CompAdv here_Adv)))) -l -treebank DetNP (DetQuant this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) -l -treebank DetCN (DetQuantOrd this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5))))))) (OrdSuperl good_A)) (UseN man_N) -l -treebank DetCN (DetQuant this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN man_N) -l -treebank DetCN (DetQuant this_Quant NumPl) (UseN man_N) -l -treebank DetCN (DetQuant this_Quant NumSg) (UseN man_N) -l -treebank NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))) -l -treebank NumCard (NumDigits (IIDig D_5 (IDig D_1))) -l -treebank NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot1plus n5 pot01))))) -l -treebank NumCard (AdNum almost_AdN (NumDigits (IIDig D_5 (IDig D_1)))) -l -treebank OrdDigits (IIDig D_5 (IDig D_1)) -l -treebank OrdNumeral (num (pot2as3 (pot1as2 (pot1plus n5 pot01)))) -l -treebank OrdSuperl warm_A -l -treebank DetCN (DetQuantOrd DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5))))))) (OrdSuperl good_A)) (UseN man_N) -l -treebank DetCN (DetQuant DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN man_N) -l -treebank DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 pot01))))))) (UseN man_N) -l -treebank DetCN (DetQuant DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 pot01))))))) (UseN man_N) -l -treebank DetCN (DetQuant DefArt NumSg) (UseN man_N) -l -treebank DetCN (DetQuant DefArt NumPl) (UseN man_N) -l -treebank MassNP (UseN beer_N) -l -treebank DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN house_N) -l -treebank UseN house_N -l -treebank ComplN2 mother_N2 (DetCN (DetQuant DefArt NumSg) (UseN king_N)) -l -treebank ComplN2 (ComplN3 distance_N3 (DetCN (DetQuant this_Quant NumSg) (UseN city_N))) (UsePN paris_PN) -l -treebank UseN2 mother_N2 -l -treebank ComplN2 (Use2N3 distance_N3) (DetCN (DetQuant this_Quant NumSg) (UseN city_N)) -l -treebank ComplN2 (Use3N3 distance_N3) (UsePN paris_PN) -l -treebank UseN2 (Use2N3 distance_N3) -l -treebank AdjCN (PositA big_A) (UseN house_N) -l -treebank RelCN (UseN house_N) (UseRCl (TTAnt TPast ASimul) PPos (RelSlash IdRP (SlashVP (UsePN john_PN) (SlashV2a buy_V2)))) -l -treebank AdvCN (UseN house_N) (PrepNP on_Prep (DetCN (DetQuant DefArt NumSg) (UseN hill_N))) -l -treebank SentCN (UseN question_N) (EmbedQS (UseQCl (TTAnt TPres ASimul) PPos (QuestIAdv where_IAdv (PredVP (UsePron she_Pron) (UseV sleep_V))))) -l -treebank DetCN (DetQuant DefArt NumSg) (ApposCN (UseN city_N) (UsePN paris_PN)) -l -treebank DetCN (DetQuant (PossPron i_Pron) NumSg) (ApposCN (UseN friend_N) (UsePN john_PN)) - --- Numeral - -l -treebank num (pot2as3 (pot1as2 (pot0as1 (pot0 n6)))) -l -treebank num (pot2as3 (pot1as2 (pot0as1 pot01))) -l -treebank num (pot2as3 (pot1as2 (pot1 n6))) -l -treebank num (pot2as3 (pot1as2 pot110)) -l -treebank num (pot2as3 (pot1as2 pot111)) -l -treebank num (pot2as3 (pot1as2 (pot1to19 n6))) -l -treebank num (pot2as3 (pot1as2 (pot1 n6))) -l -treebank num (pot2as3 (pot1as2 (pot1plus n6 (pot0 n5)))) -l -treebank num (pot2as3 (pot2 (pot0 n4))) -l -treebank num (pot2as3 (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7)))) -l -treebank num (pot3 (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7)))) -l -treebank num (pot3plus (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7))) (pot1as2 (pot1plus n8 (pot0 n9)))) -l -treebank IDig D_8 -l -treebank IIDig D_8 (IIDig D_0 (IIDig D_0 (IIDig D_1 (IIDig D_7 (IIDig D_8 (IDig D_9)))))) - - --- Phrase - -l -treebank PhrUtt but_PConj (UttImpSg PPos (ImpVP (AdvVP (UseV come_V) here_Adv))) (VocNP (DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN friend_N))) -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePN john_PN) (UseV walk_V)))) NoVoc -l -treebank UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestCl (PredVP (UsePron it_Pron) (UseComp (CompAP (PositA good_A)))))) -l -treebank UttImpSg PNeg (ImpVP (ReflVP (SlashV2a love_V2))) -l -treebank UttImpPl PNeg (ImpVP (ReflVP (SlashV2a love_V2))) -l -treebank UttImpPol PNeg (ImpVP (UseV sleep_V)) -l -treebank UttIP whoPl_IP -l -treebank UttIP whoSg_IP -l -treebank UttIAdv why_IAdv -l -treebank UttNP (DetCN (DetQuant this_Quant NumSg) (UseN man_N)) -l -treebank UttAdv here_Adv -l -treebank UttVP (UseV sleep_V) -l -treebank VocNP (DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN friend_N)) - - --- Question - -l -treebank QuestCl (PredVP (UsePN john_PN) (UseV walk_V)) -l -treebank QuestVP whoSg_IP (UseV walk_V) -l -treebank QuestSlash whoSg_IP (SlashVP (UsePN john_PN) (SlashV2a love_V2)) -l -treebank QuestIAdv why_IAdv (PredVP (UsePN john_PN) (UseV walk_V)) -l -treebank QuestIComp (CompIAdv where_IAdv) (UsePN john_PN) -l -treebank IdetCN (IdetQuant which_IQuant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN song_N) -l -treebank IdetIP (IdetQuant which_IQuant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) -l -treebank AdvIP whoSg_IP (PrepNP in_Prep (UsePN paris_PN)) -l -treebank IdetIP (IdetQuant which_IQuant NumSg) -l -treebank PrepIP with_Prep whoSg_IP -l -treebank QuestIComp (CompIAdv where_IAdv) (UsePron it_Pron) -l -treebank QuestIComp (CompIP whoSg_IP) (UsePron it_Pron) - - --- Relative - -l -treebank ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelCl (PredVP (UsePN john_PN) (ComplSlash (SlashV2a love_V2) (UsePron she_Pron))))))) -l -treebank ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (ComplSlash (SlashV2a love_V2) (UsePN john_PN)))))) -l -treebank ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePN john_PN) (SlashV2a love_V2)))))) -l -treebank ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash (FunRP possess_Prep (DetCN (DetQuant DefArt NumSg) (UseN2 mother_N2)) IdRP) (SlashVP (UsePN john_PN) (SlashV2a love_V2)))))) - --- Sentence - -l -treebank PredVP (UsePN john_PN) (UseV walk_V) -l -treebank PredSCVP (EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV go_V)))) (UseComp (CompAP (PositA good_A))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron he_Pron) (SlashV2a see_V2)))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (AdvSlash (SlashVP (UsePron he_Pron) (SlashV2a see_V2)) today_Adv))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashPrep (PredVP (UsePron he_Pron) (UseV walk_V)) with_Prep))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVS (UsePron she_Pron) say_VS (UseSlash (TTAnt TPres ASimul) PPos (SlashVP (UsePron he_Pron) (SlashV2a love_V2)))))) -l -treebank ImpVP (ReflVP (SlashV2a love_V2)) -l -treebank EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV go_V))) -l -treebank EmbedQS (UseQCl (TTAnt TPres ASimul) PPos (QuestVP whoSg_IP (UseV go_V))) -l -treebank EmbedVP (UseV go_V) -l -treebank UseCl (TTAnt TCond AAnter) PNeg (PredVP (UsePN john_PN) (UseV walk_V)) -l -treebank UseQCl (TTAnt TCond AAnter) PNeg (QuestCl (PredVP (UsePN john_PN) (UseV walk_V))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TCond AAnter) PNeg (RelVP IdRP (UseV walk_V))) -l -treebank RelCN (UseN girl_N) (UseRCl (TTAnt TCond AAnter) PNeg (RelSlash IdRP (SlashPrep (PredVP (UsePron i_Pron) (UseV walk_V)) with_Prep))) -l -treebank RelS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (UseComp (CompAP (PositA good_A))))) - - --- Text - -l -treebank TEmpty -l -treebank TFullStop (PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePN john_PN) (UseV walk_V)))) NoVoc) TEmpty -l -treebank TQuestMark (PhrUtt NoPConj (UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestCl (PredVP (UsePron they_Pron) (UseComp (CompAdv here_Adv)))))) NoVoc) TEmpty -l -treebank TExclMark (PhrUtt NoPConj (ImpPl1 (UseV go_V)) NoVoc) TEmpty - --- Verb - -l -treebank PredVP (UsePron i_Pron) (UseV sleep_V) -l -treebank PredVP (UsePron i_Pron) (ComplVV want_VV (UseV run_V)) -l -treebank PredVP (UsePron i_Pron) (ComplVS say_VS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -l -treebank PredVP (UsePron i_Pron) (ComplVQ wonder_VQ (UseQCl (TTAnt TPres ASimul) PPos (QuestVP whoSg_IP (UseV run_V)))) -l -treebank PredVP (UsePron they_Pron) (ComplVA become_VA (PositA red_A)) -l -treebank PredVP (UsePron i_Pron) (ComplSlash (Slash3V3 give_V3 (UsePron he_Pron)) (UsePron it_Pron)) -l -treebank PredVP (UsePron i_Pron) (ComplSlash (SlashV2V beg_V2V (UseV go_V)) (UsePron she_Pron)) -l -treebank PredVP (UsePron i_Pron) (ComplSlash (SlashV2S answer_V2S (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron it_Pron) (UseComp (CompAP (PositA good_A)))))) (UsePron he_Pron)) -l -treebank PredVP (UsePron i_Pron) (ComplSlash (SlashV2Q ask_V2Q (UseQCl (TTAnt TPast ASimul) PPos (QuestVP whoSg_IP (UseV come_V)))) (UsePron he_Pron)) -l -treebank PredVP (UsePron i_Pron) (ComplSlash (SlashV2A paint_V2A (PositA red_A)) (UsePron it_Pron)) -l -treebank RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron i_Pron) (SlashVV want_VV (SlashV2a buy_V2))))) -l -treebank RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron they_Pron) (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashV2a buy_V2))))) -l -treebank PredVP (UsePron he_Pron) (ReflVP (SlashV2a love_V2)) -l -treebank PredVP (DetNP (DetQuant this_Quant NumSg)) (UseComp (CompAP (PositA warm_A))) -l -treebank PredVP (UsePron we_Pron) (PassV2 love_V2) -l -treebank PredVP (UsePron we_Pron) (AdvVP (UseV sleep_V) here_Adv) -l -treebank PredVP (UsePron we_Pron) (AdVVP always_AdV (UseV sleep_V)) -l -treebank PredVP (UsePron we_Pron) (UseComp (CompAP (PositA small_A))) -l -treebank PredVP (UsePron i_Pron) (UseComp (CompNP (DetCN (DetQuant IndefArt NumSg) (UseN man_N)))) -l -treebank PredVP (UsePron i_Pron) (UseComp (CompAdv here_Adv)) - - - --- Janna's and Krasimir's long examples - -l -treebank RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron they_Pron) (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashVV want_VV (SlashV2A paint_V2A (PositA red_A))))))) -l -treebank PhrUtt NoPConj (UttImpSg PPos (ImpVP (AdVVP always_AdV (ComplSlash (SlashV2a listen_V2) (DetCN (DetQuant DefArt NumSg) (UseN sea_N)))))) NoVoc -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (ExistNP (PredetNP only_Predet (DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n2)))))))) (AdvCN (RelCN (UseN woman_N) (UseRCl (TTAnt TCond ASimul) PPos (RelSlash IdRP (SlashPrep (PredVP (UsePron i_Pron) (ComplVV want_VV (PassV2 see_V2))) with_Prep)))) (PrepNP in_Prep (DetCN (DetQuant DefArt NumSg) (UseN rain_N))))))))) NoVoc -l -treebank PhrUtt NoPConj (UttImpSg PPos (ImpVP (ComplSlash (SlashV2A paint_V2A (ConjAP both7and_DConj (BaseAP (ComparA small_A (DetCN (DetQuant DefArt NumSg) (UseN sun_N))) (ComparA big_A (DetCN (DetQuant DefArt NumSg) (UseN moon_N)))))) (DetCN (DetQuant DefArt NumSg) (UseN earth_N))))) NoVoc -l -treebank PhrUtt NoPConj (ImpPl1 (ComplVS hope_VS (ConjS either7or_DConj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumSg) (ComplN2 father_N2 (DetCN (DetQuant DefArt NumSg) (UseN baby_N)))) (UseV run_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumSg) (UseN2 (Use2N3 distance_N3))) (UseComp (CompAP (PositA small_A))))))))) NoVoc -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN every_Det (UseN baby_N)) (UseComp (CompNP (ConjNP either7or_DConj (BaseNP (DetCN (DetQuant IndefArt NumSg) (UseN boy_N)) (DetCN (DetQuant IndefArt NumSg) (UseN girl_N))))))))) NoVoc -l -treebank PhrUtt NoPConj (UttAdv (ConjAdv either7or_DConj (ConsAdv here7from_Adv (BaseAdv there_Adv everywhere_Adv)))) NoVoc -l -treebank PhrUtt NoPConj (UttVP (PassV2 know_V2)) NoVoc -l -treebank RelCN (UseN bird_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron i_Pron) (SlashVV want_VV (SlashV2A paint_V2A (PositA red_A)))))) -l -treebank UttImpSg PPos (ImpVP (ComplVV want_VV (ComplSlash (SlashV2a buy_V2) (UsePron it_Pron)))) -l -treebank UttImpSg PPos (ImpVP (ComplVV want_VV (ComplSlash (SlashV2A paint_V2A (PositA red_A)) (UsePron it_Pron)))) -l -treebank UttImpSg PPos (ImpVP (ComplSlash (SlashVV want_VV (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashV2a buy_V2))) (UsePron it_Pron))) -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumPl) (UseN fruit_N)) (ReflVP (Slash3V3 sell_V3 (DetCN (DetQuant DefArt NumSg) (UseN road_N))))))) NoVoc -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2V beg_V2V (UseV live_V)))))) NoVoc -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2S answer_V2S (UseCl (TTAnt TPres ASimul) PPos (ImpersCl (ComplVV must_VV (ReflVP (SlashV2a understand_V2)))))))))) NoVoc -l -treebank PhrUtt NoPConj (UttImpSg PPos (ImpVP (ReflVP (SlashV2Q ask_V2Q (UseQCl (TTAnt TPast ASimul) PPos (QuestVP whoSg_IP (UseV come_V))))))) NoVoc -l -treebank PhrUtt NoPConj (UttS (UseCl (TTAnt TPast ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2A paint_V2A (ComparA beautiful_A (UsePN john_PN))))))) NoVoc - --- more long examples - -l -treebank UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant this_Quant NumSg) (UseN grammar_N)) (ComplSlash (SlashV2a speak_V2) (DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot1to19 n2))))))) (UseN language_N))))) -l -treebank UseCl (TTAnt TPast AAnter) PPos (PredVP (UsePron she_Pron) (ComplSlash (SlashV2a buy_V2) (DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN house_N))))) - diff --git a/testsuite/libraries/exx-resource.gfs.gold b/testsuite/libraries/exx-resource.gfs.gold deleted file mode 100644 index b9cec44d5..000000000 --- a/testsuite/libraries/exx-resource.gfs.gold +++ /dev/null @@ -1,1032 +0,0 @@ -Lang: PositA warm_A -LangEng: warm -LangSwe: varm -LangBul: топъл - - -Lang: ComparA warm_A (UsePron i_Pron) -LangEng: warmer than I -LangSwe: varmare än jag -LangBul: по - топъл от мен - - -Lang: ComplA2 married_A2 (UsePron she_Pron) -LangEng: married to her -LangSwe: gift med henne -LangBul: женен за нея - - -Lang: ComplA2 married_A2 (DetNP (DetQuant (PossPron she_Pron) NumPl)) -LangEng: married to hers -LangSwe: gift med hennes -LangBul: женен за нейните - - -Lang: ComplA2 married_A2 (DetNP (DetQuant (PossPron she_Pron) NumSg)) -LangEng: married to hers -LangSwe: gift med hennes -LangBul: женен за нейното - - -Lang: ReflA2 married_A2 -LangEng: married to myself -LangSwe: gift med sig -LangBul: женен за себе си - - -Lang: PositA (UseA2 married_A2) -LangEng: married -LangSwe: gift -LangBul: женен - - -Lang: SentAP (PositA good_A) (EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseComp (CompAdv here_Adv))))) -LangEng: good that she is here -LangSwe: god att hon är här -LangBul: добър , че тя е тук - - -Lang: AdAP very_AdA (PositA warm_A) -LangEng: very warm -LangSwe: mycket varm -LangBul: много топъл - - -Lang: PositAdvAdj warm_A -LangEng: warmly -LangSwe: varmt -LangBul: топло - - -Lang: PrepNP in_Prep (DetCN (DetQuant DefArt NumSg) (UseN house_N)) -LangEng: in the house -LangSwe: i huset -LangBul: в къщата - - -Lang: ComparAdvAdj more_CAdv warm_A (UsePN john_PN) -LangEng: more warmly than John -LangSwe: mer varmt än Johan -LangBul: по - топло от Джон - - -Lang: ComparAdvAdjS more_CAdv warm_A (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV run_V))) -LangEng: more warmly than he runs -LangSwe: mer varmt än han springer -LangBul: по - топло от колкото той бяга - - -Lang: SubjS when_Subj (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) -LangEng: when she sleeps -LangSwe: när hon sover -LangBul: когато тя спи - - -Lang: AdNum (AdnCAdv more_CAdv) (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))) -LangEng: more than five -LangSwe: mer än fem -LangBul: повече от пет - - -Lang: ConjS and_Conj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV walk_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -LangEng: he walks and she runs -LangSwe: han går och hon springer -LangBul: той ходи и тя бяга - - -Lang: ConjAP and_Conj (BaseAP (PositA cold_A) (PositA warm_A)) -LangEng: cold and warm -LangSwe: kall och varm -LangBul: студен и топъл - - -Lang: ConjNP or_Conj (BaseNP (UsePron she_Pron) (UsePron we_Pron)) -LangEng: she or we -LangSwe: hon eller vi -LangBul: тя или ние - - -Lang: ConjAdv or_Conj (BaseAdv here_Adv there_Adv) -LangEng: here or there -LangSwe: här eller där -LangBul: тук или там - - -Lang: ConjS either7or_DConj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron he_Pron) (UseV walk_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -LangEng: either he walks or she runs -LangSwe: antingen han går eller hon springer -LangBul: или той ходи или тя бяга - - -Lang: ConjAP both7and_DConj (BaseAP (PositA warm_A) (PositA cold_A)) -LangEng: both warm and cold -LangSwe: både varm och kall -LangBul: и топъл и студен - - -Lang: ConjNP either7or_DConj (BaseNP (UsePron he_Pron) (UsePron she_Pron)) -LangEng: either he or she -LangSwe: antingen han eller hon -LangBul: или той или тя - - -Lang: ConjAdv both7and_DConj (BaseAdv here_Adv there_Adv) -LangEng: both here and there -LangSwe: både här och där -LangBul: и тук и там - - -Lang: ImpersCl (UseComp (CompAP (PositA hot_A))) -LangEng: it is hot -LangSwe: det är hett -LangBul: е горещо - - -Lang: GenericCl (UseV sleep_V) -LangEng: one sleeps -LangSwe: man sover -LangBul: някой спи - - -Lang: CleftNP (UsePron i_Pron) (UseRCl (TTAnt TPast ASimul) PPos (RelVP IdRP (ComplSlash (SlashV2a do_V2) (UsePron it_Pron)))) -LangEng: it is I who did it -LangSwe: det är jag som gjorde det -LangBul: аз съм този който направих него - - -Lang: CleftAdv here_Adv (UseCl (TTAnt TPast ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) -LangEng: it is here that she slept -LangSwe: det är här hon sov -LangBul: тук тя спа - - -Lang: ExistNP (DetCN (DetQuant IndefArt NumSg) (UseN house_N)) -LangEng: there is a house -LangSwe: det finns ett hus -LangBul: има къща - - -Lang: ExistIP (IdetCN (IdetQuant which_IQuant NumPl) (UseN house_N)) -LangEng: which houses are there -LangSwe: vilka hus finns det -LangBul: кои къщи са тук - - -Lang: PredVP (UsePron i_Pron) (ProgrVP (UseV sleep_V)) -LangEng: I am sleeping -LangSwe: jag håller på att sova -LangBul: аз спя - - -Lang: ImpPl1 (UseV go_V) -LangEng: let's go -LangSwe: låt oss gå -LangBul: нека да отидем - - -Lang: DetCN (DetQuant DefArt NumSg) (UseN man_N) -LangEng: the man -LangSwe: mannen -LangBul: мъжът - - -Lang: UsePN john_PN -LangEng: John -LangSwe: Johan -LangBul: Джон - - -Lang: UsePron he_Pron -LangEng: he -LangSwe: han -LangBul: той - - -Lang: PredetNP only_Predet (DetCN (DetQuant DefArt NumSg) (UseN man_N)) -LangEng: only the man -LangSwe: bara mannen -LangBul: само мъжът - - -Lang: PPartNP (DetCN (DetQuant DefArt NumSg) (UseN man_N)) see_V2 -LangEng: the man seen -LangSwe: mannen sedd -LangBul: мъжът видян - - -Lang: AdvNP (UsePN paris_PN) today_Adv -LangEng: Paris today -LangSwe: Paris idag -LangBul: Париж днес - - -Lang: RelNP (UsePN paris_PN) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (UseComp (CompAdv here_Adv)))) -LangEng: Paris , which is here -LangSwe: Paris , som är här -LangBul: Париж който е тук - - -Lang: DetNP (DetQuant this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) -LangEng: these five -LangSwe: de här fem -LangBul: тези пет - - -Lang: DetCN (DetQuantOrd this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5))))))) (OrdSuperl good_A)) (UseN man_N) -LangEng: these five best men -LangSwe: de här fem bästa männen -LangBul: тези петима най - добри мъже - - -Lang: DetCN (DetQuant this_Quant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN man_N) -LangEng: these five men -LangSwe: de här fem männen -LangBul: тези петима мъже - - -Lang: DetCN (DetQuant this_Quant NumPl) (UseN man_N) -LangEng: these men -LangSwe: de här männen -LangBul: тези мъже - - -Lang: DetCN (DetQuant this_Quant NumSg) (UseN man_N) -LangEng: this man -LangSwe: den här mannen -LangBul: този мъж - - -Lang: NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))) -LangEng: five -LangSwe: fem -LangBul: пет - - -Lang: NumCard (NumDigits (IIDig D_5 (IDig D_1))) -LangEng: 5 1 -LangSwe: 5 1 -LangBul: 5 1 - - -Lang: NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot1plus n5 pot01))))) -LangEng: fifty - one -LangSwe: femtio en -LangBul: петдесет и един - - -Lang: NumCard (AdNum almost_AdN (NumDigits (IIDig D_5 (IDig D_1)))) -LangEng: almost 5 1 -LangSwe: nästan 5 1 -LangBul: почти 5 1 - - -Lang: OrdDigits (IIDig D_5 (IDig D_1)) -LangEng: 5 1st -LangSwe: 5 1:a -LangBul: 5 1ви - - -Lang: OrdNumeral (num (pot2as3 (pot1as2 (pot1plus n5 pot01)))) -LangEng: fifty - first -LangSwe: femtio första -LangBul: петдесет и първи - - -Lang: OrdSuperl warm_A -LangEng: warmest -LangSwe: varmaste -LangBul: най - топъл - - -Lang: DetCN (DetQuantOrd DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5))))))) (OrdSuperl good_A)) (UseN man_N) -LangEng: the five best men -LangSwe: de fem bästa männen -LangBul: петимата най - добри мъже - - -Lang: DetCN (DetQuant DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN man_N) -LangEng: the five men -LangSwe: de fem männen -LangBul: петимата мъже - - -Lang: DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 pot01))))))) (UseN man_N) -LangEng: one man -LangSwe: en man -LangBul: един мъж - - -Lang: DetCN (DetQuant DefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 pot01))))))) (UseN man_N) -LangEng: the one man -LangSwe: den en mannen -LangBul: единият мъж - - -Lang: DetCN (DetQuant DefArt NumSg) (UseN man_N) -LangEng: the man -LangSwe: mannen -LangBul: мъжът - - -Lang: DetCN (DetQuant DefArt NumPl) (UseN man_N) -LangEng: the men -LangSwe: männen -LangBul: мъжете - - -Lang: MassNP (UseN beer_N) -LangEng: beer -LangSwe: öl -LangBul: бира - - -Lang: DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN house_N) -LangEng: my house -LangSwe: mitt hus -LangBul: моята къща - - -Lang: UseN house_N -LangEng: house -LangSwe: hus -LangBul: къща - - -Lang: ComplN2 mother_N2 (DetCN (DetQuant DefArt NumSg) (UseN king_N)) -LangEng: mother of the king -LangSwe: mor till kungen -LangBul: майка на царя - - -Lang: ComplN2 (ComplN3 distance_N3 (DetCN (DetQuant this_Quant NumSg) (UseN city_N))) (UsePN paris_PN) -LangEng: distance from this city to Paris -LangSwe: avstånd från den här staden till Paris -LangBul: разстояние от този град до Париж - - -Lang: UseN2 mother_N2 -LangEng: mother -LangSwe: mor -LangBul: майка - - -Lang: ComplN2 (Use2N3 distance_N3) (DetCN (DetQuant this_Quant NumSg) (UseN city_N)) -LangEng: distance from this city -LangSwe: avstånd från den här staden -LangBul: разстояние от този град - - -Lang: ComplN2 (Use3N3 distance_N3) (UsePN paris_PN) -LangEng: distance to Paris -LangSwe: avstånd till Paris -LangBul: разстояние до Париж - - -Lang: UseN2 (Use2N3 distance_N3) -LangEng: distance -LangSwe: avstånd -LangBul: разстояние - - -Lang: AdjCN (PositA big_A) (UseN house_N) -LangEng: big house -LangSwe: stort hus -LangBul: голяма къща - - -Lang: RelCN (UseN house_N) (UseRCl (TTAnt TPast ASimul) PPos (RelSlash IdRP (SlashVP (UsePN john_PN) (SlashV2a buy_V2)))) -LangEng: house which John bought -LangSwe: hus som Johan köpte -LangBul: къща която Джон купи - - -Lang: AdvCN (UseN house_N) (PrepNP on_Prep (DetCN (DetQuant DefArt NumSg) (UseN hill_N))) -LangEng: house on the hill -LangSwe: hus på kullen -LangBul: къща на хълма - - -Lang: SentCN (UseN question_N) (EmbedQS (UseQCl (TTAnt TPres ASimul) PPos (QuestIAdv where_IAdv (PredVP (UsePron she_Pron) (UseV sleep_V))))) -LangEng: question where she sleeps -LangSwe: fråga var hon sover -LangBul: въпрос където тя спи - - -Lang: DetCN (DetQuant DefArt NumSg) (ApposCN (UseN city_N) (UsePN paris_PN)) -LangEng: the city Paris -LangSwe: staden Paris -LangBul: градът Париж - - -Lang: DetCN (DetQuant (PossPron i_Pron) NumSg) (ApposCN (UseN friend_N) (UsePN john_PN)) -LangEng: my friend John -LangSwe: min vän Johan -LangBul: моят приятел Джон - - -Lang: num (pot2as3 (pot1as2 (pot0as1 (pot0 n6)))) -LangEng: six -LangSwe: sex -LangBul: шест - - -Lang: num (pot2as3 (pot1as2 (pot0as1 pot01))) -LangEng: one -LangSwe: en -LangBul: един - - -Lang: num (pot2as3 (pot1as2 (pot1 n6))) -LangEng: sixty -LangSwe: sextio -LangBul: шестдесет - - -Lang: num (pot2as3 (pot1as2 pot110)) -LangEng: ten -LangSwe: tio -LangBul: десет - - -Lang: num (pot2as3 (pot1as2 pot111)) -LangEng: eleven -LangSwe: elva -LangBul: единадесет - - -Lang: num (pot2as3 (pot1as2 (pot1to19 n6))) -LangEng: sixteen -LangSwe: sexton -LangBul: шестнадесет - - -Lang: num (pot2as3 (pot1as2 (pot1 n6))) -LangEng: sixty -LangSwe: sextio -LangBul: шестдесет - - -Lang: num (pot2as3 (pot1as2 (pot1plus n6 (pot0 n5)))) -LangEng: sixty - five -LangSwe: sextio fem -LangBul: шестдесет и пет - - -Lang: num (pot2as3 (pot2 (pot0 n4))) -LangEng: four hundred -LangSwe: fyra hundra -LangBul: четиристотин - - -Lang: num (pot2as3 (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7)))) -LangEng: four hundred and sixty - seven -LangSwe: fyra hundra sextio sju -LangBul: четиристотин шестдесет и седем - - -Lang: num (pot3 (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7)))) -LangEng: four hundred and sixty - seven thousand -LangSwe: fyra hundra sextio sju tusen -LangBul: четиристотин шестдесет и седем хиляди - - -Lang: num (pot3plus (pot2plus (pot0 n4) (pot1plus n6 (pot0 n7))) (pot1as2 (pot1plus n8 (pot0 n9)))) -LangEng: four hundred and sixty - seven thousand eighty - nine -LangSwe: fyra hundra sextio sju tusen åttio nio -LangBul: четиристотин шестдесет и седем хиляди осемдесет и девет - - -Lang: IDig D_8 -LangEng: 8 -LangSwe: 8 -LangBul: 8 - - -Lang: IIDig D_8 (IIDig D_0 (IIDig D_0 (IIDig D_1 (IIDig D_7 (IIDig D_8 (IDig D_9)))))) -LangEng: 8 , 0 0 1 , 7 8 9 -LangSwe: 8 0 0 1 7 8 9 -LangBul: 8 , 0 0 1 , 7 8 9 - - -Lang: PhrUtt but_PConj (UttImpSg PPos (ImpVP (AdvVP (UseV come_V) here_Adv))) (VocNP (DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN friend_N))) -LangEng: but come here , my friend -LangSwe: men kom här , min vän -LangBul: но ела тук , мой приятелю - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePN john_PN) (UseV walk_V)))) NoVoc -LangEng: John walks -LangSwe: Johan går -LangBul: Джон ходи - - -Lang: UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestCl (PredVP (UsePron it_Pron) (UseComp (CompAP (PositA good_A)))))) -LangEng: is it good -LangSwe: är det gott -LangBul: то е ли добро - - -Lang: UttImpSg PNeg (ImpVP (ReflVP (SlashV2a love_V2))) -LangEng: don't love yourself -LangSwe: älska inte dig -LangBul: не се обичай - - -Lang: UttImpPl PNeg (ImpVP (ReflVP (SlashV2a love_V2))) -LangEng: don't love yourselves -LangSwe: älska inte er -LangBul: не се обичайте - - -Lang: UttImpPol PNeg (ImpVP (UseV sleep_V)) -LangEng: don't sleep -LangSwe: sov inte -LangBul: не спете - - -Lang: UttIP whoPl_IP -LangEng: who -LangSwe: vilka -LangBul: кои - - -Lang: UttIP whoSg_IP -LangEng: who -LangSwe: vem -LangBul: кой - - -Lang: UttIAdv why_IAdv -LangEng: why -LangSwe: varför -LangBul: защо - - -Lang: UttNP (DetCN (DetQuant this_Quant NumSg) (UseN man_N)) -LangEng: this man -LangSwe: den här mannen -LangBul: този мъж - - -Lang: UttAdv here_Adv -LangEng: here -LangSwe: här -LangBul: тук - - -Lang: UttVP (UseV sleep_V) -LangEng: to sleep -LangSwe: att sova -LangBul: да спи - - -Lang: VocNP (DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN friend_N)) -LangEng: , my friend -LangSwe: , min vän -LangBul: , мой приятелю - - -Lang: QuestCl (PredVP (UsePN john_PN) (UseV walk_V)) -LangEng: does John walk -LangSwe: går Johan -LangBul: Джон ходи ли - - -Lang: QuestVP whoSg_IP (UseV walk_V) -LangEng: who walks -LangSwe: vem går -LangBul: кой ходи - - -Lang: QuestSlash whoSg_IP (SlashVP (UsePN john_PN) (SlashV2a love_V2)) -LangEng: whom does John love -LangSwe: vem älskar Johan -LangBul: кого обича Джон - - -Lang: QuestIAdv why_IAdv (PredVP (UsePN john_PN) (UseV walk_V)) -LangEng: why does John walk -LangSwe: varför går Johan -LangBul: защо ходи Джон - - -Lang: QuestIComp (CompIAdv where_IAdv) (UsePN john_PN) -LangEng: where is John -LangSwe: var är Johan -LangBul: къде е Джон - - -Lang: IdetCN (IdetQuant which_IQuant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) (UseN song_N) -LangEng: which five songs -LangSwe: vilka fem sånger -LangBul: кои пет песни - - -Lang: IdetIP (IdetQuant which_IQuant (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n5)))))))) -LangEng: which five -LangSwe: vilka fem -LangBul: кои пет - - -Lang: AdvIP whoSg_IP (PrepNP in_Prep (UsePN paris_PN)) -LangEng: who in Paris -LangSwe: vem i Paris -LangBul: кой в Париж - - -Lang: IdetIP (IdetQuant which_IQuant NumSg) -LangEng: which -LangSwe: vilket -LangBul: кое - - -Lang: PrepIP with_Prep whoSg_IP -LangEng: with whom -LangSwe: med vem -LangBul: с кой - - -Lang: QuestIComp (CompIAdv where_IAdv) (UsePron it_Pron) -LangEng: where is it -LangSwe: var är det -LangBul: къде е то - - -Lang: QuestIComp (CompIP whoSg_IP) (UsePron it_Pron) -LangEng: who is it -LangSwe: vem är det -LangBul: кой е то - - -Lang: ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelCl (PredVP (UsePN john_PN) (ComplSlash (SlashV2a love_V2) (UsePron she_Pron))))))) -LangEng: there is a woman such that John loves her -LangSwe: det finns en kvinna sådan att Johan älskar henne -LangBul: има жена такава че Джон обича нея - - -Lang: ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (ComplSlash (SlashV2a love_V2) (UsePN john_PN)))))) -LangEng: there is a woman who loves John -LangSwe: det finns en kvinna som älskar Johan -LangBul: има жена която обича Джон - - -Lang: ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePN john_PN) (SlashV2a love_V2)))))) -LangEng: there is a woman whom John loves -LangSwe: det finns en kvinna som Johan älskar -LangBul: има жена която Джон обича - - -Lang: ExistNP (DetCN (DetQuant IndefArt NumSg) (RelCN (UseN woman_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash (FunRP possess_Prep (DetCN (DetQuant DefArt NumSg) (UseN2 mother_N2)) IdRP) (SlashVP (UsePN john_PN) (SlashV2a love_V2)))))) -LangEng: there is a woman the mother of whom John loves -LangSwe: det finns en kvinna modern av vilken Johan älskar -LangBul: има жена майката на която Джон обича - - -Lang: PredVP (UsePN john_PN) (UseV walk_V) -LangEng: John walks -LangSwe: Johan går -LangBul: Джон ходи - - -Lang: PredSCVP (EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV go_V)))) (UseComp (CompAP (PositA good_A))) -LangEng: that she goes is good -LangSwe: att hon går är gott -LangBul: , че тя отива е добър - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron he_Pron) (SlashV2a see_V2)))) -LangEng: girl whom he sees -LangSwe: flicka som han ser -LangBul: момиче което той вижда - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (AdvSlash (SlashVP (UsePron he_Pron) (SlashV2a see_V2)) today_Adv))) -LangEng: girl whom he sees today -LangSwe: flicka som han ser idag -LangBul: момиче което той вижда днес - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashPrep (PredVP (UsePron he_Pron) (UseV walk_V)) with_Prep))) -LangEng: girl with whom he walks -LangSwe: flicka med vilken han går -LangBul: момиче с което той ходи - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVS (UsePron she_Pron) say_VS (UseSlash (TTAnt TPres ASimul) PPos (SlashVP (UsePron he_Pron) (SlashV2a love_V2)))))) -LangEng: girl whom she says that he loves -LangSwe: flicka som hon säger att han älskar -LangBul: момиче което тя казва че той обича - - -Lang: ImpVP (ReflVP (SlashV2a love_V2)) -LangEng: love yourself -LangSwe: älska dig -LangBul: обичай се - - -Lang: EmbedS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV go_V))) -LangEng: that she goes -LangSwe: att hon går -LangBul: , че тя отива - - -Lang: EmbedQS (UseQCl (TTAnt TPres ASimul) PPos (QuestVP whoSg_IP (UseV go_V))) -LangEng: who goes -LangSwe: vem som går -LangBul: който отива - - -Lang: EmbedVP (UseV go_V) -LangEng: to go -LangSwe: att gå -LangBul: да отида - - -Lang: UseCl (TTAnt TCond AAnter) PNeg (PredVP (UsePN john_PN) (UseV walk_V)) -LangEng: John wouldn't have walked -LangSwe: Johan skulle inte ha gått -LangBul: Джон не би ходил - - -Lang: UseQCl (TTAnt TCond AAnter) PNeg (QuestCl (PredVP (UsePN john_PN) (UseV walk_V))) -LangEng: wouldn't John have walked -LangSwe: skulle Johan inte ha gått -LangBul: Джон не би ли ходил - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TCond AAnter) PNeg (RelVP IdRP (UseV walk_V))) -LangEng: girl who wouldn't have walked -LangSwe: flicka som inte skulle ha gått -LangBul: момиче което не би ходило - - -Lang: RelCN (UseN girl_N) (UseRCl (TTAnt TCond AAnter) PNeg (RelSlash IdRP (SlashPrep (PredVP (UsePron i_Pron) (UseV walk_V)) with_Prep))) -LangEng: girl with whom I wouldn't have walked -LangSwe: flicka med vilken jag inte skulle ha gått -LangBul: момиче с което аз не бих ходил - - -Lang: RelS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV sleep_V))) (UseRCl (TTAnt TPres ASimul) PPos (RelVP IdRP (UseComp (CompAP (PositA good_A))))) -LangEng: she sleeps , which is good -LangSwe: hon sover , som är gott -LangBul: тя спи , което е добро - - -Lang: TEmpty -LangEng: -LangSwe: -LangBul: - - -Lang: TFullStop (PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePN john_PN) (UseV walk_V)))) NoVoc) TEmpty -LangEng: John walks . -LangSwe: Johan går . -LangBul: Джон ходи . - - -Lang: TQuestMark (PhrUtt NoPConj (UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestCl (PredVP (UsePron they_Pron) (UseComp (CompAdv here_Adv)))))) NoVoc) TEmpty -LangEng: are they here ? -LangSwe: är de här ? -LangBul: те са ли тук ? - - -Lang: TExclMark (PhrUtt NoPConj (ImpPl1 (UseV go_V)) NoVoc) TEmpty -LangEng: let's go ! -LangSwe: låt oss gå ! -LangBul: нека да отидем ! - - -Lang: PredVP (UsePron i_Pron) (UseV sleep_V) -LangEng: I sleep -LangSwe: jag sover -LangBul: аз спя - - -Lang: PredVP (UsePron i_Pron) (ComplVV want_VV (UseV run_V)) -LangEng: I want to run -LangSwe: jag vill springa -LangBul: аз искам да бягам - - -Lang: PredVP (UsePron i_Pron) (ComplVS say_VS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron she_Pron) (UseV run_V)))) -LangEng: I say that she runs -LangSwe: jag säger att hon springer -LangBul: аз казвам , че тя бяга - - -Lang: PredVP (UsePron i_Pron) (ComplVQ wonder_VQ (UseQCl (TTAnt TPres ASimul) PPos (QuestVP whoSg_IP (UseV run_V)))) -LangEng: I wonder who runs -LangSwe: jag undrar vem som springer -LangBul: аз се учудвам кой бяга - - -Lang: PredVP (UsePron they_Pron) (ComplVA become_VA (PositA red_A)) -LangEng: they become red -LangSwe: de blir röda -LangBul: те стават червени - - -Lang: PredVP (UsePron i_Pron) (ComplSlash (Slash3V3 give_V3 (UsePron he_Pron)) (UsePron it_Pron)) -LangEng: I give it to him -LangSwe: jag ger det till honom -LangBul: аз давам него му - - -Lang: PredVP (UsePron i_Pron) (ComplSlash (SlashV2V beg_V2V (UseV go_V)) (UsePron she_Pron)) -LangEng: I beg her to go -LangSwe: jag ber henne att gå -LangBul: аз моля нея да отиде - - -Lang: PredVP (UsePron i_Pron) (ComplSlash (SlashV2S answer_V2S (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron it_Pron) (UseComp (CompAP (PositA good_A)))))) (UsePron he_Pron)) -LangEng: I answer to him that it is good -LangSwe: jag svarar till honom att det är gott -LangBul: аз отговарям му , че то е добро - - -Lang: PredVP (UsePron i_Pron) (ComplSlash (SlashV2Q ask_V2Q (UseQCl (TTAnt TPast ASimul) PPos (QuestVP whoSg_IP (UseV come_V)))) (UsePron he_Pron)) -LangEng: I ask him who came -LangSwe: jag frågar honom vem som kom -LangBul: аз питам него кой дойде - - -Lang: PredVP (UsePron i_Pron) (ComplSlash (SlashV2A paint_V2A (PositA red_A)) (UsePron it_Pron)) -LangEng: I paint it red -LangSwe: jag målar det rött -LangBul: аз рисувам него червено - - -Lang: RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron i_Pron) (SlashVV want_VV (SlashV2a buy_V2))))) -LangEng: car which I want to buy -LangSwe: bil som jag vill köpa -LangBul: кола която аз искам да купя - - -Lang: RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron they_Pron) (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashV2a buy_V2))))) -LangEng: car which they beg me to buy -LangSwe: bil som de ber mig att köpa -LangBul: кола която те молят мен да купя - - -Lang: PredVP (UsePron he_Pron) (ReflVP (SlashV2a love_V2)) -LangEng: he loves himself -LangSwe: han älskar sig -LangBul: той се обича - - -Lang: PredVP (DetNP (DetQuant this_Quant NumSg)) (UseComp (CompAP (PositA warm_A))) -LangEng: this is warm -LangSwe: det här är varmt -LangBul: това е топло - - -Lang: PredVP (UsePron we_Pron) (PassV2 love_V2) -LangEng: we are loved -LangSwe: vi blir älskade -LangBul: ние сме обичани - - -Lang: PredVP (UsePron we_Pron) (AdvVP (UseV sleep_V) here_Adv) -LangEng: we sleep here -LangSwe: vi sover här -LangBul: ние спим тук - - -Lang: PredVP (UsePron we_Pron) (AdVVP always_AdV (UseV sleep_V)) -LangEng: we always sleep -LangSwe: vi sover alltid -LangBul: ние винаги спим - - -Lang: PredVP (UsePron we_Pron) (UseComp (CompAP (PositA small_A))) -LangEng: we are small -LangSwe: vi är små -LangBul: ние сме малки - - -Lang: PredVP (UsePron i_Pron) (UseComp (CompNP (DetCN (DetQuant IndefArt NumSg) (UseN man_N)))) -LangEng: I am a man -LangSwe: jag är en man -LangBul: аз съм мъж - - -Lang: PredVP (UsePron i_Pron) (UseComp (CompAdv here_Adv)) -LangEng: I am here -LangSwe: jag är här -LangBul: аз съм тук - - -Lang: RelCN (UseN car_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron they_Pron) (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashVV want_VV (SlashV2A paint_V2A (PositA red_A))))))) -LangEng: car which they beg me to want to paint red -LangSwe: bil som de ber mig att vilja måla röd -LangBul: кола която те молят мен да искам да нарисувам червена - - -Lang: PhrUtt NoPConj (UttImpSg PPos (ImpVP (AdVVP always_AdV (ComplSlash (SlashV2a listen_V2) (DetCN (DetQuant DefArt NumSg) (UseN sea_N)))))) NoVoc -LangEng: always listen to the sea -LangSwe: lyssna alltid på havet -LangBul: винаги слушай морето - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (ExistNP (PredetNP only_Predet (DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot0as1 (pot0 n2)))))))) (AdvCN (RelCN (UseN woman_N) (UseRCl (TTAnt TCond ASimul) PPos (RelSlash IdRP (SlashPrep (PredVP (UsePron i_Pron) (ComplVV want_VV (PassV2 see_V2))) with_Prep)))) (PrepNP in_Prep (DetCN (DetQuant DefArt NumSg) (UseN rain_N))))))))) NoVoc -LangEng: there are only two women with whom I would want to be seen in the rain -LangSwe: det finns bara två kvinnor med vilka jag skulle vilja bli sedd i regnet -LangBul: има само две жени с които аз бих искал да съм видян в дъжда - - -Lang: PhrUtt NoPConj (UttImpSg PPos (ImpVP (ComplSlash (SlashV2A paint_V2A (ConjAP both7and_DConj (BaseAP (ComparA small_A (DetCN (DetQuant DefArt NumSg) (UseN sun_N))) (ComparA big_A (DetCN (DetQuant DefArt NumSg) (UseN moon_N)))))) (DetCN (DetQuant DefArt NumSg) (UseN earth_N))))) NoVoc -LangEng: paint the earth both smaller than the sun and bigger than the moon -LangSwe: måla jorden både mindre än solen och större än månen -LangBul: нарисувай земята и по - малка от слънцето и по - голяма от луната - - -Lang: PhrUtt NoPConj (ImpPl1 (ComplVS hope_VS (ConjS either7or_DConj (BaseS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumSg) (ComplN2 father_N2 (DetCN (DetQuant DefArt NumSg) (UseN baby_N)))) (UseV run_V))) (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumSg) (UseN2 (Use2N3 distance_N3))) (UseComp (CompAP (PositA small_A))))))))) NoVoc -LangEng: let's hope that either the father of the baby runs or the distance is small -LangSwe: låt oss hoppas att antingen fadern till bebisen springer eller avståndet är litet -LangBul: нека да се надяваме , че или бащата на бебето бяга или разстоянието е малко - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN every_Det (UseN baby_N)) (UseComp (CompNP (ConjNP either7or_DConj (BaseNP (DetCN (DetQuant IndefArt NumSg) (UseN boy_N)) (DetCN (DetQuant IndefArt NumSg) (UseN girl_N))))))))) NoVoc -LangEng: every baby is either a boy or a girl -LangSwe: varje bebis är antingen en pojke eller en flicka -LangBul: всяко бебе е или момче или момиче - - -Lang: PhrUtt NoPConj (UttAdv (ConjAdv either7or_DConj (ConsAdv here7from_Adv (BaseAdv there_Adv everywhere_Adv)))) NoVoc -LangEng: either from here , there or everywhere -LangSwe: antingen härifrån , där eller överallt -LangBul: или от тук или там или навсякъде - - -Lang: PhrUtt NoPConj (UttVP (PassV2 know_V2)) NoVoc -LangEng: to be known -LangSwe: att bli kännd -LangBul: да е известно - - -Lang: RelCN (UseN bird_N) (UseRCl (TTAnt TPres ASimul) PPos (RelSlash IdRP (SlashVP (UsePron i_Pron) (SlashVV want_VV (SlashV2A paint_V2A (PositA red_A)))))) -LangEng: bird which I want to paint red -LangSwe: fågel som jag vill måla röd -LangBul: птица която аз искам да нарисувам червена - - -Lang: UttImpSg PPos (ImpVP (ComplVV want_VV (ComplSlash (SlashV2a buy_V2) (UsePron it_Pron)))) -LangEng: want to buy it -LangSwe: vilj köpa det -LangBul: искай да купиш него - - -Lang: UttImpSg PPos (ImpVP (ComplVV want_VV (ComplSlash (SlashV2A paint_V2A (PositA red_A)) (UsePron it_Pron)))) -LangEng: want to paint it red -LangSwe: vilj måla det rött -LangBul: искай да нарисуваш него червено - - -Lang: UttImpSg PPos (ImpVP (ComplSlash (SlashVV want_VV (SlashV2VNP beg_V2V (UsePron i_Pron) (SlashV2a buy_V2))) (UsePron it_Pron))) -LangEng: want it to beg me to buy -LangSwe: vilj det be mig att köpa -LangBul: искай да молиш мен да купя него - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumPl) (UseN fruit_N)) (ReflVP (Slash3V3 sell_V3 (DetCN (DetQuant DefArt NumSg) (UseN road_N))))))) NoVoc -LangEng: the fruits sell themselves to the road -LangSwe: frukterna säljer sig till vägen -LangBul: плодовете се продават на пътя - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2V beg_V2V (UseV live_V)))))) NoVoc -LangEng: I beg myself to live -LangSwe: jag ber mig att leva -LangBul: аз се моля да живея - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2S answer_V2S (UseCl (TTAnt TPres ASimul) PPos (ImpersCl (ComplVV must_VV (ReflVP (SlashV2a understand_V2)))))))))) NoVoc -LangEng: I answer to myself that it must understand itself -LangSwe: jag svarar till mig att det måste förstå sig -LangBul: аз си отговарям , че трябва да се разбере - - -Lang: PhrUtt NoPConj (UttImpSg PPos (ImpVP (ReflVP (SlashV2Q ask_V2Q (UseQCl (TTAnt TPast ASimul) PPos (QuestVP whoSg_IP (UseV come_V))))))) NoVoc -LangEng: ask yourself who came -LangSwe: fråga dig vem som kom -LangBul: питай се кой дойде - - -Lang: PhrUtt NoPConj (UttS (UseCl (TTAnt TPast ASimul) PPos (PredVP (UsePron i_Pron) (ReflVP (SlashV2A paint_V2A (ComparA beautiful_A (UsePN john_PN))))))) NoVoc -LangEng: I painted myself more beautiful than John -LangSwe: jag målade mig vackrare än Johan -LangBul: аз се нарисувах по - красив от Джон - - -Lang: UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant this_Quant NumSg) (UseN grammar_N)) (ComplSlash (SlashV2a speak_V2) (DetCN (DetQuant IndefArt (NumCard (NumNumeral (num (pot2as3 (pot1as2 (pot1to19 n2))))))) (UseN language_N))))) -LangEng: this grammar speaks twelve languages -LangSwe: den här grammatiken talar tolv språk -LangBul: тази граматика говори дванадесет езика - - -Lang: UseCl (TTAnt TPast AAnter) PPos (PredVP (UsePron she_Pron) (ComplSlash (SlashV2a buy_V2) (DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN house_N))))) -LangEng: she had bought a red house -LangSwe: hon hade köpt ett rött hus -LangBul: тя беше купилa червена къща - - From a1372040b4212be6af0b52a304de3054ec762619 Mon Sep 17 00:00:00 2001 From: 1Regina <46968488+1Regina@users.noreply.github.com> Date: Fri, 11 Jun 2021 11:47:03 +0800 Subject: [PATCH 28/75] Add RGL dependencies - Prelude and Predef --- .../compiler/check/lincat-types/Predef.gf | 48 ++++++ testsuite/compiler/check/strMatch/Prelude.gf | 161 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 testsuite/compiler/check/lincat-types/Predef.gf create mode 100644 testsuite/compiler/check/strMatch/Prelude.gf diff --git a/testsuite/compiler/check/lincat-types/Predef.gf b/testsuite/compiler/check/lincat-types/Predef.gf new file mode 100644 index 000000000..fded5ae38 --- /dev/null +++ b/testsuite/compiler/check/lincat-types/Predef.gf @@ -0,0 +1,48 @@ +--1 Predefined functions for concrete syntax + +-- The definitions of these constants are hard-coded in GF, and defined +-- in Predef.hs (gf-core/src/compiler/GF/Compile/Compute/Predef.hs). +-- Applying them to run-time variables leads to compiler errors that are +-- often only detected at the code generation time. + +resource Predef = { + +-- This type of booleans is for internal use only. + + param PBool = PTrue | PFalse ; + + oper Error : Type = variants {} ; -- the empty type + oper Float : Type = variants {} ; -- the type of floats + oper Int : Type = variants {} ; -- the type of integers + oper Ints : Int -> PType = variants {} ; -- the type of integers from 0 to n + + oper error : Str -> Error = variants {} ; -- forms error message + oper length : Tok -> Int = variants {} ; -- length of string + oper drop : Int -> Tok -> Tok = variants {} ; -- drop prefix of length + oper take : Int -> Tok -> Tok = variants {} ; -- take prefix of length + oper tk : Int -> Tok -> Tok = variants {} ; -- drop suffix of length + oper dp : Int -> Tok -> Tok = variants {} ; -- take suffix of length + oper eqInt : Int -> Int -> PBool = variants {} ; -- test if equal integers + oper lessInt: Int -> Int -> PBool = variants {} ; -- test order of integers + oper plus : Int -> Int -> Int = variants {} ; -- add integers + oper eqStr : Tok -> Tok -> PBool = variants {} ; -- test if equal strings + oper occur : Tok -> Tok -> PBool = variants {} ; -- test if occurs as substring + oper occurs : Tok -> Tok -> PBool = variants {} ; -- test if any char occurs + oper isUpper : Tok -> PBool = variants {} ; -- test if all chars are upper-case + oper toUpper : Tok -> Tok = variants {} ; -- map all chars to upper case + oper toLower : Tok -> Tok = variants {} ; -- map all chars to lower case + oper show : (P : Type) -> P -> Tok = variants {} ; -- convert param to string + oper read : (P : Type) -> Tok -> P = variants {} ; -- convert string to param + oper eqVal : (P : Type) -> P -> P -> PBool = variants {} ; -- test if equal values + oper toStr : (L : Type) -> L -> Str = variants {} ; -- find the "first" string + oper mapStr : (L : Type) -> (Str -> Str) -> L -> L = variants {} ; + -- map all strings in a data structure; experimental --- + + oper nonExist : Str = variants {} ; -- a placeholder for non-existant morphological forms + oper BIND : Str = variants {} ; -- a token for gluing + oper SOFT_BIND : Str = variants {} ; -- a token for soft gluing + oper SOFT_SPACE : Str = variants {} ; -- a token for soft space + oper CAPIT : Str = variants {} ; -- a token for capitalization + oper ALL_CAPIT : Str = variants {} ; -- a token for capitalization of abreviations + +} ; diff --git a/testsuite/compiler/check/strMatch/Prelude.gf b/testsuite/compiler/check/strMatch/Prelude.gf new file mode 100644 index 000000000..1c5b50354 --- /dev/null +++ b/testsuite/compiler/check/strMatch/Prelude.gf @@ -0,0 +1,161 @@ +--1 The GF Prelude + +-- This file defines some prelude facilities usable in all grammars. + +resource Prelude = Predef[nonExist, BIND, SOFT_BIND, SOFT_SPACE, CAPIT, ALL_CAPIT] ** open (Predef=Predef) in { + +oper + +--2 Strings, records, and tables + + SS : Type = {s : Str} ; + ss : Str -> SS = \s -> {s = s} ; + ss2 : (_,_ : Str) -> SS = \x,y -> ss (x ++ y) ; + ss3 : (_,_ ,_: Str) -> SS = \x,y,z -> ss (x ++ y ++ z) ; + + cc2 : (_,_ : SS) -> SS = \x,y -> ss (x.s ++ y.s) ; + cc3 : (_,_,_ : SS) -> SS = \x,y,z -> ss (x.s ++ y.s ++ z.s) ; + + SS1 : PType -> Type = \P -> {s : P => Str} ; + ss1 : (A : PType) -> Str -> SS1 A = \A,s -> {s = table {_ => s}} ; + + SP1 : Type -> Type = \P -> {s : Str ; p : P} ; + sp1 : (A : Type) -> Str -> A -> SP1 A = \_,s,a -> {s = s ; p = a} ; + + constTable : (A : PType) -> (B : Type) -> B -> A => B = \u,v,b -> \\_ => b ; + constStr : (A : PType) -> Str -> A => Str = \A -> constTable A Str ; + +-- Discontinuous constituents. + + SD2 : Type = {s1,s2 : Str} ; + sd2 : (_,_ : Str) -> SD2 = \x,y -> {s1 = x ; s2 = y} ; + + +--2 Optional elements + +-- Optional string with preference on the string vs. empty. + + optStr : Str -> Str = \s -> variants {s ; []} ; + strOpt : Str -> Str = \s -> variants {[] ; s} ; + +-- Free order between two strings. + + bothWays : Str -> Str -> Str = \x,y -> variants {x ++ y ; y ++ x} ; + +-- Parametric order between two strings. + + preOrPost : Bool -> Str -> Str -> Str = \pr,x,y -> + if_then_Str pr (x ++ y) (y ++ x) ; + +--2 Infixes. prefixes, and postfixes + +-- Fixes with precedences are defined in [Precedence Precedence.html]. + + infixSS : Str -> SS -> SS -> SS = \f,x,y -> ss (x.s ++ f ++ y.s) ; + prefixSS : Str -> SS -> SS = \f,x -> ss (f ++ x.s) ; + postfixSS : Str -> SS -> SS = \f,x -> ss (x.s ++ f) ; + embedSS : Str -> Str -> SS -> SS = \f,g,x -> ss (f ++ x.s ++ g) ; + + +--2 Booleans + + param Bool = False | True ; + +oper + if_then_else : (A : Type) -> Bool -> A -> A -> A = \_,c,d,e -> + case c of { + True => d ; ---- should not need to qualify + False => e + } ; + + andB : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a b False ; + orB : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a True b ; + notB : Bool -> Bool = \a -> if_then_else Bool a False True ; + + if_then_Str : Bool -> Str -> Str -> Str = if_then_else Str ; + + onlyIf : Bool -> Str -> Str = \b,s -> case b of { + True => s ; + _ => nonExist + } ; + +-- Interface to internal booleans + + pbool2bool : Predef.PBool -> Bool = \b -> case b of { + Predef.PFalse => False ; Predef.PTrue => True + } ; + + init : Tok -> Tok = Predef.tk 1 ; + last : Tok -> Tok = Predef.dp 1 ; + +--2 High-level acces to Predef operations + + isNil : Tok -> Bool = \b -> pbool2bool (Predef.eqStr [] b) ; + + ifTok : (A : Type) -> Tok -> Tok -> A -> A -> A = \A,t,u,a,b -> + case Predef.eqStr t u of {Predef.PTrue => a ; Predef.PFalse => b} ; + +--2 Lexer-related operations + +-- Bind together two tokens in some lexers, either obligatorily or optionally + + oper + glue : Str -> Str -> Str = \x,y -> x ++ BIND ++ y ; + glueOpt : Str -> Str -> Str = \x,y -> variants {glue x y ; x ++ y} ; + noglueOpt : Str -> Str -> Str = \x,y -> variants {x ++ y ; glue x y} ; + +-- Force capitalization of next word in some unlexers + + capitalize : Str -> Str = \s -> CAPIT ++ s ; + +-- These should be hidden, and never changed since they are hardcoded in (un)lexers + + PARA : Str = "&-" ; + +-- Embed between commas, where the latter one disappears in front of other punctuation + + embedInCommas : Str -> Str = \s -> bindComma ++ s ++ endComma ; + endComma : Str = pre {"," | "." => []; "" => bindComma ; _ => []} ; + + bindComma : Str = SOFT_BIND ++ "," ; + optComma : Str = bindComma | [] ; + optCommaSS : SS -> SS = \s -> ss (s.s ++ optComma) ; + +--2 Miscellaneous + +-- Identity function + + id : (A : Type) -> A -> A = \_,a -> a ; + +-- Parentheses + + paren : Str -> Str = \s -> "(" ++ s ++ ")" ; + parenss : SS -> SS = \s -> ss (paren s.s) ; + +-- Zero, one, two, or more (elements in a list etc) + +param + ENumber = E0 | E1 | E2 | Emore ; + +oper + eNext : ENumber -> ENumber = \e -> case e of { + E0 => E1 ; E1 => E2 ; _ => Emore} ; + +-- convert initial to upper/lower + + toUpperFirst : Str -> Str = \s -> case s of { + x@? + xs => Predef.toUpper x + xs ; + _ => s + } ; + + toLowerFirst : Str -> Str = \s -> case s of { + x@? + xs => Predef.toLower x + xs ; + _ => s + } ; + +-- handling errors caused by temporarily missing definitions + + notYet : Str -> Predef.Error = \s -> + Predef.error ("NOT YET IMPLEMENTED:" ++ s) ; + +} From c4165714066eb4fa4ccea0debf2a736930c2a281 Mon Sep 17 00:00:00 2001 From: 1Regina <46968488+1Regina@users.noreply.github.com> Date: Fri, 11 Jun 2021 12:14:49 +0800 Subject: [PATCH 29/75] Rectified gold files --- .../check/cyclic/abs-types/test3.gfs.gold | 0 .../compiler/check/lincat-types/test.gfs.gold | 12 +- testsuite/compiler/check/lins/lins.gfs.gold | 80 +++---- .../check/oper-definition/test.gfs.gold | 7 +- .../compiler/check/strMatch/strMatch.gfs.gold | 1 + testsuite/compiler/params/params.gfs.gold | 0 .../typecheck/abstract/LetInDefAbs.gfs.gold | 15 ++ .../typecheck/abstract/LetInTypesAbs.gfs.gold | 4 +- .../typecheck/abstract/test_A.gfs.gold | 7 +- .../typecheck/abstract/test_B.gfs.gold | 7 +- .../typecheck/abstract/test_C.gfs.gold | 7 +- .../typecheck/concrete/test_A.gfs.gold | 10 +- testsuite/runtime/linearize/brackets.gfs.gold | 11 +- .../runtime/linearize/linearize.gfs.gold | 10 - .../typecheck/hard-unification.gfs.gold | 14 +- .../typecheck/implicit-arguments.gfs.gold | 72 ++++--- .../runtime/typecheck/typecheck.gfs.gold | 204 ++++++++++-------- 17 files changed, 254 insertions(+), 207 deletions(-) create mode 100644 testsuite/compiler/check/cyclic/abs-types/test3.gfs.gold create mode 100644 testsuite/compiler/check/strMatch/strMatch.gfs.gold create mode 100644 testsuite/compiler/params/params.gfs.gold create mode 100644 testsuite/compiler/typecheck/abstract/LetInDefAbs.gfs.gold diff --git a/testsuite/compiler/check/cyclic/abs-types/test3.gfs.gold b/testsuite/compiler/check/cyclic/abs-types/test3.gfs.gold new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/compiler/check/lincat-types/test.gfs.gold b/testsuite/compiler/check/lincat-types/test.gfs.gold index 7e95ec7af..2e14e89e6 100644 --- a/testsuite/compiler/check/lincat-types/test.gfs.gold +++ b/testsuite/compiler/check/lincat-types/test.gfs.gold @@ -1,7 +1,9 @@ -testsuite/compiler/check/lincat-types/TestCnc.gf:3: - Happened in linearization type of S - type of PTrue - expected: Type - inferred: PBool +testsuite/compiler/check/lincat-types/TestCnc.gf: + testsuite/compiler/check/lincat-types/TestCnc.gf:3: + Happened in linearization type of S + type of PTrue + expected: Type + inferred: Predef.PBool + diff --git a/testsuite/compiler/check/lins/lins.gfs.gold b/testsuite/compiler/check/lins/lins.gfs.gold index 149912bde..798c91e43 100644 --- a/testsuite/compiler/check/lins/lins.gfs.gold +++ b/testsuite/compiler/check/lins/lins.gfs.gold @@ -1,39 +1,41 @@ -checking module linsCnc - Warning: no linearization type for C, inserting default {s : Str} - Warning: no linearization of test -abstract lins { - cat C Nat ; - cat Float ; - cat Int ; - cat Nat ; - cat String ; - fun test : C zero ; - fun zero : Nat ; -} -concrete linsCnc { - productions - C1 -> F2[] - lindefs - C0 -> F0 - C1 -> F1 - lin - F0 := (S0) [lindef C] - F1 := () [lindef Nat] - F2 := () [zero] - sequences - S0 := {0,0} - categories - C := range [C0 .. C0] - labels ["s"] - Float := range [CFloat .. CFloat] - labels ["s"] - Int := range [CInt .. CInt] - labels ["s"] - Nat := range [C1 .. C1] - labels [] - String := range [CString .. CString] - labels ["s"] - __gfVar := range [CVar .. CVar] - labels [""] - printnames -} +abstract lins { + cat C Nat ; + cat Float ; + cat Int ; + cat Nat ; + cat String ; + fun test : C zero ; + fun zero : Nat ; +} +concrete linsCnc { + productions + C1 -> F4[] + lindefs + C0 -> F0[CVar] + C1 -> F2[CVar] + linrefs + CVar -> F1[C0] + CVar -> F3[C1] + lin + F0 := (S2) ['lindef C'] + F1 := (S1) ['lindef C'] + F2 := () ['lindef Nat'] + F3 := (S0) ['lindef Nat'] + F4 := () [zero] + sequences + S0 := + S1 := <0,0> + S2 := {0,0} + categories + C := range [C0 .. C0] + labels ["s"] + Float := range [CFloat .. CFloat] + labels ["s"] + Int := range [CInt .. CInt] + labels ["s"] + Nat := range [C1 .. C1] + labels [] + String := range [CString .. CString] + labels ["s"] + printnames +} diff --git a/testsuite/compiler/check/oper-definition/test.gfs.gold b/testsuite/compiler/check/oper-definition/test.gfs.gold index 240819c74..373ef17bd 100644 --- a/testsuite/compiler/check/oper-definition/test.gfs.gold +++ b/testsuite/compiler/check/oper-definition/test.gfs.gold @@ -1,5 +1,6 @@ -testsuite/compiler/check/oper-definition/Res.gf:3: - Happened in operation my_oper - No definition given to the operation +testsuite/compiler/check/oper-definition/Res.gf: + testsuite/compiler/check/oper-definition/Res.gf:3: + Happened in operation my_oper + No definition given to the operation diff --git a/testsuite/compiler/check/strMatch/strMatch.gfs.gold b/testsuite/compiler/check/strMatch/strMatch.gfs.gold new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/testsuite/compiler/check/strMatch/strMatch.gfs.gold @@ -0,0 +1 @@ + diff --git a/testsuite/compiler/params/params.gfs.gold b/testsuite/compiler/params/params.gfs.gold new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/compiler/typecheck/abstract/LetInDefAbs.gfs.gold b/testsuite/compiler/typecheck/abstract/LetInDefAbs.gfs.gold new file mode 100644 index 000000000..e4613af56 --- /dev/null +++ b/testsuite/compiler/typecheck/abstract/LetInDefAbs.gfs.gold @@ -0,0 +1,15 @@ +fun f : Int -> Int ; +def f n = ? ; +000 CHECK_ARGS 1 + ALLOC 2 + PUT_CLOSURE 001 + SET_PAD + TUCK hp(0) 1 + EVAL f tail(0) +001 ALLOC 2 + PUT_LIT 0 + PUSH_FRAME + PUSH hp(0) + EVAL f update +Probability: 1.0 + diff --git a/testsuite/compiler/typecheck/abstract/LetInTypesAbs.gfs.gold b/testsuite/compiler/typecheck/abstract/LetInTypesAbs.gfs.gold index 588b1643d..bbd381681 100644 --- a/testsuite/compiler/typecheck/abstract/LetInTypesAbs.gfs.gold +++ b/testsuite/compiler/typecheck/abstract/LetInTypesAbs.gfs.gold @@ -1 +1,3 @@ -fun f : (Int -> Int) -> Int -> Int +fun f : (Int -> Int) -> Int -> Int ; +Probability: 1.0 + diff --git a/testsuite/compiler/typecheck/abstract/test_A.gfs.gold b/testsuite/compiler/typecheck/abstract/test_A.gfs.gold index 821a4da2c..d99a5ec08 100644 --- a/testsuite/compiler/typecheck/abstract/test_A.gfs.gold +++ b/testsuite/compiler/typecheck/abstract/test_A.gfs.gold @@ -1,5 +1,6 @@ -testsuite/compiler/typecheck/abstract/A.gf:4: - Happened in the category B - Prod expected for function A instead of Type +testsuite/compiler/typecheck/abstract/A.gf: + testsuite/compiler/typecheck/abstract/A.gf:4: + Happened in the category B + Prod expected for function A instead of Type diff --git a/testsuite/compiler/typecheck/abstract/test_B.gfs.gold b/testsuite/compiler/typecheck/abstract/test_B.gfs.gold index 1355ff7c5..3c923c6de 100644 --- a/testsuite/compiler/typecheck/abstract/test_B.gfs.gold +++ b/testsuite/compiler/typecheck/abstract/test_B.gfs.gold @@ -1,5 +1,6 @@ -testsuite/compiler/typecheck/abstract/B.gf:5: - Happened in the type of function f - Prod expected for function S instead of Type +testsuite/compiler/typecheck/abstract/B.gf: + testsuite/compiler/typecheck/abstract/B.gf:5: + Happened in the type of function f + Prod expected for function S instead of Type diff --git a/testsuite/compiler/typecheck/abstract/test_C.gfs.gold b/testsuite/compiler/typecheck/abstract/test_C.gfs.gold index d055b11cd..d86aeda8b 100644 --- a/testsuite/compiler/typecheck/abstract/test_C.gfs.gold +++ b/testsuite/compiler/typecheck/abstract/test_C.gfs.gold @@ -1,5 +1,6 @@ -testsuite/compiler/typecheck/abstract/C.gf:6: - Happened in the definition of function f - {Int <> S} +testsuite/compiler/typecheck/abstract/C.gf: + testsuite/compiler/typecheck/abstract/C.gf:6: + Happened in the definition of function f + {Int <> S} diff --git a/testsuite/compiler/typecheck/concrete/test_A.gfs.gold b/testsuite/compiler/typecheck/concrete/test_A.gfs.gold index 1bd4dffab..19b66a865 100644 --- a/testsuite/compiler/typecheck/concrete/test_A.gfs.gold +++ b/testsuite/compiler/typecheck/concrete/test_A.gfs.gold @@ -1,5 +1,9 @@ -testsuite/compiler/typecheck/concrete/A.gf:5: - Happened in operation silly - A function type is expected for a_Det instead of type Str +testsuite/compiler/typecheck/concrete/A.gf: + testsuite/compiler/typecheck/concrete/A.gf:5: + Happened in operation silly + A function type is expected for a_Det instead of type Str + + ** Maybe you gave too many arguments to a_Det + diff --git a/testsuite/runtime/linearize/brackets.gfs.gold b/testsuite/runtime/linearize/brackets.gfs.gold index e356e6521..7337daa9d 100644 --- a/testsuite/runtime/linearize/brackets.gfs.gold +++ b/testsuite/runtime/linearize/brackets.gfs.gold @@ -1,28 +1,19 @@ (S:2 (E:1 (_:0 ?1)) is even) - (S:3 exists x such that (S:2 (E:1 (_:0 x)) is even)) - (S:1 (E:0 a)) - (S:1 (E:0 aa) a) - (S:1 (E:0 a) b) - (S:1 (String:0 abcd) is string) - (S:1 (Int:0 100) is integer) - (S:1 (Float:0 12.4) is float) - (S:1 (String:0 xyz) is string) - -cannot linearize + cannot linearize diff --git a/testsuite/runtime/linearize/linearize.gfs.gold b/testsuite/runtime/linearize/linearize.gfs.gold index 8a17ab506..7749644f1 100644 --- a/testsuite/runtime/linearize/linearize.gfs.gold +++ b/testsuite/runtime/linearize/linearize.gfs.gold @@ -1,30 +1,20 @@ ?1 is even - exists x such that x is even - a - aa a - a b - abcd is string - 100 is integer - 12.4 is float - xyz is string - - diff --git a/testsuite/runtime/typecheck/hard-unification.gfs.gold b/testsuite/runtime/typecheck/hard-unification.gfs.gold index 9ca737384..f21d6c2da 100644 --- a/testsuite/runtime/typecheck/hard-unification.gfs.gold +++ b/testsuite/runtime/typecheck/hard-unification.gfs.gold @@ -1,6 +1,8 @@ -Expression: s (\v0 -> v0) (app (\v0 -> v0)) ex -Type: S -Probability: 1.0 - -Meta variable(s) ?2 should be resolved -in the expression: s ?2 (app ?2) ?4 +Expression: s (\v0 -> v0) (app (\v0 -> v0)) ex +Type: S +Probability: 1.0 + +Meta variable(s) ?2 should be resolved +in the expression: s ?2 (app ?2) ?4 +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands diff --git a/testsuite/runtime/typecheck/implicit-arguments.gfs.gold b/testsuite/runtime/typecheck/implicit-arguments.gfs.gold index 3292c2ea1..eda2eb4fd 100644 --- a/testsuite/runtime/typecheck/implicit-arguments.gfs.gold +++ b/testsuite/runtime/typecheck/implicit-arguments.gfs.gold @@ -1,35 +1,37 @@ -Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) -Type: Path n1 n3 -Probability: 1.0000000000000002e-2 - -Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) -Type: Path n1 n3 -Probability: 1.0000000000000002e-2 - -Expression: -Type: Label {?1} -Probability: 1.0 - -Expression: -Type: Label {n1} -Probability: 1.0 - -{n1} is implicit argument but not implicit argument is expected here -Expression: <\{_1}, x -> x : ({m} : Node) -> (n : Node) -> Node> -Type: ({m} : Node) -> (n : Node) -> Node -Probability: 1.0 - -Expression: <\{_1} -> n1 : ({m} : Node) -> Node> -Type: ({m} : Node) -> Node -Probability: 1.0 - -Expression: <\{_1} -> ?1 : ({m} : Node) -> Node> -Type: ({m} : Node) -> Node -Probability: 1.0 - -Expression: -Type: Path n1 n1 -Probability: 1.0 - -n1 - +Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) +Type: Path n1 n3 +Probability: 1.0000000000000002e-2 + +Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) +Type: Path n1 n3 +Probability: 1.0000000000000002e-2 + +Expression: +Type: Label {?1} +Probability: 1.0 + +Expression: +Type: Label {n1} +Probability: 1.0 + +{n1} is implicit argument but not implicit argument is expected here +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: <\{_1}, x -> x : ({m} : Node) -> (n : Node) -> Node> +Type: ({m} : Node) -> (n : Node) -> Node +Probability: 1.0 + +Expression: <\{_1} -> n1 : ({m} : Node) -> Node> +Type: ({m} : Node) -> Node +Probability: 1.0 + +Expression: <\{_1} -> ?1 : ({m} : Node) -> Node> +Type: ({m} : Node) -> Node +Probability: 1.0 + +Expression: +Type: Path n1 n1 +Probability: 1.0 + +n1 + diff --git a/testsuite/runtime/typecheck/typecheck.gfs.gold b/testsuite/runtime/typecheck/typecheck.gfs.gold index 048b6d892..a6a1b7d2e 100644 --- a/testsuite/runtime/typecheck/typecheck.gfs.gold +++ b/testsuite/runtime/typecheck/typecheck.gfs.gold @@ -1,86 +1,118 @@ -Couldn't match expected type Nat - against inferred type String -In the expression: "0" -Category Int should have 0 argument(s), but has been given 1 -In the type: Int 0 -A function type is expected for the expression 1 instead of type Int -Couldn't match expected type Int -> Int - against inferred type Int -In the expression: 1 -unknown category of function identifier unknown_fun - -Category unknown_cat is not in scope -Cannot infer the type of expression \x -> x -A function type is expected for the expression \x -> x instead of type Int -Expression: append (succ (succ zero)) (succ zero) (vector (succ (succ zero))) (vector (succ zero)) -Type: Vector (succ (succ (succ zero))) -Probability: 3.532127097800926e-8 - -Expression: <\m, n -> vector (plus m n) : (m : Nat) -> (n : Nat) -> Vector (plus m n)> -Type: (m : Nat) -> (n : Nat) -> Vector (plus m n) -Probability: 1.0 - -Expression: mkMorph (\x -> succ zero) -Type: Morph (\v0 -> succ zero) -Probability: 0.5 - -Expression: idMorph (mkMorph (\x -> x)) -Type: Nat -Probability: 0.125 - -Couldn't match expected type Morph (\v0 -> v0) - against inferred type Morph (\v0 -> succ zero) -In the expression: mkMorph (\x -> succ zero) -Expression: Vector (succ zero) -> Vector (succ zero)> -Type: Vector zero -> Vector (succ zero) -> Vector (succ zero) -Probability: 1.0 - -Expression: <\n, v1, n1, v2 -> append n n1 v1 v2 : (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m)> -Type: (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m) -Probability: 1.0 - -Category EQ is not in scope -Expression: <\v1, v2 -> cmpVector ?7 v1 v2 : Vector ?7 -> Vector ?7 -> Int> (vector ?7) -Type: Vector ?7 -> Int -Probability: 0.3333333333333333 - -Couldn't match expected type (m : Nat) -> Vector ?1 - against inferred type (n : Nat) -> Vector n -In the expression: vector -Expression: f1 (\v -> v) vector -Type: Int -Probability: 5.555555555555555e-2 - -Expression: f1 (\v -> succ v) (\x -> vector (succ x)) -Type: Int -Probability: 0.16666666666666666 - -Couldn't match expected type Vector x - against inferred type Vector (succ x) -In the expression: vector (succ x) -Couldn't match expected type Vector n - against inferred type Vector (succ n) -In the expression: vector (succ n) -Expression: h ?2 (u0 ?2) -Type: Int -Probability: 8.333333333333333e-2 - -Couldn't match expected type U ?2 ?2 - against inferred type U ?2 (succ ?2) -In the expression: u1 ?2 -Meta variable(s) ?11 should be resolved -in the expression: cmpVector (succ (succ zero)) (vector (succ (succ zero))) (append ?11 (succ zero) (vector ?11) (vector (succ zero))) -Expression: diff (succ (succ (succ zero))) (succ (succ zero)) (vector (succ (succ (succ (succ (succ zero)))))) (vector (succ (succ (succ zero)))) -Type: Vector (succ (succ zero)) -Probability: 2.1558392930913853e-12 - -Couldn't match expected type Vector (plus (succ (succ (succ zero))) (succ (succ zero))) - against inferred type Vector (succ (succ (succ (succ zero)))) -In the expression: vector (succ (succ (succ (succ zero)))) -Expression: idMorph (mkMorph2 (\x -> x) (vector zero)) -Type: Nat -Probability: 1.0416666666666666e-2 - -Couldn't match expected type Vector zero - against inferred type Vector n -In the expression: x +Couldn't match expected type Nat + against inferred type String +In the expression: "0" +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Category Int should have 0 argument(s), but has been given 1 +In the type: Int 0 +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +A function type is expected for the expression 1 instead of type Int +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Couldn't match expected type Int -> Int + against inferred type Int +In the expression: 1 +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +unknown category of function identifier unknown_fun + +Category unknown_cat is not in scope +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Cannot infer the type of expression \x -> x +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +A function type is expected for the expression \x -> x instead of type Int +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: append (succ (succ zero)) (succ zero) (vector (succ (succ zero))) (vector (succ zero)) +Type: Vector (succ (succ (succ zero))) +Probability: 3.532127097800926e-8 + +Expression: <\m, n -> vector (plus m n) : (m : Nat) -> (n : Nat) -> Vector (plus m n)> +Type: (m : Nat) -> (n : Nat) -> Vector (plus m n) +Probability: 1.0 + +Expression: mkMorph (\x -> succ zero) +Type: Morph (\v0 -> succ zero) +Probability: 0.5 + +Expression: idMorph (mkMorph (\x -> x)) +Type: Nat +Probability: 0.125 + +Couldn't match expected type Morph (\v0 -> v0) + against inferred type Morph (\v0 -> succ zero) +In the expression: mkMorph (\x -> succ zero) +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: Vector (succ zero) -> Vector (succ zero)> +Type: Vector zero -> Vector (succ zero) -> Vector (succ zero) +Probability: 1.0 + +Expression: <\n, v1, n1, v2 -> append n n1 v1 v2 : (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m)> +Type: (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m) +Probability: 1.0 + +Category EQ is not in scope +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: <\v1, v2 -> cmpVector ?7 v1 v2 : Vector ?7 -> Vector ?7 -> Int> (vector ?7) +Type: Vector ?7 -> Int +Probability: 0.3333333333333333 + +Couldn't match expected type (m : Nat) -> Vector ?1 + against inferred type (n : Nat) -> Vector n +In the expression: vector +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: f1 (\v -> v) vector +Type: Int +Probability: 5.555555555555555e-2 + +Expression: f1 (\v -> succ v) (\x -> vector (succ x)) +Type: Int +Probability: 0.16666666666666666 + +Couldn't match expected type Vector x + against inferred type Vector (succ x) +In the expression: vector (succ x) +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Couldn't match expected type Vector n + against inferred type Vector (succ n) +In the expression: vector (succ n) +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: h ?2 (u0 ?2) +Type: Int +Probability: 8.333333333333333e-2 + +Couldn't match expected type U ?2 ?2 + against inferred type U ?2 (succ ?2) +In the expression: u1 ?2 +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Meta variable(s) ?11 should be resolved +in the expression: cmpVector (succ (succ zero)) (vector (succ (succ zero))) (append ?11 (succ zero) (vector ?11) (vector (succ zero))) +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: diff (succ (succ (succ zero))) (succ (succ zero)) (vector (succ (succ (succ (succ (succ zero)))))) (vector (succ (succ (succ zero)))) +Type: Vector (succ (succ zero)) +Probability: 2.1558392930913853e-12 + +Couldn't match expected type Vector (plus (succ (succ (succ zero))) (succ (succ zero))) + against inferred type Vector (succ (succ (succ (succ zero)))) +In the expression: vector (succ (succ (succ (succ zero)))) +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: idMorph (mkMorph2 (\x -> x) (vector zero)) +Type: Nat +Probability: 1.0416666666666666e-2 + +Couldn't match expected type Vector zero + against inferred type Vector n +In the expression: x +CallStack (from HasCallStack): + error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands From ecb19013c09438b8c193f28e77f813a887d57b27 Mon Sep 17 00:00:00 2001 From: Jacob Tan En Date: Wed, 9 Jun 2021 18:31:16 +0800 Subject: [PATCH 30/75] Update index-3.11.md `Cabal install` is fragile and can fail if the GHC on path is of an incompatible version. Use ghcup to use a GHC version that is known to work. --- download/index-3.11.md | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/download/index-3.11.md b/download/index-3.11.md index c128e77ce..0ebf0f031 100644 --- a/download/index-3.11.md +++ b/download/index-3.11.md @@ -49,15 +49,17 @@ 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). -## Installing the latest release from source +## Installing the latest Hackage release (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: -1. Install a recent version of the [Haskell Platform](http://hackage.haskell.org/platform) (see note below) -2. `cabal update` -3. On Linux: install some C libraries from your Linux distribution (see note below) -4. `cabal install gf` +1. Install ghcup https://www.haskell.org/ghcup/ +2. `ghcup install ghc 8.10.4` +3. `ghcup set ghc 8.10.4` +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**. @@ -74,17 +76,6 @@ so you might want to add this directory to your path (in `.bash_profile` or simi PATH=$HOME/.cabal/bin:$PATH ``` -**Build tools** - -In order to compile GF you need the build tools **Alex** and **Happy**. -These can be installed via Cabal, e.g.: - -``` -cabal install alex happy -``` - -or obtained by other means, depending on your OS. - **Haskeline** GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which From 6179d79e72e4d200e6ccaeb504f38ddba510e959 Mon Sep 17 00:00:00 2001 From: Jacob Tan En Date: Wed, 9 Jun 2021 19:56:08 +0800 Subject: [PATCH 31/75] Update gf.cabal `cabal install` needs this --- gf.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/gf.cabal b/gf.cabal index 731e2e2e7..608a5d636 100644 --- a/gf.cabal +++ b/gf.cabal @@ -14,6 +14,7 @@ maintainer: Thomas Hallgren tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3 data-dir: src +extra-source-files: WebSetup.hs data-files: www/*.html www/*.css From 544b39a8a5ea156f934c0cc41d774fe047409063 Mon Sep 17 00:00:00 2001 From: Tristan Koh Date: Thu, 10 Jun 2021 12:00:57 +0800 Subject: [PATCH 32/75] changed build wheels repo link from master to main --- .github/workflows/build-python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index 6326821dc..67cbba6dd 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -25,7 +25,7 @@ jobs: - name: Install cibuildwheel run: | - python -m pip install git+https://github.com/joerick/cibuildwheel.git@master + python -m pip install git+https://github.com/joerick/cibuildwheel.git@main - name: Install build tools for OSX if: startsWith(matrix.os, 'macos') From 53c3afbd6f0df2991b41459fe46d3a8c37d11278 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Fri, 11 Jun 2021 13:55:04 +0800 Subject: [PATCH 33/75] Remove CallStack outputs from gold files Rather, we should not output these, or output them in a nicer way. --- .../typecheck/hard-unification.gfs.gold | 14 +- .../typecheck/implicit-arguments.gfs.gold | 72 +++---- .../runtime/typecheck/typecheck.gfs.gold | 204 ++++++++---------- 3 files changed, 127 insertions(+), 163 deletions(-) diff --git a/testsuite/runtime/typecheck/hard-unification.gfs.gold b/testsuite/runtime/typecheck/hard-unification.gfs.gold index f21d6c2da..9ca737384 100644 --- a/testsuite/runtime/typecheck/hard-unification.gfs.gold +++ b/testsuite/runtime/typecheck/hard-unification.gfs.gold @@ -1,8 +1,6 @@ -Expression: s (\v0 -> v0) (app (\v0 -> v0)) ex -Type: S -Probability: 1.0 - -Meta variable(s) ?2 should be resolved -in the expression: s ?2 (app ?2) ?4 -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Expression: s (\v0 -> v0) (app (\v0 -> v0)) ex +Type: S +Probability: 1.0 + +Meta variable(s) ?2 should be resolved +in the expression: s ?2 (app ?2) ?4 diff --git a/testsuite/runtime/typecheck/implicit-arguments.gfs.gold b/testsuite/runtime/typecheck/implicit-arguments.gfs.gold index eda2eb4fd..3292c2ea1 100644 --- a/testsuite/runtime/typecheck/implicit-arguments.gfs.gold +++ b/testsuite/runtime/typecheck/implicit-arguments.gfs.gold @@ -1,37 +1,35 @@ -Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) -Type: Path n1 n3 -Probability: 1.0000000000000002e-2 - -Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) -Type: Path n1 n3 -Probability: 1.0000000000000002e-2 - -Expression: -Type: Label {?1} -Probability: 1.0 - -Expression: -Type: Label {n1} -Probability: 1.0 - -{n1} is implicit argument but not implicit argument is expected here -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: <\{_1}, x -> x : ({m} : Node) -> (n : Node) -> Node> -Type: ({m} : Node) -> (n : Node) -> Node -Probability: 1.0 - -Expression: <\{_1} -> n1 : ({m} : Node) -> Node> -Type: ({m} : Node) -> Node -Probability: 1.0 - -Expression: <\{_1} -> ?1 : ({m} : Node) -> Node> -Type: ({m} : Node) -> Node -Probability: 1.0 - -Expression: -Type: Path n1 n1 -Probability: 1.0 - -n1 - +Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) +Type: Path n1 n3 +Probability: 1.0000000000000002e-2 + +Expression: join {n1} {n2} {n3} l12 (link {n2} {n3} l23) +Type: Path n1 n3 +Probability: 1.0000000000000002e-2 + +Expression: +Type: Label {?1} +Probability: 1.0 + +Expression: +Type: Label {n1} +Probability: 1.0 + +{n1} is implicit argument but not implicit argument is expected here +Expression: <\{_1}, x -> x : ({m} : Node) -> (n : Node) -> Node> +Type: ({m} : Node) -> (n : Node) -> Node +Probability: 1.0 + +Expression: <\{_1} -> n1 : ({m} : Node) -> Node> +Type: ({m} : Node) -> Node +Probability: 1.0 + +Expression: <\{_1} -> ?1 : ({m} : Node) -> Node> +Type: ({m} : Node) -> Node +Probability: 1.0 + +Expression: +Type: Path n1 n1 +Probability: 1.0 + +n1 + diff --git a/testsuite/runtime/typecheck/typecheck.gfs.gold b/testsuite/runtime/typecheck/typecheck.gfs.gold index a6a1b7d2e..048b6d892 100644 --- a/testsuite/runtime/typecheck/typecheck.gfs.gold +++ b/testsuite/runtime/typecheck/typecheck.gfs.gold @@ -1,118 +1,86 @@ -Couldn't match expected type Nat - against inferred type String -In the expression: "0" -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Category Int should have 0 argument(s), but has been given 1 -In the type: Int 0 -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -A function type is expected for the expression 1 instead of type Int -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Couldn't match expected type Int -> Int - against inferred type Int -In the expression: 1 -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -unknown category of function identifier unknown_fun - -Category unknown_cat is not in scope -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Cannot infer the type of expression \x -> x -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -A function type is expected for the expression \x -> x instead of type Int -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: append (succ (succ zero)) (succ zero) (vector (succ (succ zero))) (vector (succ zero)) -Type: Vector (succ (succ (succ zero))) -Probability: 3.532127097800926e-8 - -Expression: <\m, n -> vector (plus m n) : (m : Nat) -> (n : Nat) -> Vector (plus m n)> -Type: (m : Nat) -> (n : Nat) -> Vector (plus m n) -Probability: 1.0 - -Expression: mkMorph (\x -> succ zero) -Type: Morph (\v0 -> succ zero) -Probability: 0.5 - -Expression: idMorph (mkMorph (\x -> x)) -Type: Nat -Probability: 0.125 - -Couldn't match expected type Morph (\v0 -> v0) - against inferred type Morph (\v0 -> succ zero) -In the expression: mkMorph (\x -> succ zero) -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: Vector (succ zero) -> Vector (succ zero)> -Type: Vector zero -> Vector (succ zero) -> Vector (succ zero) -Probability: 1.0 - -Expression: <\n, v1, n1, v2 -> append n n1 v1 v2 : (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m)> -Type: (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m) -Probability: 1.0 - -Category EQ is not in scope -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: <\v1, v2 -> cmpVector ?7 v1 v2 : Vector ?7 -> Vector ?7 -> Int> (vector ?7) -Type: Vector ?7 -> Int -Probability: 0.3333333333333333 - -Couldn't match expected type (m : Nat) -> Vector ?1 - against inferred type (n : Nat) -> Vector n -In the expression: vector -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: f1 (\v -> v) vector -Type: Int -Probability: 5.555555555555555e-2 - -Expression: f1 (\v -> succ v) (\x -> vector (succ x)) -Type: Int -Probability: 0.16666666666666666 - -Couldn't match expected type Vector x - against inferred type Vector (succ x) -In the expression: vector (succ x) -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Couldn't match expected type Vector n - against inferred type Vector (succ n) -In the expression: vector (succ n) -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: h ?2 (u0 ?2) -Type: Int -Probability: 8.333333333333333e-2 - -Couldn't match expected type U ?2 ?2 - against inferred type U ?2 (succ ?2) -In the expression: u1 ?2 -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Meta variable(s) ?11 should be resolved -in the expression: cmpVector (succ (succ zero)) (vector (succ (succ zero))) (append ?11 (succ zero) (vector ?11) (vector (succ zero))) -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: diff (succ (succ (succ zero))) (succ (succ zero)) (vector (succ (succ (succ (succ (succ zero)))))) (vector (succ (succ (succ zero)))) -Type: Vector (succ (succ zero)) -Probability: 2.1558392930913853e-12 - -Couldn't match expected type Vector (plus (succ (succ (succ zero))) (succ (succ zero))) - against inferred type Vector (succ (succ (succ (succ zero)))) -In the expression: vector (succ (succ (succ (succ zero)))) -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands -Expression: idMorph (mkMorph2 (\x -> x) (vector zero)) -Type: Nat -Probability: 1.0416666666666666e-2 - -Couldn't match expected type Vector zero - against inferred type Vector n -In the expression: x -CallStack (from HasCallStack): - error, called at src/compiler/GF/Command/Commands.hs:744:43 in gf-3.10.4-EdD6fabQUzM4AhRenbxTb3:GF.Command.Commands +Couldn't match expected type Nat + against inferred type String +In the expression: "0" +Category Int should have 0 argument(s), but has been given 1 +In the type: Int 0 +A function type is expected for the expression 1 instead of type Int +Couldn't match expected type Int -> Int + against inferred type Int +In the expression: 1 +unknown category of function identifier unknown_fun + +Category unknown_cat is not in scope +Cannot infer the type of expression \x -> x +A function type is expected for the expression \x -> x instead of type Int +Expression: append (succ (succ zero)) (succ zero) (vector (succ (succ zero))) (vector (succ zero)) +Type: Vector (succ (succ (succ zero))) +Probability: 3.532127097800926e-8 + +Expression: <\m, n -> vector (plus m n) : (m : Nat) -> (n : Nat) -> Vector (plus m n)> +Type: (m : Nat) -> (n : Nat) -> Vector (plus m n) +Probability: 1.0 + +Expression: mkMorph (\x -> succ zero) +Type: Morph (\v0 -> succ zero) +Probability: 0.5 + +Expression: idMorph (mkMorph (\x -> x)) +Type: Nat +Probability: 0.125 + +Couldn't match expected type Morph (\v0 -> v0) + against inferred type Morph (\v0 -> succ zero) +In the expression: mkMorph (\x -> succ zero) +Expression: Vector (succ zero) -> Vector (succ zero)> +Type: Vector zero -> Vector (succ zero) -> Vector (succ zero) +Probability: 1.0 + +Expression: <\n, v1, n1, v2 -> append n n1 v1 v2 : (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m)> +Type: (n : Nat) -> Vector n -> (m : Nat) -> Vector m -> Vector (plus n m) +Probability: 1.0 + +Category EQ is not in scope +Expression: <\v1, v2 -> cmpVector ?7 v1 v2 : Vector ?7 -> Vector ?7 -> Int> (vector ?7) +Type: Vector ?7 -> Int +Probability: 0.3333333333333333 + +Couldn't match expected type (m : Nat) -> Vector ?1 + against inferred type (n : Nat) -> Vector n +In the expression: vector +Expression: f1 (\v -> v) vector +Type: Int +Probability: 5.555555555555555e-2 + +Expression: f1 (\v -> succ v) (\x -> vector (succ x)) +Type: Int +Probability: 0.16666666666666666 + +Couldn't match expected type Vector x + against inferred type Vector (succ x) +In the expression: vector (succ x) +Couldn't match expected type Vector n + against inferred type Vector (succ n) +In the expression: vector (succ n) +Expression: h ?2 (u0 ?2) +Type: Int +Probability: 8.333333333333333e-2 + +Couldn't match expected type U ?2 ?2 + against inferred type U ?2 (succ ?2) +In the expression: u1 ?2 +Meta variable(s) ?11 should be resolved +in the expression: cmpVector (succ (succ zero)) (vector (succ (succ zero))) (append ?11 (succ zero) (vector ?11) (vector (succ zero))) +Expression: diff (succ (succ (succ zero))) (succ (succ zero)) (vector (succ (succ (succ (succ (succ zero)))))) (vector (succ (succ (succ zero)))) +Type: Vector (succ (succ zero)) +Probability: 2.1558392930913853e-12 + +Couldn't match expected type Vector (plus (succ (succ (succ zero))) (succ (succ zero))) + against inferred type Vector (succ (succ (succ (succ zero)))) +In the expression: vector (succ (succ (succ (succ zero)))) +Expression: idMorph (mkMorph2 (\x -> x) (vector zero)) +Type: Nat +Probability: 1.0416666666666666e-2 + +Couldn't match expected type Vector zero + against inferred type Vector n +In the expression: x From fd4fb62b9e287afaceca3f789623856bd64f0ee3 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Fri, 11 Jun 2021 13:55:20 +0800 Subject: [PATCH 34/75] Add output files for test suite in gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 01b58ccb4..b698d53ab 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,10 @@ DATA_DIR stack*.yaml.lock +# Output files for test suite +*.out +gf-tests.html + # Generated documentation (not exhaustive) demos/index-numbers.html demos/resourcegrammars.html From c3153134b73a21a1059dc6896b35097f37dfdd14 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 16 Jun 2021 12:01:28 +0800 Subject: [PATCH 35/75] Remove CStr [] which causes error, update gold --- testsuite/compiler/typecheck/abstract/LitAbs.gf | 2 +- .../compiler/typecheck/abstract/LitAbs.gfs | 1 - .../compiler/typecheck/abstract/LitAbs.gfs.gold | 17 ++++++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/testsuite/compiler/typecheck/abstract/LitAbs.gf b/testsuite/compiler/typecheck/abstract/LitAbs.gf index 03f850232..08230b8cf 100644 --- a/testsuite/compiler/typecheck/abstract/LitAbs.gf +++ b/testsuite/compiler/typecheck/abstract/LitAbs.gf @@ -5,7 +5,7 @@ cat CStr String ; CFloat Float ; data empty : CStr "" ; - null : CStr [] ; + -- null : CStr [] ; -- Commented out by IL 06/2021: causes parse error other : CStr "other" ; data zero : CInt 0 ; diff --git a/testsuite/compiler/typecheck/abstract/LitAbs.gfs b/testsuite/compiler/typecheck/abstract/LitAbs.gfs index ce10daa20..71c4cca29 100644 --- a/testsuite/compiler/typecheck/abstract/LitAbs.gfs +++ b/testsuite/compiler/typecheck/abstract/LitAbs.gfs @@ -1,5 +1,4 @@ i -src testsuite/compiler/typecheck/abstract/LitAbs.gf -ai null ai empty ai other ai zero diff --git a/testsuite/compiler/typecheck/abstract/LitAbs.gfs.gold b/testsuite/compiler/typecheck/abstract/LitAbs.gfs.gold index 83dda9094..2d1e93979 100644 --- a/testsuite/compiler/typecheck/abstract/LitAbs.gfs.gold +++ b/testsuite/compiler/typecheck/abstract/LitAbs.gfs.gold @@ -1,5 +1,12 @@ -data null : CStr "" -data empty : CStr "" -data other : CStr "other" -data zero : CInt 0 -data pi : CFloat 3.14 +data empty : CStr "" ; +Probability: 0.5 + +data other : CStr "other" ; +Probability: 0.5 + +data zero : CInt 0 ; +Probability: 1.0 + +data pi : CFloat 3.14 ; +Probability: 1.0 + From f23031ea1d0fc1171d15f115b642adf42ed454fa Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 16 Jun 2021 12:23:07 +0800 Subject: [PATCH 36/75] Add command `ai f` to trigger error msg --- testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs b/testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs index 0b07b7ed4..1edc94e02 100644 --- a/testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs +++ b/testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs @@ -1,2 +1,5 @@ i -src testsuite/compiler/typecheck/abstract/PolyTypes.gf -i -src testsuite/compiler/typecheck/abstract/RecTypes.gf \ No newline at end of file +ai f + +i -src testsuite/compiler/typecheck/abstract/RecTypes.gf +ai f \ No newline at end of file From b1ed63b089cbe0ba8530475ff6a1b2582de37d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Wed, 16 Jun 2021 14:26:22 +0800 Subject: [PATCH 37/75] Don't print stack traces in Command.hs They don't provide useful info anyways and they are needlessly verbose. --- src/compiler/GF/Command/Commands.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/GF/Command/Commands.hs b/src/compiler/GF/Command/Commands.hs index 0e5c61404..48d8cb85a 100644 --- a/src/compiler/GF/Command/Commands.hs +++ b/src/compiler/GF/Command/Commands.hs @@ -741,7 +741,7 @@ pgfCommands = Map.fromList [ Nothing -> do putStrLn ("unknown category of function identifier "++show id) return void [e] -> case inferExpr pgf e of - Left tcErr -> error $ render (ppTcError tcErr) + Left tcErr -> errorWithoutStackTrace $ render (ppTcError tcErr) Right (e,ty) -> do putStrLn ("Expression: "++showExpr [] e) putStrLn ("Type: "++showType [] ty) putStrLn ("Probability: "++show (probTree pgf e)) From f505d88a8e9e664c90acc98a9cf9ec7d68a1f4f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Wed, 16 Jun 2021 14:27:19 +0800 Subject: [PATCH 38/75] Fix build of test suite on ghc-8.2.2 --- testsuite/run.hs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/testsuite/run.hs b/testsuite/run.hs index 7f377af79..ed013ab0f 100644 --- a/testsuite/run.hs +++ b/testsuite/run.hs @@ -1,7 +1,7 @@ import Data.List(partition) import System.IO import Distribution.Simple.BuildPaths(exeExtension) -import Distribution.System ( buildPlatform ) +import Distribution.System ( buildPlatform, OS (Windows), Platform (Platform) ) import System.Process(readProcess) import System.Directory(doesFileExist,getDirectoryContents) import System.FilePath((),(<.>),takeExtension) @@ -73,7 +73,12 @@ main = -- Should consult the Cabal configuration! run_gf = readProcess default_gf -default_gf = "gf"<.>exeExtension buildPlatform +default_gf = "gf"<.>exeExtension + where + -- shadows Distribution.Simple.BuildPaths.exeExtension, which changed type signature in Cabal 2.4 + exeExtension = case buildPlatform of + Platform arch Windows -> "exe" + _ -> "" -- | List files, excluding "." and ".." ls path = filter (`notElem` [".",".."]) `fmap` getDirectoryContents path From 2c37e7dfad66bbfb13cef87fdcef479ce9fd9e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Wed, 16 Jun 2021 14:54:36 +0800 Subject: [PATCH 39/75] Fix build for ghc-7.10.3 --- src/compiler/GF/Command/Commands.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/GF/Command/Commands.hs b/src/compiler/GF/Command/Commands.hs index 48d8cb85a..2f2e802e0 100644 --- a/src/compiler/GF/Command/Commands.hs +++ b/src/compiler/GF/Command/Commands.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE FlexibleInstances, UndecidableInstances #-} +{-# LANGUAGE FlexibleInstances, UndecidableInstances, CPP #-} module GF.Command.Commands ( PGFEnv,HasPGFEnv(..),pgf,mos,pgfEnv,pgfCommands, options,flags, @@ -1019,3 +1019,7 @@ stanzas = map unlines . chop . lines where chop ls = case break (=="") ls of (ls1,[]) -> [ls1] (ls1,_:ls2) -> ls1 : chop ls2 + +#if !(MIN_VERSION_base(4,9,0)) +errorWithoutStackTrace = error +#endif \ No newline at end of file From 7065125e1979fd45f650e6248f8724b7a0124417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Wed, 16 Jun 2021 15:25:22 +0800 Subject: [PATCH 40/75] Fix "canonicalizePath: does not exist" issue on ghc-7.10 This caused failures in the test suite Only fixes it for stack builds. We should probably add constraints to the cabal file as well --- stack-ghc7.10.3.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stack-ghc7.10.3.yaml b/stack-ghc7.10.3.yaml index 0761b54af..6869d6572 100644 --- a/stack-ghc7.10.3.yaml +++ b/stack-ghc7.10.3.yaml @@ -4,6 +4,8 @@ extra-deps: - happy-1.19.9 - alex-3.2.4 - transformers-compat-0.6.5 +- directory-1.2.3.0 +- process-1.2.3.0@sha256:ee08707f1c806ad4a628c5997d8eb6e66d2ae924283548277d85a66341d57322,1806 allow-newer: true From 65522a63c3d3aaf8e350db514bf9494e545b1c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Thu, 17 Jun 2021 16:38:33 +0800 Subject: [PATCH 41/75] Testsuite: Add support for expected failures And mark the currently failing tests as expected failures --- testsuite/run.hs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/testsuite/run.hs b/testsuite/run.hs index ed013ab0f..4f231368b 100644 --- a/testsuite/run.hs +++ b/testsuite/run.hs @@ -11,7 +11,7 @@ main = do res <- walk "testsuite" let cnt = length res (good,bad) = partition ((=="OK").fst.snd) res - ok = length good + ok = length good + length (filter ((=="FAIL (expected)").fst.snd) bad) fail = okexeExtension From 889be1ab8ed6a71feea211ff8ce1ca0ed72d4d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Thu, 17 Jun 2021 16:42:04 +0800 Subject: [PATCH 42/75] Enable tests in github actions --- .github/workflows/build-all-versions.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-all-versions.yml b/.github/workflows/build-all-versions.yml index 46bd05b23..fde8b2157 100644 --- a/.github/workflows/build-all-versions.yml +++ b/.github/workflows/build-all-versions.yml @@ -56,9 +56,9 @@ jobs: cabal configure --enable-tests --enable-benchmarks --test-show-details=direct cabal build all - # - name: Test - # run: | - # cabal test all + - name: Test + run: | + cabal test all stack: name: stack / ghc ${{ matrix.ghc }} @@ -90,6 +90,6 @@ jobs: 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 + - name: Test + run: | + stack test --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml From 0a18688788f300a8a305114e69bde84bdaf1ea8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Thu, 17 Jun 2021 19:24:14 +0800 Subject: [PATCH 43/75] Remove gf-lib-path from testsuite Since it no longer depends on RGL and it caused issues in the testsuite --- testsuite/run.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testsuite/run.hs b/testsuite/run.hs index 4f231368b..7faf9625e 100644 --- a/testsuite/run.hs +++ b/testsuite/run.hs @@ -55,8 +55,7 @@ main = runTest in_file out_file gold_file = do input <- readFile in_file - rgl_lib_dir <- readFile "DATA_DIR" - writeFile out_file =<< run_gf ["-run","-gf-lib-path=" ++ rgl_lib_dir] input + writeFile out_file =<< run_gf ["-run"] input exists <- doesFileExist gold_file if exists then do out <- compatReadFile out_file From 02671cafd0049f0793206a7d13c47a74e89ae2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Thu, 17 Jun 2021 20:20:18 +0800 Subject: [PATCH 44/75] Disable cabal tests The test suite isn't currently able to find the gf executable on cabal --- .github/workflows/build-all-versions.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-all-versions.yml b/.github/workflows/build-all-versions.yml index fde8b2157..fca637189 100644 --- a/.github/workflows/build-all-versions.yml +++ b/.github/workflows/build-all-versions.yml @@ -56,9 +56,9 @@ jobs: cabal configure --enable-tests --enable-benchmarks --test-show-details=direct cabal build all - - name: Test - run: | - cabal test all + # - name: Test + # run: | + # cabal test all stack: name: stack / ghc ${{ matrix.ghc }} From 5564a2f2448f2f13050ae3ba11bed168411aa486 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 22 Jun 2021 13:35:46 +0200 Subject: [PATCH 45/75] Make stack.yaml a regular file again --- stack.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) mode change 120000 => 100644 stack.yaml diff --git a/stack.yaml b/stack.yaml deleted file mode 120000 index 84f47e45a..000000000 --- a/stack.yaml +++ /dev/null @@ -1 +0,0 @@ -stack-ghc8.6.5.yaml \ No newline at end of file diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 000000000..69b8c8790 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,16 @@ +# This default stack file is a copy of stack-ghc8.6.5.yaml +# But committing a symlink can be problematic on Windows, so it's a real copy. +# See: https://github.com/GrammaticalFramework/gf-core/pull/106 + +resolver: lts-14.27 # ghc 8.6.5 + +extra-deps: +- network-2.6.3.6 +- httpd-shed-0.4.0.3 +- cgi-3001.5.0.0 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib From 91d2ecf23c77e488bd904c7f343d9ce4464a8761 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 23 Jun 2021 09:16:03 +0200 Subject: [PATCH 46/75] Update RELEASE.md Add link to gf maintainers on Hackage. --- RELEASE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASE.md b/RELEASE.md index 3a771b78d..04bd4b933 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -45,6 +45,8 @@ but the generated _artifacts_ must be manually attached to the release as _asset ### 4. Upload to 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` 2. Upload the package, either: 1. **Manually**: visit and upload the file `dist/gf-X.Y.tar.gz` From cf9afa8f744f6babee1982a62921b6d53a174c4b Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 23 Jun 2021 09:20:44 +0200 Subject: [PATCH 47/75] Update README.md Add `stack install` as alternative to `cabal install` --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2afa476ea..e393be0e6 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,16 @@ GF particularly addresses four aspects of grammars: ## Compilation and installation -The simplest way of installing GF is with the command: +The simplest way of installing GF from source is with the command: ``` cabal install ``` +or: +``` +stack install +``` -For more details, see the [download page](http://www.grammaticalframework.org/download/index.html) -and [developers manual](http://www.grammaticalframework.org/doc/gf-developers.html). +For more information, including links to precompiled binaries, see the [download page](http://www.grammaticalframework.org/download/index.html). ## About this repository From 1ba5449d210b2b5565e1a3179548cfb2df9fce1b Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 24 Jun 2021 09:31:37 +0200 Subject: [PATCH 48/75] Update pgf.cabal, and minors to other cabal files --- gf.cabal | 4 ++-- src/runtime/haskell-bind/pgf2.cabal | 3 +-- src/runtime/haskell/pgf.cabal | 30 ++++++++++++++--------------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/gf.cabal b/gf.cabal index 608a5d636..9a9e3903e 100644 --- a/gf.cabal +++ b/gf.cabal @@ -72,7 +72,7 @@ flag c-runtime Description: Include functionality from the C run-time library (which must be installed already) Default: False -Library +library default-language: Haskell2010 build-depends: base >= 4.6 && <5, array, @@ -320,7 +320,7 @@ Library if impl(ghc>=8.2) ghc-options: -fhide-source-paths -Executable gf +executable gf hs-source-dirs: src/programs main-is: gf-main.hs default-language: Haskell2010 diff --git a/src/runtime/haskell-bind/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal index 91e77c77b..c8d5d8c6c 100644 --- a/src/runtime/haskell-bind/pgf2.cabal +++ b/src/runtime/haskell-bind/pgf2.cabal @@ -9,8 +9,7 @@ homepage: https://www.grammaticalframework.org license: LGPL-3 license-file: LICENSE author: Krasimir Angelov -maintainer: kr.angelov@gmail.com -category: Language +category: Natural Language Processing build-type: Simple extra-source-files: CHANGELOG.md, README.md cabal-version: >=1.10 diff --git a/src/runtime/haskell/pgf.cabal b/src/runtime/haskell/pgf.cabal index 76e12bd2c..86faf8f01 100644 --- a/src/runtime/haskell/pgf.cabal +++ b/src/runtime/haskell/pgf.cabal @@ -1,5 +1,5 @@ name: pgf -version: 3.10 +version: 3.10.1-git cabal-version: >= 1.20 build-type: Simple @@ -9,20 +9,21 @@ synopsis: Grammatical Framework description: A library for interpreting the Portable Grammar Format (PGF) homepage: http://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues -maintainer: Thomas Hallgren -tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2 +tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC=8.4.4 -Library - default-language: Haskell2010 - build-depends: base >= 4.6 && <5, - array, - containers, - bytestring, - utf8-string, - random, - pretty, - mtl, - exceptions +library + default-language: Haskell2010 + build-depends: + array, + base >= 4.6 && <5, + bytestring, + containers, + -- exceptions, + ghc-prim, + mtl, + pretty, + random, + utf8-string other-modules: -- not really part of GF but I have changed the original binary library @@ -37,7 +38,6 @@ Library --if impl(ghc>=7.8) -- ghc-options: +RTS -A20M -RTS ghc-prof-options: -fprof-auto - extensions: exposed-modules: PGF From 3a27fa0d390b86cab3ecc68418e4116ea5c4f8ba Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 24 Jun 2021 09:34:27 +0200 Subject: [PATCH 49/75] Add another = --- src/runtime/haskell/pgf.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/haskell/pgf.cabal b/src/runtime/haskell/pgf.cabal index 86faf8f01..f829a6e35 100644 --- a/src/runtime/haskell/pgf.cabal +++ b/src/runtime/haskell/pgf.cabal @@ -9,7 +9,7 @@ synopsis: Grammatical Framework description: A library for interpreting the Portable Grammar Format (PGF) homepage: http://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues -tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC=8.4.4 +tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC==8.4.4 library default-language: Haskell2010 From 0a70eca6e2913c462c5c65361131f3ed341e539d Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 30 Jun 2021 10:58:23 +0200 Subject: [PATCH 50/75] Make GF.Grammar.Canonical.Id a type synonym for GF.Infra.Ident.RawIdent This avoids a lot of conversion back and forth between Strings and ByteStrings This commit was cherry-picked from d0c27cdaae78c670b098740bfb49b428d900e640 (lpgf branch) --- src/compiler/GF/Compile/ConcreteToHaskell.hs | 47 +++++++++---------- src/compiler/GF/Compile/GrammarToCanonical.hs | 36 +++++++------- src/compiler/GF/Grammar/Canonical.hs | 3 +- src/compiler/GF/Grammar/CanonicalJSON.hs | 37 ++++++++------- src/compiler/GF/Infra/Ident.hs | 39 +++++++-------- 5 files changed, 86 insertions(+), 76 deletions(-) diff --git a/src/compiler/GF/Compile/ConcreteToHaskell.hs b/src/compiler/GF/Compile/ConcreteToHaskell.hs index d74fcdacd..c9f0438e6 100644 --- a/src/compiler/GF/Compile/ConcreteToHaskell.hs +++ b/src/compiler/GF/Compile/ConcreteToHaskell.hs @@ -7,7 +7,7 @@ import GF.Text.Pretty --import GF.Grammar.Predef(cPredef,cInts) --import GF.Compile.Compute.Predef(predef) --import GF.Compile.Compute.Value(Predefined(..)) -import GF.Infra.Ident(Ident,identS,identW,prefixIdent) +import GF.Infra.Ident(Ident,identC,identS,identW,prefixIdent,showRawIdent,rawIdentS) import GF.Infra.Option import GF.Haskell as H import GF.Grammar.Canonical as C @@ -21,7 +21,7 @@ concretes2haskell opts absname gr = | let Grammar abstr cncs = grammar2canonical opts absname gr, cncmod<-cncs, let ModId name = concName cncmod - filename = name ++ ".hs" :: FilePath + filename = showRawIdent name ++ ".hs" :: FilePath ] -- | Generate Haskell code for the given concrete module. @@ -53,7 +53,7 @@ concrete2haskell opts labels = S.difference (S.unions (map S.fromList recs)) common_labels common_records = S.fromList [[label_s]] common_labels = S.fromList [label_s] - label_s = LabelId "s" + label_s = LabelId (rawIdentS "s") signature (CatDef c _) = TypeSig lf (Fun abs (pure lin)) where @@ -69,7 +69,7 @@ concrete2haskell opts where --funcats = S.fromList [c | FunDef f (C.Type _ (TypeApp c _))<-funs] allcats = S.fromList [c | CatDef c _<-cats] - + gId :: ToIdent i => i -> Ident gId = (if haskellOption opts HaskellNoPrefix then id else prefixIdent "G") . toIdent @@ -116,7 +116,7 @@ concrete2haskell opts where (ls,ts) = unzip $ sortOn fst [(l,t)|RecordRow l t<-rs] StrType -> tcon0 (identS "Str") TableType pt lt -> Fun (ppT pt) (ppT lt) --- TupleType lts -> +-- TupleType lts -> lincatDef (LincatDef c t) = tsyn0 (lincatName c) (convLinType t) @@ -126,7 +126,7 @@ concrete2haskell opts linDefs = map eqn . sortOn fst . map linDef where eqn (cat,(f,(ps,rhs))) = (cat,Eqn (f,ps) rhs) - linDef (LinDef f xs rhs0) = + linDef (LinDef f xs rhs0) = (cat,(linfunName cat,(lhs,rhs))) where lhs = [ConP (aId f) (map VarP abs_args)] @@ -144,7 +144,7 @@ concrete2haskell opts where vs = [(VarValueId (Unqual x),a)|(VarId x,a)<-zip xs args] env= [(VarValueId (Unqual x),lc)|(VarId x,lc)<-zip xs (map arglincat absctx)] - + letlin a (TypeBinding _ (C.Type _ (TypeApp acat _))) = (a,Ap (Var (linfunName acat)) (Var (abs_arg a))) @@ -187,7 +187,7 @@ concrete2haskell opts pId p@(ParamId s) = if "to_R_" `isPrefixOf` unqual s then toIdent p else gId p -- !! a hack - + table cs = if all (null.patVars) ps then lets ds (LambdaCase [(ppP p,t')|(p,t')<-zip ps ts']) @@ -315,13 +315,13 @@ instance Records rhs => Records (TableRow rhs) where -- | Record subtyping is converted into explicit coercions in Haskell coerce env ty t = - case (ty,t) of + case (ty,t) of (_,VariantValue ts) -> VariantValue (map (coerce env ty) ts) (TableType ti tv,TableValue _ cs) -> TableValue ti [TableRow p (coerce env tv t)|TableRow p t<-cs] (RecordType rt,RecordValue r) -> RecordValue [RecordRow l (coerce env ft f) | - RecordRow l f<-r,ft<-[ft|RecordRow l' ft<-rt,l'==l]] + RecordRow l f<-r,ft<-[ft | RecordRow l' ft <- rt, l'==l]] (RecordType rt,VarValue x)-> case lookup x env of Just ty' | ty'/=ty -> -- better to compare to normal form of ty' @@ -334,18 +334,17 @@ coerce env ty t = _ -> t where app f ts = ParamConstant (Param f ts) -- !! a hack - to_rcon = ParamId . Unqual . to_rcon' . labels + to_rcon = ParamId . Unqual . rawIdentS . to_rcon' . labels patVars p = [] -labels r = [l|RecordRow l _<-r] +labels r = [l | RecordRow l _ <- r] proj = Var . identS . proj' -proj' (LabelId l) = "proj_"++l +proj' (LabelId l) = "proj_" ++ showRawIdent l rcon = Var . rcon' rcon' = identS . rcon_name -rcon_name ls = "R"++concat (sort ['_':l|LabelId l<-ls]) - +rcon_name ls = "R"++concat (sort ['_':showRawIdent l | LabelId l <- ls]) to_rcon' = ("to_"++) . rcon_name recordType ls = @@ -400,17 +399,17 @@ linfunName c = prefixIdent "lin" (toIdent c) class ToIdent i where toIdent :: i -> Ident -instance ToIdent ParamId where toIdent (ParamId q) = qIdentS q -instance ToIdent PredefId where toIdent (PredefId s) = identS s -instance ToIdent CatId where toIdent (CatId s) = identS s -instance ToIdent C.FunId where toIdent (FunId s) = identS s -instance ToIdent VarValueId where toIdent (VarValueId q) = qIdentS q +instance ToIdent ParamId where toIdent (ParamId q) = qIdentC q +instance ToIdent PredefId where toIdent (PredefId s) = identC s +instance ToIdent CatId where toIdent (CatId s) = identC s +instance ToIdent C.FunId where toIdent (FunId s) = identC s +instance ToIdent VarValueId where toIdent (VarValueId q) = qIdentC q -qIdentS = identS . unqual +qIdentC = identS . unqual -unqual (Qual (ModId m) n) = m++"_"++n -unqual (Unqual n) = n +unqual (Qual (ModId m) n) = showRawIdent m++"_"++ showRawIdent n +unqual (Unqual n) = showRawIdent n instance ToIdent VarId where toIdent Anonymous = identW - toIdent (VarId s) = identS s + toIdent (VarId s) = identC s diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 33f35ad08..2b701382c 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -16,7 +16,7 @@ import GF.Grammar.Lockfield(isLockLabel) import GF.Grammar.Predef(cPredef,cInts) import GF.Compile.Compute.Predef(predef) import GF.Compile.Compute.Value(Predefined(..)) -import GF.Infra.Ident(ModuleName(..),Ident,prefixIdent,showIdent,isWildIdent) +import GF.Infra.Ident(ModuleName(..),Ident,ident2raw,rawIdentS,prefixIdent,showIdent,isWildIdent) import GF.Infra.Option(optionsPGF) import PGF.Internal(Literal(..)) import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues) @@ -69,10 +69,10 @@ concretes2canonical opts absname gr = concrete2canonical gr cenv absname cnc modinfo = Concrete (modId cnc) (modId absname) (convFlags gr cnc) (neededParamTypes S.empty (params defs)) - [lincat|(_,Left lincat)<-defs] - [lin|(_,Right lin)<-defs] + [lincat | (_,Left lincat) <- defs] + [lin | (_,Right lin) <- defs] where - defs = concatMap (toCanonical gr absname cenv) . + defs = concatMap (toCanonical gr absname cenv) . M.toList $ jments modinfo @@ -188,8 +188,8 @@ convert' gr vs = ppT Ok ALL_CAPIT -> p "ALL_CAPIT" _ -> VarValue (gQId cPredef n) -- hmm where - p = PredefValue . PredefId - + p = PredefValue . PredefId . rawIdentS + ppP p = case p of PC c ps -> ParamPattern (Param (gId c) (map ppP ps)) @@ -247,7 +247,7 @@ projection r l = maybe (Projection r l) id (proj r l) proj r l = case r of - RecordValue r -> case [v|RecordRow l' v<-r,l'==l] of + RecordValue r -> case [v | RecordRow l' v <- r, l'==l] of [v] -> Just v _ -> Nothing _ -> Nothing @@ -257,7 +257,7 @@ selection t v = -- Note: impossible cases can become possible after grammar transformation case t of TableValue tt r -> - case nub [rv|TableRow _ rv<-keep] of + case nub [rv | TableRow _ rv <- keep] of [rv] -> rv _ -> Selection (TableValue tt r') v where @@ -357,16 +357,20 @@ paramType gr q@(_,n) = argTypes = S.unions . map argTypes1 argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx] -lblId = LabelId . render -- hmm -modId (MN m) = ModId (showIdent m) +lblId :: Label -> C.LabelId +lblId (LIdent ri) = LabelId ri +lblId (LVar i) = LabelId (rawIdentS (show i)) -- hmm + +modId :: ModuleName -> C.ModId +modId (MN m) = ModId (ident2raw m) class FromIdent i where gId :: Ident -> i instance FromIdent VarId where - gId i = if isWildIdent i then Anonymous else VarId (showIdent i) + gId i = if isWildIdent i then Anonymous else VarId (ident2raw i) -instance FromIdent C.FunId where gId = C.FunId . showIdent -instance FromIdent CatId where gId = CatId . showIdent +instance FromIdent C.FunId where gId = C.FunId . ident2raw +instance FromIdent CatId where gId = CatId . ident2raw instance FromIdent ParamId where gId = ParamId . unqual instance FromIdent VarValueId where gId = VarValueId . unqual @@ -375,11 +379,11 @@ class FromIdent i => QualIdent i where gQId :: ModuleName -> Ident -> i instance QualIdent ParamId where gQId m n = ParamId (qual m n) instance QualIdent VarValueId where gQId m n = VarValueId (qual m n) -qual m n = Qual (modId m) (showIdent n) -unqual n = Unqual (showIdent n) +qual m n = Qual (modId m) (ident2raw n) +unqual n = Unqual (ident2raw n) convFlags gr mn = - Flags [(n,convLit v) | + Flags [(rawIdentS n,convLit v) | (n,v)<-err (const []) (optionsPGF.mflags) (lookupModule gr mn)] where convLit l = diff --git a/src/compiler/GF/Grammar/Canonical.hs b/src/compiler/GF/Grammar/Canonical.hs index 0df3236ff..80e9f5e7b 100644 --- a/src/compiler/GF/Grammar/Canonical.hs +++ b/src/compiler/GF/Grammar/Canonical.hs @@ -11,6 +11,7 @@ module GF.Grammar.Canonical where import Prelude hiding ((<>)) import GF.Text.Pretty +import GF.Infra.Ident (RawIdent) -- | A Complete grammar data Grammar = Grammar Abstract [Concrete] deriving Show @@ -126,7 +127,7 @@ data FlagValue = Str String | Int Int | Flt Double deriving Show -- *** Identifiers -type Id = String +type Id = RawIdent data QualId = Qual ModId Id | Unqual Id deriving (Eq,Ord,Show) -------------------------------------------------------------------------------- diff --git a/src/compiler/GF/Grammar/CanonicalJSON.hs b/src/compiler/GF/Grammar/CanonicalJSON.hs index 0ec7f43e6..04c13df5e 100644 --- a/src/compiler/GF/Grammar/CanonicalJSON.hs +++ b/src/compiler/GF/Grammar/CanonicalJSON.hs @@ -7,6 +7,7 @@ import Control.Applicative ((<|>)) import Data.Ratio (denominator, numerator) import GF.Grammar.Canonical import Control.Monad (guard) +import GF.Infra.Ident (RawIdent,showRawIdent,rawIdentS) encodeJSON :: FilePath -> Grammar -> IO () @@ -29,7 +30,7 @@ instance JSON Grammar where -- ** Abstract Syntax instance JSON Abstract where - showJSON (Abstract absid flags cats funs) + showJSON (Abstract absid flags cats funs) = makeObj [("abs", showJSON absid), ("flags", showJSON flags), ("cats", showJSON cats), @@ -81,7 +82,7 @@ instance JSON TypeBinding where -- ** Concrete syntax instance JSON Concrete where - showJSON (Concrete cncid absid flags params lincats lins) + showJSON (Concrete cncid absid flags params lincats lins) = makeObj [("cnc", showJSON cncid), ("abs", showJSON absid), ("flags", showJSON flags), @@ -204,12 +205,12 @@ instance JSON a => JSON (RecordRow a) where -- record rows and lists of record rows are both encoded as JSON records (i.e., objects) showJSON row = showJSONs [row] showJSONs rows = makeObj (map toRow rows) - where toRow (RecordRow (LabelId lbl) val) = (lbl, showJSON val) + where toRow (RecordRow (LabelId lbl) val) = (showRawIdent lbl, showJSON val) readJSON obj = head <$> readJSONs obj readJSONs obj = mapM fromRow (assocsJSObject obj) where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue - return (RecordRow (LabelId lbl) value) + return (RecordRow (LabelId (rawIdentS lbl)) value) instance JSON rhs => JSON (TableRow rhs) where showJSON (TableRow l v) = makeObj [(".pattern", showJSON l), (".value", showJSON v)] @@ -219,19 +220,19 @@ instance JSON rhs => JSON (TableRow rhs) where -- *** Identifiers in Concrete Syntax -instance JSON PredefId where showJSON (PredefId s) = showJSON s ; readJSON = fmap PredefId . readJSON -instance JSON LabelId where showJSON (LabelId s) = showJSON s ; readJSON = fmap LabelId . readJSON -instance JSON VarValueId where showJSON (VarValueId s) = showJSON s ; readJSON = fmap VarValueId . readJSON -instance JSON ParamId where showJSON (ParamId s) = showJSON s ; readJSON = fmap ParamId . readJSON -instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s ; readJSON = fmap ParamTypeId . readJSON +instance JSON PredefId where showJSON (PredefId s) = showJSON s ; readJSON = fmap PredefId . readJSON +instance JSON LabelId where showJSON (LabelId s) = showJSON s ; readJSON = fmap LabelId . readJSON +instance JSON VarValueId where showJSON (VarValueId s) = showJSON s ; readJSON = fmap VarValueId . readJSON +instance JSON ParamId where showJSON (ParamId s) = showJSON s ; readJSON = fmap ParamId . readJSON +instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s ; readJSON = fmap ParamTypeId . readJSON -------------------------------------------------------------------------------- -- ** Used in both Abstract and Concrete Syntax -instance JSON ModId where showJSON (ModId s) = showJSON s ; readJSON = fmap ModId . readJSON -instance JSON CatId where showJSON (CatId s) = showJSON s ; readJSON = fmap CatId . readJSON -instance JSON FunId where showJSON (FunId s) = showJSON s ; readJSON = fmap FunId . readJSON +instance JSON ModId where showJSON (ModId s) = showJSON s ; readJSON = fmap ModId . readJSON +instance JSON CatId where showJSON (CatId s) = showJSON s ; readJSON = fmap CatId . readJSON +instance JSON FunId where showJSON (FunId s) = showJSON s ; readJSON = fmap FunId . readJSON instance JSON VarId where -- the anonymous variable is the underscore: @@ -242,20 +243,24 @@ instance JSON VarId where <|> VarId <$> readJSON o instance JSON QualId where - showJSON (Qual (ModId m) n) = showJSON (m++"."++n) + showJSON (Qual (ModId m) n) = showJSON (showRawIdent m++"."++showRawIdent n) showJSON (Unqual n) = showJSON n readJSON o = do qualid <- readJSON o let (mod, id) = span (/= '.') qualid - return $ if null mod then Unqual id else Qual (ModId mod) id + return $ if null mod then Unqual (rawIdentS id) else Qual (ModId (rawIdentS mod)) (rawIdentS id) + +instance JSON RawIdent where + showJSON i = showJSON $ showRawIdent i + readJSON o = rawIdentS <$> readJSON o instance JSON Flags where -- flags are encoded directly as JSON records (i.e., objects): - showJSON (Flags fs) = makeObj [(f, showJSON v) | (f, v) <- fs] + showJSON (Flags fs) = makeObj [(showRawIdent f, showJSON v) | (f, v) <- fs] readJSON obj = Flags <$> mapM fromRow (assocsJSObject obj) where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue - return (lbl, value) + return (rawIdentS lbl, value) instance JSON FlagValue where -- flag values are encoded as basic JSON types: diff --git a/src/compiler/GF/Infra/Ident.hs b/src/compiler/GF/Infra/Ident.hs index b856d3995..ad47d91cd 100644 --- a/src/compiler/GF/Infra/Ident.hs +++ b/src/compiler/GF/Infra/Ident.hs @@ -5,7 +5,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/11/15 11:43:33 $ +-- > CVS $Date: 2005/11/15 11:43:33 $ -- > CVS $Author: aarne $ -- > CVS $Revision: 1.8 $ -- @@ -13,18 +13,18 @@ ----------------------------------------------------------------------------- module GF.Infra.Ident (-- ** Identifiers - ModuleName(..), moduleNameS, - Ident, ident2utf8, showIdent, prefixIdent, - -- *** Normal identifiers (returned by the parser) - identS, identC, identW, - -- *** Special identifiers for internal use - identV, identA, identAV, - argIdent, isArgIdent, getArgIndex, - varStr, varX, isWildIdent, varIndex, - -- *** Raw identifiers - RawIdent, rawIdentS, rawIdentC, ident2raw, prefixRawIdent, - isPrefixOf, showRawIdent - ) where + ModuleName(..), moduleNameS, + Ident, ident2utf8, showIdent, prefixIdent, + -- *** Normal identifiers (returned by the parser) + identS, identC, identW, + -- *** Special identifiers for internal use + identV, identA, identAV, + argIdent, isArgIdent, getArgIndex, + varStr, varX, isWildIdent, varIndex, + -- *** Raw identifiers + RawIdent, rawIdentS, rawIdentC, ident2raw, prefixRawIdent, + isPrefixOf, showRawIdent +) where import qualified Data.ByteString.UTF8 as UTF8 import qualified Data.ByteString.Char8 as BS(append,isPrefixOf) @@ -46,7 +46,7 @@ instance Pretty ModuleName where pp (MN m) = pp m -- | the constructors labelled /INTERNAL/ are -- internal representation never returned by the parser -data Ident = +data Ident = IC {-# UNPACK #-} !RawIdent -- ^ raw identifier after parsing, resolved in Rename | IW -- ^ wildcard -- @@ -54,7 +54,7 @@ data Ident = | IV {-# UNPACK #-} !RawIdent {-# UNPACK #-} !Int -- ^ /INTERNAL/ variable | IA {-# UNPACK #-} !RawIdent {-# UNPACK #-} !Int -- ^ /INTERNAL/ argument of cat at position | IAV {-# UNPACK #-} !RawIdent {-# UNPACK #-} !Int {-# UNPACK #-} !Int -- ^ /INTERNAL/ argument of cat with bindings at position --- +-- deriving (Eq, Ord, Show, Read) -- | Identifiers are stored as UTF-8-encoded bytestrings. @@ -70,14 +70,13 @@ rawIdentS = Id . pack rawIdentC = Id showRawIdent = unpack . rawId2utf8 -prefixRawIdent (Id x) (Id y) = Id (BS.append x y) +prefixRawIdent (Id x) (Id y) = Id (BS.append x y) isPrefixOf (Id x) (Id y) = BS.isPrefixOf x y instance Binary RawIdent where put = put . rawId2utf8 get = fmap rawIdentC get - -- | This function should be used with care, since the returned ByteString is -- UTF-8-encoded. ident2utf8 :: Ident -> UTF8.ByteString @@ -88,6 +87,7 @@ ident2utf8 i = case i of IAV (Id s) b j -> BS.append s (pack ('_':show b ++ '_':show j)) IW -> pack "_" +ident2raw :: Ident -> RawIdent ident2raw = Id . ident2utf8 showIdent :: Ident -> String @@ -95,13 +95,14 @@ showIdent i = unpack $! ident2utf8 i instance Pretty Ident where pp = pp . showIdent +instance Pretty RawIdent where pp = pp . showRawIdent + identS :: String -> Ident identS = identC . rawIdentS identC :: RawIdent -> Ident identW :: Ident - prefixIdent :: String -> Ident -> Ident prefixIdent pref = identC . Id . BS.append (pack pref) . ident2utf8 @@ -112,7 +113,7 @@ identV :: RawIdent -> Int -> Ident identA :: RawIdent -> Int -> Ident identAV:: RawIdent -> Int -> Int -> Ident -(identC, identV, identA, identAV, identW) = +(identC, identV, identA, identAV, identW) = (IC, IV, IA, IAV, IW) -- | to mark argument variables From d5c6aec3ec58b981d702eada8feab6685a0acea4 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 30 Jun 2021 12:12:26 +0200 Subject: [PATCH 51/75] Superficial refactoring to testsuite module --- testsuite/run.hs | 104 ++++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/testsuite/run.hs b/testsuite/run.hs index 7faf9625e..f8e6bf49f 100644 --- a/testsuite/run.hs +++ b/testsuite/run.hs @@ -1,13 +1,17 @@ import Data.List(partition) import System.IO import Distribution.Simple.BuildPaths(exeExtension) -import Distribution.System ( buildPlatform, OS (Windows), Platform (Platform) ) +import Distribution.System(buildPlatform, OS (Windows), Platform (Platform) ) import System.Process(readProcess) import System.Directory(doesFileExist,getDirectoryContents) import System.FilePath((),(<.>),takeExtension) import System.Exit(exitSuccess,exitFailure) -main = +type TestResult = (FilePath, RunResult) +type RunResult = (String, (String, String, String)) -- (message, (input commands, gold output, actual output)) + +main :: IO () +main = do res <- walk "testsuite" let cnt = length res (good,bad) = partition ((=="OK").fst.snd) res @@ -16,29 +20,16 @@ main = putStrLn $ show ok++"/"++show cnt++ " passed/tests" let overview = "gf-tests.html" writeFile overview (toHTML bad) - if ok IO [TestResult] +walk path = fmap concat . mapM (walkFile . (path )) =<< ls path where - toHTML res = - "\n" - ++ "\n" - ++ "\n" - ++ "\n
ResultInputGoldOutput\n" - ++ unlines (map testToHTML res) - ++ "
\n" - - testToHTML (in_file,(res,(input,gold,output))) = - ""++concatMap td [pre res,in_file++":\n"++pre input,pre gold,pre output] - pre s = "
"++s++"
" - td s = ""++s - - walk path = fmap concat . mapM (walkFile . (path )) =<< ls path - + walkFile :: FilePath -> IO [TestResult] walkFile fpath = do exists <- doesFileExist fpath if exists @@ -53,25 +44,23 @@ main = else return [] else walk fpath - runTest in_file out_file gold_file = do - input <- readFile in_file - writeFile out_file =<< run_gf ["-run"] input - exists <- doesFileExist gold_file - if exists - then do out <- compatReadFile out_file - gold <- compatReadFile gold_file - let info = (input,gold,out) - if in_file `elem` expectedFailures - then return $! if out == gold then ("Unexpected success",info) else ("FAIL (expected)",info) - else return $! if out == gold then ("OK",info) else ("FAIL",info) - else do out <- compatReadFile out_file - return ("MISSING GOLD",(input,"",out)) - -- Avoid failures caused by Win32/Unix text file incompatibility - compatReadFile path = - do h <- openFile path ReadMode - hSetNewlineMode h universalNewlineMode - hGetContents h +-- | Run an individual test +runTest :: FilePath -> FilePath -> FilePath -> IO RunResult +runTest in_file out_file gold_file = do + input <- readFile in_file + writeFile out_file =<< runGF ["-run"] input + exists <- doesFileExist gold_file + if exists + then do out <- compatReadFile out_file + gold <- compatReadFile gold_file + let info = (input,gold,out) + if in_file `elem` expectedFailures + then return $! if out == gold then ("Unexpected success",info) else ("FAIL (expected)",info) + else return $! if out == gold then ("OK",info) else ("FAIL",info) + else do out <- compatReadFile out_file + return ("MISSING GOLD",(input,"",out)) +-- | Test scripts which should fail expectedFailures :: [String] expectedFailures = [ "testsuite/runtime/parser/parser.gfs" -- Only parses `z` as `zero` and not also as e.g. `succ zero` as expected @@ -79,9 +68,34 @@ expectedFailures = , "testsuite/compiler/typecheck/abstract/non-abstract-terms.gfs" -- Gives a different error than expected ] +-- | Produce HTML document with test results +toHTML :: [TestResult] -> String +toHTML res = + "\n" + ++ "\n" + ++ "\n" + ++ "\n
ResultInputGoldOutput\n" + ++ unlines (map testToHTML res) + ++ "
\n" + where + testToHTML (in_file,(res,(input,gold,output))) = + ""++concatMap td [pre res,in_file++":\n"++pre input,pre gold,pre output] + pre s = "
"++s++"
" + td s = ""++s + +-- | Run commands in GF shell, returning output +runGF + :: [String] -- ^ command line flags + -> String -- ^ standard input (shell commands) + -> IO String -- ^ standard output +runGF = readProcess defaultGF + -- Should consult the Cabal configuration! -run_gf = readProcess default_gf -default_gf = "gf"<.>exeExtension +defaultGF :: FilePath +defaultGF = "gf"<.>exeExtension where -- shadows Distribution.Simple.BuildPaths.exeExtension, which changed type signature in Cabal 2.4 exeExtension = case buildPlatform of @@ -89,4 +103,12 @@ default_gf = "gf"<.>exeExtension _ -> "" -- | List files, excluding "." and ".." +ls :: FilePath -> IO [String] ls path = filter (`notElem` [".",".."]) `fmap` getDirectoryContents path + +-- | Avoid failures caused by Win32/Unix text file incompatibility +compatReadFile :: FilePath -> IO String +compatReadFile path = + do h <- openFile path ReadMode + hSetNewlineMode h universalNewlineMode + hGetContents h From 0f5be0bbaa862d2ccdb649eb6dd9fc5e26814e8a Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 30 Jun 2021 12:41:56 +0200 Subject: [PATCH 52/75] Add shell script in testsuite/compiler/canonical for replicating known issues Ideally this is integrated into proper test suite, but that's too much overhead for now --- testsuite/compiler/canonical/.gitignore | 1 + testsuite/compiler/canonical/Foods.gf | 16 + testsuite/compiler/canonical/FoodsFin.gf | 6 + testsuite/compiler/canonical/FoodsFin.gf.gold | 102 ++++++ testsuite/compiler/canonical/FoodsI.gf | 29 ++ testsuite/compiler/canonical/Greetings.gf | 28 ++ testsuite/compiler/canonical/GreetingsBul.gf | 31 ++ testsuite/compiler/canonical/GreetingsGer.gf | 31 ++ testsuite/compiler/canonical/LexFoods.gf | 15 + testsuite/compiler/canonical/LexFoodsFin.gf | 21 ++ testsuite/compiler/canonical/Phrasebook.gf | 8 + testsuite/compiler/canonical/PhrasebookBul.gf | 9 + testsuite/compiler/canonical/PhrasebookGer.gf | 10 + testsuite/compiler/canonical/Sentences.gf | 222 +++++++++++++ testsuite/compiler/canonical/SentencesBul.gf | 54 ++++ testsuite/compiler/canonical/SentencesGer.gf | 50 +++ testsuite/compiler/canonical/SentencesI.gf | 302 +++++++++++++++++ testsuite/compiler/canonical/Words.gf | 254 +++++++++++++++ testsuite/compiler/canonical/WordsBul.gf | 305 ++++++++++++++++++ testsuite/compiler/canonical/WordsGer.gf | 262 +++++++++++++++ testsuite/compiler/canonical/run.sh | 23 ++ 21 files changed, 1779 insertions(+) create mode 100644 testsuite/compiler/canonical/.gitignore create mode 100644 testsuite/compiler/canonical/Foods.gf create mode 100644 testsuite/compiler/canonical/FoodsFin.gf create mode 100644 testsuite/compiler/canonical/FoodsFin.gf.gold create mode 100644 testsuite/compiler/canonical/FoodsI.gf create mode 100644 testsuite/compiler/canonical/Greetings.gf create mode 100644 testsuite/compiler/canonical/GreetingsBul.gf create mode 100644 testsuite/compiler/canonical/GreetingsGer.gf create mode 100644 testsuite/compiler/canonical/LexFoods.gf create mode 100644 testsuite/compiler/canonical/LexFoodsFin.gf create mode 100644 testsuite/compiler/canonical/Phrasebook.gf create mode 100644 testsuite/compiler/canonical/PhrasebookBul.gf create mode 100644 testsuite/compiler/canonical/PhrasebookGer.gf create mode 100644 testsuite/compiler/canonical/Sentences.gf create mode 100644 testsuite/compiler/canonical/SentencesBul.gf create mode 100644 testsuite/compiler/canonical/SentencesGer.gf create mode 100644 testsuite/compiler/canonical/SentencesI.gf create mode 100644 testsuite/compiler/canonical/Words.gf create mode 100644 testsuite/compiler/canonical/WordsBul.gf create mode 100644 testsuite/compiler/canonical/WordsGer.gf create mode 100755 testsuite/compiler/canonical/run.sh diff --git a/testsuite/compiler/canonical/.gitignore b/testsuite/compiler/canonical/.gitignore new file mode 100644 index 000000000..72988cf10 --- /dev/null +++ b/testsuite/compiler/canonical/.gitignore @@ -0,0 +1 @@ +canonical/ diff --git a/testsuite/compiler/canonical/Foods.gf b/testsuite/compiler/canonical/Foods.gf new file mode 100644 index 000000000..aa68d4429 --- /dev/null +++ b/testsuite/compiler/canonical/Foods.gf @@ -0,0 +1,16 @@ +-- (c) 2009 Aarne Ranta under LGPL + +abstract Foods = { + flags startcat = Comment ; + cat + Comment ; Item ; Kind ; Quality ; + fun + -- Pred : Item -> Quality -> Comment ; + -- This, That, These, Those : Kind -> Item ; + -- Mod : Quality -> Kind -> Kind ; + -- Wine, Cheese, Fish, Pizza : Kind ; + -- Very : Quality -> Quality ; + -- Fresh, Warm, Italian, + -- Expensive, Delicious, Boring : Quality ; + Expensive: Quality; +} diff --git a/testsuite/compiler/canonical/FoodsFin.gf b/testsuite/compiler/canonical/FoodsFin.gf new file mode 100644 index 000000000..962199805 --- /dev/null +++ b/testsuite/compiler/canonical/FoodsFin.gf @@ -0,0 +1,6 @@ + +-- (c) 2009 Aarne Ranta under LGPL + +concrete FoodsFin of Foods = FoodsI with + (Syntax = SyntaxFin), + (LexFoods = LexFoodsFin) ; diff --git a/testsuite/compiler/canonical/FoodsFin.gf.gold b/testsuite/compiler/canonical/FoodsFin.gf.gold new file mode 100644 index 000000000..55c2fa6c9 --- /dev/null +++ b/testsuite/compiler/canonical/FoodsFin.gf.gold @@ -0,0 +1,102 @@ +concrete FoodsFin of Foods = { +param ParamX_Number = ParamX_Sg | ParamX_Pl; +param Prelude_Bool = Prelude_False | Prelude_True; +param ResFin_Agr = ResFin_Ag ParamX_Number ParamX_Person | ResFin_AgPol; +param ParamX_Person = ParamX_P1 | ParamX_P2 | ParamX_P3; +param ResFin_Harmony = ResFin_Back | ResFin_Front; +param ResFin_NForm = + ResFin_NCase ParamX_Number ResFin_Case | ResFin_NComit | ResFin_NInstruct | + ResFin_NPossNom ParamX_Number | ResFin_NPossGen ParamX_Number | + ResFin_NPossTransl ParamX_Number | ResFin_NPossIllat ParamX_Number | + ResFin_NCompound; +param ResFin_Case = + ResFin_Nom | ResFin_Gen | ResFin_Part | ResFin_Transl | ResFin_Ess | + ResFin_Iness | ResFin_Elat | ResFin_Illat | ResFin_Adess | ResFin_Ablat | + ResFin_Allat | ResFin_Abess; +param ResFin_NPForm = ResFin_NPCase ResFin_Case | ResFin_NPAcc | ResFin_NPSep; +lincat Comment = {s : Str}; + Item = + {s : ResFin_NPForm => Str; a : ResFin_Agr; isNeg : Prelude_Bool; + isPron : Prelude_Bool}; + Kind = + {s : ResFin_NForm => Str; h : ResFin_Harmony; + postmod : ParamX_Number => Str}; + Quality = + {s : Prelude_Bool => ResFin_NForm => Str; hasPrefix : Prelude_Bool; + p : Str}; +lin Expensive = + {s = + table {Prelude_False => + table {ResFin_NCase ParamX_Sg ResFin_Nom => "kallis"; + ResFin_NCase ParamX_Sg ResFin_Gen => "kalliin"; + ResFin_NCase ParamX_Sg ResFin_Part => "kallista"; + ResFin_NCase ParamX_Sg ResFin_Transl => "kalliiksi"; + ResFin_NCase ParamX_Sg ResFin_Ess => "kalliina"; + ResFin_NCase ParamX_Sg ResFin_Iness => "kalliissa"; + ResFin_NCase ParamX_Sg ResFin_Elat => "kalliista"; + ResFin_NCase ParamX_Sg ResFin_Illat => "kalliiseen"; + ResFin_NCase ParamX_Sg ResFin_Adess => "kalliilla"; + ResFin_NCase ParamX_Sg ResFin_Ablat => "kalliilta"; + ResFin_NCase ParamX_Sg ResFin_Allat => "kalliille"; + ResFin_NCase ParamX_Sg ResFin_Abess => "kalliitta"; + ResFin_NCase ParamX_Pl ResFin_Nom => "kalliit"; + ResFin_NCase ParamX_Pl ResFin_Gen => "kalliiden"; + ResFin_NCase ParamX_Pl ResFin_Part => "kalliita"; + ResFin_NCase ParamX_Pl ResFin_Transl => "kalliiksi"; + ResFin_NCase ParamX_Pl ResFin_Ess => "kalliina"; + ResFin_NCase ParamX_Pl ResFin_Iness => "kalliissa"; + ResFin_NCase ParamX_Pl ResFin_Elat => "kalliista"; + ResFin_NCase ParamX_Pl ResFin_Illat => "kalliisiin"; + ResFin_NCase ParamX_Pl ResFin_Adess => "kalliilla"; + ResFin_NCase ParamX_Pl ResFin_Ablat => "kalliilta"; + ResFin_NCase ParamX_Pl ResFin_Allat => "kalliille"; + ResFin_NCase ParamX_Pl ResFin_Abess => "kalliitta"; + ResFin_NComit => "kalliine"; + ResFin_NInstruct => "kalliin"; + ResFin_NPossNom ParamX_Sg => "kallii"; + ResFin_NPossNom ParamX_Pl => "kallii"; + ResFin_NPossGen ParamX_Sg => "kallii"; + ResFin_NPossGen ParamX_Pl => "kalliide"; + ResFin_NPossTransl ParamX_Sg => "kalliikse"; + ResFin_NPossTransl ParamX_Pl => "kalliikse"; + ResFin_NPossIllat ParamX_Sg => "kalliisee"; + ResFin_NPossIllat ParamX_Pl => "kalliisii"; + ResFin_NCompound => "kallis"}; + Prelude_True => + table {ResFin_NCase ParamX_Sg ResFin_Nom => "kallis"; + ResFin_NCase ParamX_Sg ResFin_Gen => "kalliin"; + ResFin_NCase ParamX_Sg ResFin_Part => "kallista"; + ResFin_NCase ParamX_Sg ResFin_Transl => "kalliiksi"; + ResFin_NCase ParamX_Sg ResFin_Ess => "kalliina"; + ResFin_NCase ParamX_Sg ResFin_Iness => "kalliissa"; + ResFin_NCase ParamX_Sg ResFin_Elat => "kalliista"; + ResFin_NCase ParamX_Sg ResFin_Illat => "kalliiseen"; + ResFin_NCase ParamX_Sg ResFin_Adess => "kalliilla"; + ResFin_NCase ParamX_Sg ResFin_Ablat => "kalliilta"; + ResFin_NCase ParamX_Sg ResFin_Allat => "kalliille"; + ResFin_NCase ParamX_Sg ResFin_Abess => "kalliitta"; + ResFin_NCase ParamX_Pl ResFin_Nom => "kalliit"; + ResFin_NCase ParamX_Pl ResFin_Gen => "kalliiden"; + ResFin_NCase ParamX_Pl ResFin_Part => "kalliita"; + ResFin_NCase ParamX_Pl ResFin_Transl => "kalliiksi"; + ResFin_NCase ParamX_Pl ResFin_Ess => "kalliina"; + ResFin_NCase ParamX_Pl ResFin_Iness => "kalliissa"; + ResFin_NCase ParamX_Pl ResFin_Elat => "kalliista"; + ResFin_NCase ParamX_Pl ResFin_Illat => "kalliisiin"; + ResFin_NCase ParamX_Pl ResFin_Adess => "kalliilla"; + ResFin_NCase ParamX_Pl ResFin_Ablat => "kalliilta"; + ResFin_NCase ParamX_Pl ResFin_Allat => "kalliille"; + ResFin_NCase ParamX_Pl ResFin_Abess => "kalliitta"; + ResFin_NComit => "kalliine"; + ResFin_NInstruct => "kalliin"; + ResFin_NPossNom ParamX_Sg => "kallii"; + ResFin_NPossNom ParamX_Pl => "kallii"; + ResFin_NPossGen ParamX_Sg => "kallii"; + ResFin_NPossGen ParamX_Pl => "kalliide"; + ResFin_NPossTransl ParamX_Sg => "kalliikse"; + ResFin_NPossTransl ParamX_Pl => "kalliikse"; + ResFin_NPossIllat ParamX_Sg => "kalliisee"; + ResFin_NPossIllat ParamX_Pl => "kalliisii"; + ResFin_NCompound => "kallis"}}; + hasPrefix = Prelude_False; p = ""}; +} diff --git a/testsuite/compiler/canonical/FoodsI.gf b/testsuite/compiler/canonical/FoodsI.gf new file mode 100644 index 000000000..f4113b724 --- /dev/null +++ b/testsuite/compiler/canonical/FoodsI.gf @@ -0,0 +1,29 @@ +-- (c) 2009 Aarne Ranta under LGPL + +incomplete concrete FoodsI of Foods = + open Syntax, LexFoods in { + lincat + Comment = Utt ; + Item = NP ; + Kind = CN ; + Quality = AP ; + lin + Pred item quality = mkUtt (mkCl item quality) ; + This kind = mkNP this_Det kind ; + That kind = mkNP that_Det kind ; + These kind = mkNP these_Det kind ; + Those kind = mkNP those_Det kind ; + Mod quality kind = mkCN quality kind ; + Very quality = mkAP very_AdA quality ; + + Wine = mkCN wine_N ; + Pizza = mkCN pizza_N ; + Cheese = mkCN cheese_N ; + Fish = mkCN fish_N ; + Fresh = mkAP fresh_A ; + Warm = mkAP warm_A ; + Italian = mkAP italian_A ; + Expensive = mkAP expensive_A ; + Delicious = mkAP delicious_A ; + Boring = mkAP boring_A ; +} diff --git a/testsuite/compiler/canonical/Greetings.gf b/testsuite/compiler/canonical/Greetings.gf new file mode 100644 index 000000000..580b1560b --- /dev/null +++ b/testsuite/compiler/canonical/Greetings.gf @@ -0,0 +1,28 @@ +abstract Greetings = Sentences [Greeting] ** { + +fun + GBye : Greeting ; + GCheers : Greeting ; + GDamn : Greeting ; + GExcuse, GExcusePol : Greeting ; + GGoodDay : Greeting ; + GGoodEvening : Greeting ; + GGoodMorning : Greeting ; + GGoodNight : Greeting ; + GGoodbye : Greeting ; + GHello : Greeting ; + GHelp : Greeting ; + GHowAreYou : Greeting ; + GLookOut : Greeting ; + GNiceToMeetYou : Greeting ; + GPleaseGive, GPleaseGivePol : Greeting ; + GSeeYouSoon : Greeting ; + GSorry, GSorryPol : Greeting ; + GThanks : Greeting ; + GTheCheck : Greeting ; + GCongratulations : Greeting ; + GHappyBirthday : Greeting ; + GGoodLuck : Greeting ; + GWhatTime : Greeting ; + +} diff --git a/testsuite/compiler/canonical/GreetingsBul.gf b/testsuite/compiler/canonical/GreetingsBul.gf new file mode 100644 index 000000000..f271d7717 --- /dev/null +++ b/testsuite/compiler/canonical/GreetingsBul.gf @@ -0,0 +1,31 @@ +concrete GreetingsBul of Greetings = SentencesBul [Greeting,mkGreeting] ** open Prelude in { + +flags + coding=utf8; + +lin + GBye = mkGreeting "чао" ; + GCheers = mkGreeting "наздраве" ; + GDamn = mkGreeting "по дяволите" ; + GExcuse, GExcusePol = mkGreeting "извинете" ; + GGoodDay = mkGreeting "добър ден" ; + GGoodEvening = mkGreeting "добра вечер" ; + GGoodMorning = mkGreeting "добро утро" ; + GGoodNight = mkGreeting "лека нощ" ; + GGoodbye = mkGreeting "довиждане" ; + GHello = mkGreeting "здравей" ; + GHelp = mkGreeting "помощ" ; + GHowAreYou = mkGreeting "как си" ; + GLookOut = mkGreeting "погледни" ; + GNiceToMeetYou = mkGreeting "радвам се да се видим" ; + GPleaseGive, GPleaseGivePol = mkGreeting "моля" ; + GSeeYouSoon = mkGreeting "до скоро" ; + GSorry, GSorryPol = mkGreeting "извинете" ; + GThanks = mkGreeting "благодаря ти" ; + GTheCheck = mkGreeting "сметката" ; + GCongratulations = mkGreeting "поздравления"; + GHappyBirthday = mkGreeting "честит рожден ден" ; + GGoodLuck = mkGreeting "успех" ; + GWhatTime = mkGreeting "колко е часът" ; + +} diff --git a/testsuite/compiler/canonical/GreetingsGer.gf b/testsuite/compiler/canonical/GreetingsGer.gf new file mode 100644 index 000000000..f027d70ac --- /dev/null +++ b/testsuite/compiler/canonical/GreetingsGer.gf @@ -0,0 +1,31 @@ +--# -path=.:abstract:prelude:german:api:common +--# -coding=latin1 +concrete GreetingsGer of Greetings = SentencesGer [Greeting,mkGreeting] ** open Prelude in { + +lin + GBye = mkGreeting "tsch" ; + GCheers = mkGreeting "zum Wohl" ; + GDamn = mkGreeting "verdammt" ; + GExcuse, GExcusePol = mkGreeting "Entschuldigung" ; + GGoodDay = mkGreeting "guten Tag" ; + GGoodEvening = mkGreeting "guten Abend" ; + GGoodMorning = mkGreeting "guten Morgen" ; + GGoodNight = mkGreeting "gute Nacht" ; + GGoodbye = mkGreeting "auf Wiedersehen" ; + GHello = mkGreeting "Hallo" ; + GHelp = mkGreeting "Hilfe" ; + GHowAreYou = mkGreeting "wie geht's" ; + GLookOut = mkGreeting "Achtung" ; + GNiceToMeetYou = mkGreeting "nett, Sie zu treffen" ; + GPleaseGive, GPleaseGivePol = mkGreeting "bitte" ; + GSeeYouSoon = mkGreeting "bis bald" ; + GSorry, GSorryPol = mkGreeting "Entschuldigung" ; + GThanks = mkGreeting "Danke" ; + GTheCheck = mkGreeting "die Rechnung" ; + GCongratulations = mkGreeting "herzlichen Glckwunsch"; + GHappyBirthday = mkGreeting "alles Gute zum Geburtstag" ; + GGoodLuck = mkGreeting "viel Glck" ; + GWhatTime = mkGreeting "wieviel Uhr ist es" | mkGreeting "wie spt ist es" ; + +} + diff --git a/testsuite/compiler/canonical/LexFoods.gf b/testsuite/compiler/canonical/LexFoods.gf new file mode 100644 index 000000000..12ace208c --- /dev/null +++ b/testsuite/compiler/canonical/LexFoods.gf @@ -0,0 +1,15 @@ +-- (c) 2009 Aarne Ranta under LGPL + +interface LexFoods = open Syntax in { + oper + wine_N : N ; + pizza_N : N ; + cheese_N : N ; + fish_N : N ; + fresh_A : A ; + warm_A : A ; + italian_A : A ; + expensive_A : A ; + delicious_A : A ; + boring_A : A ; +} diff --git a/testsuite/compiler/canonical/LexFoodsFin.gf b/testsuite/compiler/canonical/LexFoodsFin.gf new file mode 100644 index 000000000..8b12f449f --- /dev/null +++ b/testsuite/compiler/canonical/LexFoodsFin.gf @@ -0,0 +1,21 @@ +-- (c) 2009 Aarne Ranta under LGPL +--# -coding=latin1 + +instance LexFoodsFin of LexFoods = + open SyntaxFin, ParadigmsFin in { + oper + wine_N = mkN "viini" ; + pizza_N = mkN "pizza" ; + cheese_N = mkN "juusto" ; + fish_N = mkN "kala" ; + fresh_A = mkA "tuore" ; + warm_A = mkA + (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�mpim�mpi" "l�mpimin" ; + italian_A = mkA "italialainen" ; + expensive_A = mkA "kallis" ; + delicious_A = mkA "herkullinen" ; + boring_A = mkA "tyls�" ; +} diff --git a/testsuite/compiler/canonical/Phrasebook.gf b/testsuite/compiler/canonical/Phrasebook.gf new file mode 100644 index 000000000..9ebc13106 --- /dev/null +++ b/testsuite/compiler/canonical/Phrasebook.gf @@ -0,0 +1,8 @@ +abstract Phrasebook = + Greetings, + Words + ** { + +flags startcat = Phrase ; + +} diff --git a/testsuite/compiler/canonical/PhrasebookBul.gf b/testsuite/compiler/canonical/PhrasebookBul.gf new file mode 100644 index 000000000..bbc092963 --- /dev/null +++ b/testsuite/compiler/canonical/PhrasebookBul.gf @@ -0,0 +1,9 @@ +--# -path=.:present + +concrete PhrasebookBul of Phrasebook = + GreetingsBul, + WordsBul ** open + SyntaxBul, + Prelude in { + +} diff --git a/testsuite/compiler/canonical/PhrasebookGer.gf b/testsuite/compiler/canonical/PhrasebookGer.gf new file mode 100644 index 000000000..69a61187c --- /dev/null +++ b/testsuite/compiler/canonical/PhrasebookGer.gf @@ -0,0 +1,10 @@ +--# -path=.:present + +concrete PhrasebookGer of Phrasebook = + GreetingsGer, + WordsGer ** open + SyntaxGer, + Prelude in { + + +} diff --git a/testsuite/compiler/canonical/Sentences.gf b/testsuite/compiler/canonical/Sentences.gf new file mode 100644 index 000000000..6798c2127 --- /dev/null +++ b/testsuite/compiler/canonical/Sentences.gf @@ -0,0 +1,222 @@ +--1 The Ontology of the Phrasebook + +--2 Syntactic Structures of the Phrasebook + +-- This module contains phrases that can be defined by a functor over the +-- resource grammar API. The phrases that are likely to have different implementations +-- are in the module Words. But the distinction is not quite sharp; thus it may happen +-- that the functor instantiations make exceptions. + +abstract Sentences = Numeral ** { + +-- The ontology of the phrasebook is defined by the following types. The commented ones +-- are defined in other modules. + + cat + Phrase ; -- complete phrase, the unit of translation e.g. "Where are you?" + Word ; -- word that could be used as phrase e.g. "Monday" + Message ; -- sequence of phrases, longest unit e.g. "Hello! Where are you?" + Greeting ; -- idiomatic greeting e.g. "hello" + Sentence ; -- declarative sentence e.g. "I am in the bar" + Question ; -- question, either yes/no or wh e.g. "where are you" + Proposition ; -- can be turned into sentence or question e.g. "this pizza is good" + Object ; -- the object of wanting, ordering, etc e.g. "three pizzas and a beer" + PrimObject ; -- single object of wanting, ordering, etc e.g. "three pizzas" + Item ; -- a single entity e.g. "this pizza" + Kind ; -- a type of an item e.g. "pizza" + MassKind ; -- a type mass (uncountable) e.g. "water" + PlurKind ; -- a type usually only in plural e.g. "noodles" + DrinkKind ; -- a drinkable, countable type e.g. "beer" + Quality ; -- qualification of an item, can be complex e.g. "very good" + Property ; -- basic property of an item, one word e.g. "good" + Place ; -- location e.g. "the bar" + PlaceKind ; -- type of location e.g. "bar" + Currency ; -- currency unit e.g. "leu" + Price ; -- number of currency units e.g. "eleven leu" + Person ; -- agent wanting or doing something e.g. "you" + Action ; -- proposition about a Person e.g. "you are here" + Nationality ; -- complex of language, property, country e.g. "Swedish, Sweden" + LAnguage ; -- language (can be without nationality) e.g. "Flemish" + Citizenship ; -- property (can be without language) e.g. "Belgian" + Country ; -- country (can be without language) e.g. "Belgium" + Day ; -- weekday type e.g. "Friday" + Date ; -- definite date e.g. "on Friday" + Name ; -- name of person e.g. "NN" + Number ; -- number expression 1 .. 999,999 e.g. "twenty" + Transport ; -- transportation device e.g. "car" + ByTransport ; -- mean of transportation e.g. "by tram" + Superlative ; -- superlative modifiers of places e.g. "the best restaurant" + + + fun + +-- To build a whole message + + MPhrase : Phrase -> Message ; + MContinue : Phrase -> Message -> Message ; + +-- Many of the categories are accessible as Phrases, i.e. as translation units. +-- To regulate whether words appear on the top level, change their status between +-- Word and Phrase, or uncomment PWord, + + -- PWord : Word -> Phrase ; + + PGreetingMale : Greeting -> Phrase ; -- depends on speaker e.g. in Thai + PGreetingFemale : Greeting -> Phrase ; + PSentence : Sentence -> Phrase ; + PQuestion : Question -> Phrase ; + + PNumber : Number -> Phrase ; + PPrice : Price -> Phrase ; + PObject : Object -> Word ; + PKind : Kind -> Word ; + PMassKind : MassKind -> Word ; + PQuality : Quality -> Word ; + PPlace : Place -> Word ; + PPlaceKind : PlaceKind -> Word ; + PCurrency : Currency -> Word ; + PLanguage : LAnguage -> Word ; + PCitizenship : Citizenship -> Word ; + PCountry : Country -> Word ; + PDay : Day -> Word ; + PByTransport : ByTransport -> Word ; + PTransport : Transport -> Word ; + + PYes, PNo, PYesToNo : Greeting ; -- yes, no, si/doch (pos. answer to neg. question) + +-- To order something. + + GObjectPlease : Object -> Greeting ; -- a pizza and beer, please! + +-- This is the way to build propositions about inanimate items. + + Is : Item -> Quality -> Proposition ; -- this pizza is good + IsMass : MassKind -> Quality -> Proposition ; -- Belgian beer is good + +-- To use propositions on higher levels. + + SProp : Proposition -> Sentence ; -- this pizza is good + SPropNot : Proposition -> Sentence ; -- this pizza isn't good + QProp : Proposition -> Question ; -- is this pizza good + + WherePlace : Place -> Question ; -- where is the bar + WherePerson : Person -> Question ; -- where are you + +-- This is the way to build propositions about persons. + + PropAction : Action -> Proposition ; -- (you (are|aren't) | are you) Swedish + +-- Here are some general syntactic constructions. + + ObjItem : Item -> PrimObject ; -- this pizza + ObjNumber : Number -> Kind -> PrimObject ; -- five pizzas + ObjIndef : Kind -> PrimObject ; -- a pizza + ObjPlural : Kind -> PrimObject ; -- pizzas + ObjPlur : PlurKind -> PrimObject ; -- noodles + ObjMass : MassKind -> PrimObject ; -- water + ObjAndObj : PrimObject -> Object -> Object ; -- this pizza and a beer + OneObj : PrimObject -> Object ; -- this pizza + + SuchKind : Quality -> Kind -> Kind ; -- Italian pizza + SuchMassKind : Quality -> MassKind -> MassKind ; -- Italian water + Very : Property -> Quality ; -- very Italian + Too : Property -> Quality ; -- too Italian + PropQuality : Property -> Quality ; -- Italian + + MassDrink : DrinkKind -> MassKind ; -- beer + DrinkNumber : Number -> DrinkKind -> PrimObject ; -- five beers + +-- Determiners. + + This, That, These, Those : Kind -> Item ; -- this pizza,...,those pizzas + The, Thes : Kind -> Item ; -- the pizza, the pizzas + ThisMass, ThatMass, TheMass : MassKind -> Item ; -- this/that/the water + ThesePlur, ThosePlur, ThesPlur : PlurKind -> Item ; -- these/those/the potatoes + + AmountCurrency : Number -> Currency -> Price ; -- five euros + + ThePlace : PlaceKind -> Place ; -- the bar + APlace : PlaceKind -> Place ; -- a bar + + IMale, IFemale, -- I, said by man/woman (affects agreement) + YouFamMale, YouFamFemale, -- familiar you, said to man/woman (affects agreement) + YouPolMale, YouPolFemale : Person ; -- polite you, said to man/woman (affects agreement) + + LangNat : Nationality -> LAnguage ; -- Swedish + CitiNat : Nationality -> Citizenship ; -- Swedish + CountryNat : Nationality -> Country ; -- Sweden + PropCit : Citizenship -> Property ; -- Swedish + + OnDay : Day -> Date ; -- on Friday + Today : Date ; -- today + + PersonName : Name -> Person ; -- person referred by name + NameNN : Name ; -- the name "NN" + +---- NameString : String -> Name ; ---- creates ambiguities with all words --% + + NNumeral : Numeral -> Number ; -- numeral in words, e.g. "twenty" + +-- Actions are typically language-dependent, not only lexically but also +-- structurally. However, these ones are mostly functorial. + + SHave : Person -> Object -> Sentence ; -- you have beer + SHaveNo : Person -> Kind -> Sentence ; -- you have no apples + SHaveNoMass : Person -> MassKind -> Sentence ; -- you have no beer + QDoHave : Person -> Object -> Question ; -- do you have beer + + AHaveCurr : Person -> Currency -> Action ; -- you have dollars + ACitizen : Person -> Citizenship -> Action ; -- you are Swedish + ABePlace : Person -> Place -> Action ; -- you are in the bar + + ByTransp : Transport -> ByTransport ; -- by bus + + AKnowSentence : Person -> Sentence -> Action ; -- you know that I am in the bar + AKnowPerson : Person -> Person -> Action ; -- you know me + AKnowQuestion : Person -> Question -> Action ; -- you know how far the bar is + +------------------------------------------------------------------------------------------ +-- New things added 30/11/2011 by AR +------------------------------------------------------------------------------------------ + + cat + VerbPhrase ; -- things one does, can do, must do, wants to do, e.g. swim + Modality ; -- can, want, must + fun + ADoVerbPhrase : Person -> VerbPhrase -> Action ; -- I swim + AModVerbPhrase : Modality -> Person -> VerbPhrase -> Action ; -- I can swim + ADoVerbPhrasePlace : Person -> VerbPhrase -> Place -> Action ; -- I swim in the hotel + AModVerbPhrasePlace : Modality -> Person -> VerbPhrase -> Place -> Action ; -- I can swim in the hotel + + QWhereDoVerbPhrase : Person -> VerbPhrase -> Question ; -- where do you swim + QWhereModVerbPhrase : Modality -> Person -> VerbPhrase -> Question ; -- where can I swim + + MCan, MKnow, MMust, MWant : Modality ; + +-- lexical items given in the resource Lexicon + + VPlay, VRun, VSit, VSleep, VSwim, VWalk : VerbPhrase ; + VDrink, VEat, VRead, VWait, VWrite, VSit, VStop : VerbPhrase ; + V2Buy, V2Drink, V2Eat : Object -> VerbPhrase ; + V2Wait : Person -> VerbPhrase ; + + PImperativeFamPos, -- eat + PImperativeFamNeg, -- don't eat + PImperativePolPos, -- essen Sie + PImperativePolNeg, -- essen Sie nicht + PImperativePlurPos, -- esst + PImperativePlurNeg : -- esst nicht + VerbPhrase -> Phrase ; + +-- other new things allowed by the resource + +--- PBecause : Sentence -> Sentence -> Phrase ; -- I want to swim because it is hot + + He, She, -- he, she + WeMale, WeFemale, -- we, said by men/women (affects agreement) + YouPlurFamMale, YouPlurFamFemale, -- plural familiar you, said to men/women (affects agreement) + YouPlurPolMale, YouPlurPolFemale, -- plural polite you, said to men/women (affects agreement) + TheyMale, TheyFemale : Person ; -- they, said of men/women (affects agreement) + +} + diff --git a/testsuite/compiler/canonical/SentencesBul.gf b/testsuite/compiler/canonical/SentencesBul.gf new file mode 100644 index 000000000..b2968bc85 --- /dev/null +++ b/testsuite/compiler/canonical/SentencesBul.gf @@ -0,0 +1,54 @@ +concrete SentencesBul of Sentences = + NumeralBul ** SentencesI - [IMale, IFemale, YouFamMale, YouFamFemale, YouPolMale, + YouPolFemale, ACitizen, Citizenship, PCitizenship, + LangNat, CitiNat, CountryNat, PropCit, + Nationality, Country, LAnguage, PLanguage, PCountry + ] with + (Syntax = SyntaxBul), + (Symbolic = SymbolicBul), + (Lexicon = LexiconBul) ** open ExtraBul, (R = ResBul) in { + +lincat + Citizenship = {s1 : R.Gender => R.NForm => Str; -- there are two nouns for every citizenship - one for males and one for females + s2 : A -- furthermore, adjective for Property + } ; + Nationality = {s1 : R.Gender => R.NForm => Str; -- there are two nouns for every citizenship - one for males and one for females + s2 : A; -- furthermore, adjective for Property + s3 : PN -- country name + } ; + LAnguage = A ; + Country = PN ; + +lin IMale = mkPerson i_Pron ; + IFemale = mkPerson i8fem_Pron ; + +lin YouFamMale = mkPerson youSg_Pron ; + YouFamFemale = mkPerson youSg8fem_Pron ; + YouPolMale, YouPolFemale = mkPerson youPol_Pron ; + +lin ACitizen p cit = + let noun : N + = case p.name.gn of { + R.GSg g => lin N {s = \\nf => cit.s1 ! g ! nf; + rel = cit.s2.s; relType = R.AdjMod; + g = case g of {R.Masc=>R.AMasc R.Human; R.Fem=>R.AFem; R.Neut=>R.ANeut} + } ; + R.GPl => lin N {s = \\nf => cit.s1 ! R.Masc ! nf; + rel = cit.s2.s; relType = R.AdjMod; + g = R.AMasc R.Human + } + } ; + in mkCl p.name noun ; + + PCitizenship cit = + mkPhrase (mkUtt (mkAP cit.s2)) ; + + LangNat n = n.s2 ; + CitiNat n = n ; + CountryNat n = n.s3 ; + PropCit cit = cit.s2 ; + + PLanguage x = mkPhrase (mkUtt (mkAP x)) ; + PCountry x = mkPhrase (mkUtt (mkNP x)) ; + +} diff --git a/testsuite/compiler/canonical/SentencesGer.gf b/testsuite/compiler/canonical/SentencesGer.gf new file mode 100644 index 000000000..cc0922d5f --- /dev/null +++ b/testsuite/compiler/canonical/SentencesGer.gf @@ -0,0 +1,50 @@ +concrete SentencesGer of Sentences = NumeralGer ** SentencesI - + [PYesToNo,SHaveNo,SHaveNoMass, + Proposition, Action, Is, IsMass, SProp, SPropNot, QProp, + AHaveCurr, ACitizen, ABePlace, AKnowSentence, AKnowPerson, AKnowQuestion, + Nationality, LAnguage, + ADoVerbPhrase, AModVerbPhrase, ADoVerbPhrasePlace, AModVerbPhrasePlace, + YouPlurPolMale, YouPlurPolFemale + ] with + (Syntax = SyntaxGer), + (Symbolic = SymbolicGer), + (Lexicon = LexiconGer) ** open Prelude, SyntaxGer in { + + lin + PYesToNo = mkPhrase (lin Utt (ss "doch")) ; + SHaveNo p k = mkS (mkCl p.name have_V2 (mkNP no_Quant plNum k)) ; + SHaveNoMass p k = mkS (mkCl p.name have_V2 (mkNP no_Quant k)) ; + + lincat + Proposition, Action = Prop ; + oper + Prop = {pos : Cl ; neg : S} ; -- x F y ; x F nicht/kein y + mkProp : Cl -> S -> Prop = \pos,neg -> {pos = pos ; neg = neg} ; + prop : Cl -> Prop = \cl -> mkProp cl (mkS negativePol cl) ; + lin + Is i q = prop (mkCl i q) ; + IsMass m q = prop (mkCl (mkNP m) q) ; + SProp p = mkS p.pos ; + SPropNot p = p.neg ; + QProp p = mkQS (mkQCl p.pos) ; + + AHaveCurr p curr = prop (mkCl p.name have_V2 (mkNP aPl_Det curr)) ; + ACitizen p n = prop (mkCl p.name n) ; + ABePlace p place = prop (mkCl p.name place.at) ; + + AKnowSentence p s = prop (mkCl p.name Lexicon.know_VS s) ; + AKnowQuestion p s = prop (mkCl p.name Lexicon.know_VQ s) ; + AKnowPerson p q = prop (mkCl p.name Lexicon.know_V2 q.name) ; + + lincat + Nationality = {lang : CN ; country : NP ; prop : A} ; + LAnguage = CN ; -- kein Deutsch + +-- the new things + lin + ADoVerbPhrase p vp = prop (mkCl p.name vp) ; + AModVerbPhrase m p vp = prop (mkCl p.name (mkVP m vp)) ; + ADoVerbPhrasePlace p vp x = prop (mkCl p.name (mkVP vp x.at)) ; + AModVerbPhrasePlace m p vp x = prop (mkCl p.name (mkVP m (mkVP vp x.at))) ; + YouPlurPolMale, YouPlurPolFemale = mkPerson youPol_Pron ; +} diff --git a/testsuite/compiler/canonical/SentencesI.gf b/testsuite/compiler/canonical/SentencesI.gf new file mode 100644 index 000000000..913aa11ad --- /dev/null +++ b/testsuite/compiler/canonical/SentencesI.gf @@ -0,0 +1,302 @@ +--1 Implementation of MOLTO Phrasebook + +--2 The functor for (mostly) common structures + +incomplete concrete SentencesI of Sentences = Numeral ** + open + Syntax, + Lexicon, + Symbolic, -- for names as strings + Prelude + in { + lincat + Phrase = Text ; + Word = Text ; + Message = Text ; + Greeting = Text ; + Sentence = S ; + Question = QS ; + Proposition = Cl ; + Item = NP ; + Kind = CN ; + MassKind = CN ; + MassKind = CN ; + PlurKind = CN ; + DrinkKind = CN ; + Quality = AP ; + Property = A ; + Object = NP ; + PrimObject = NP ; + Place = NPPlace ; -- {name : NP ; at : Syntax.Adv ; to : Syntax.Adv} ; + PlaceKind = CNPlace ; -- {name : CN ; at : Prep ; to : Prep} ; + Currency = CN ; + Price = NP ; + Action = Cl ; + Person = NPPerson ; -- {name : NP ; isPron : Bool ; poss : Quant} ; + Nationality = NPNationality ; -- {lang : NP ; country : NP ; prop : A} ; + LAnguage = NP ; + Citizenship = A ; + Country = NP ; + Day = NPDay ; -- {name : NP ; point : Syntax.Adv ; habitual : Syntax.Adv} ; + Date = Syntax.Adv ; + Name = NP ; + Number = Card ; + ByTransport = Syntax.Adv ; + Transport = {name : CN ; by : Syntax.Adv} ; + Superlative = Det ; + lin + MPhrase p = p ; + MContinue p m = mkText p m ; + + PSentence s = mkText s | lin Text (mkUtt s) ; -- optional '.' + PQuestion s = mkText s | lin Text (mkUtt s) ; -- optional '?' + + PGreetingMale, PGreetingFemale = \g -> mkText (lin Phr (ss g.s)) exclMarkPunct | g ; + + -- PWord w = w ; + + PNumber x = mkSentence (mkUtt x) ; + PPrice x = mkSentence (mkUtt x) ; + + PObject x = mkPhrase (mkUtt x) ; + PKind x = mkPhrase (mkUtt x) ; + PMassKind x = mkPhrase (mkUtt x) ; + PQuality x = mkPhrase (mkUtt x) ; + PPlace x = mkPhrase (mkUtt x.name) ; + PPlaceKind x = mkPhrase (mkUtt x.name) ; + PCurrency x = mkPhrase (mkUtt x) ; + PLanguage x = mkPhrase (mkUtt x) ; + PCountry x = mkPhrase (mkUtt x) ; + PCitizenship x = mkPhrase (mkUtt (mkAP x)) ; + PDay d = mkPhrase (mkUtt d.name) ; + PTransport t = mkPhrase (mkUtt t.name) ; + PByTransport t = mkPhrase (mkUtt t) ; + + PYes = mkPhrase yes_Utt ; + PNo = mkPhrase no_Utt ; + PYesToNo = mkPhrase yes_Utt ; + + GObjectPlease o = lin Text (mkPhr noPConj (mkUtt o) please_Voc) | lin Text (mkUtt o) ; + + Is = mkCl ; + IsMass m q = mkCl (mkNP m) q ; + + SProp = mkS ; + SPropNot = mkS negativePol ; + QProp p = mkQS (mkQCl p) ; + + WherePlace place = mkQS (mkQCl where_IAdv place.name) ; + WherePerson person = mkQS (mkQCl where_IAdv person.name) ; + + PropAction a = a ; + + AmountCurrency num curr = mkNP num curr ; + + ObjItem i = i ; + ObjNumber n k = mkNP n k ; + ObjIndef k = mkNP a_Quant k ; + ObjPlural k = mkNP aPl_Det k ; + ObjPlur k = mkNP aPl_Det k ; + ObjMass k = mkNP k ; + ObjAndObj = mkNP and_Conj ; + OneObj o = o ; + + MassDrink d = d ; + DrinkNumber n k = mkNP n k ; + + This kind = mkNP this_Quant kind ; + That kind = mkNP that_Quant kind ; + These kind = mkNP this_Quant plNum kind ; + Those kind = mkNP that_Quant plNum kind ; + The kind = mkNP the_Quant kind ; + Thes kind = mkNP the_Quant plNum kind ; + ThisMass kind = mkNP this_Quant kind ; + ThatMass kind = mkNP that_Quant kind ; + TheMass kind = mkNP the_Quant kind ; + ThesePlur kind = mkNP this_Quant plNum kind ; + ThosePlur kind = mkNP that_Quant plNum kind ; + ThesPlur kind = mkNP the_Quant plNum kind ; + + SuchKind quality kind = mkCN quality kind ; + SuchMassKind quality kind = mkCN quality kind ; + Very property = mkAP very_AdA (mkAP property) ; + Too property = mkAP too_AdA (mkAP property) ; + PropQuality property = mkAP property ; + + ThePlace kind = let dd : Det = if_then_else Det kind.isPl thePl_Det theSg_Det + in placeNP dd kind ; + APlace kind = let dd : Det = if_then_else Det kind.isPl aPl_Det aSg_Det + in placeNP dd kind ; + + IMale, IFemale = mkPerson i_Pron ; + YouFamMale, YouFamFemale = mkPerson youSg_Pron ; + YouPolMale, YouPolFemale = mkPerson youPol_Pron ; + + LangNat n = n.lang ; + CitiNat n = n.prop ; + CountryNat n = n.country ; + PropCit c = c ; + + OnDay d = d.point ; + Today = today_Adv ; + + PersonName n = + {name = n ; isPron = False ; poss = mkQuant he_Pron} ; -- poss not used +---- NameString s = symb s ; --% + NameNN = symb "NN" ; + + NNumeral n = mkCard ; + + SHave p obj = mkS (mkCl p.name have_V2 obj) ; + SHaveNo p k = mkS negativePol (mkCl p.name have_V2 (mkNP aPl_Det k)) ; + SHaveNoMass p m = mkS negativePol (mkCl p.name have_V2 (mkNP m)) ; + QDoHave p obj = mkQS (mkQCl (mkCl p.name have_V2 obj)) ; + + AHaveCurr p curr = mkCl p.name have_V2 (mkNP aPl_Det curr) ; + ACitizen p n = mkCl p.name n ; + ABePlace p place = mkCl p.name place.at ; + ByTransp t = t.by ; + + AKnowSentence p s = mkCl p.name Lexicon.know_VS s ; + AKnowQuestion p s = mkCl p.name Lexicon.know_VQ s ; + AKnowPerson p q = mkCl p.name Lexicon.know_V2 q.name ; + +oper + +-- These operations are used internally in Sentences. + + mkPhrase : Utt -> Text = \u -> lin Text u ; -- no punctuation + mkGreeting : Str -> Text = \s -> lin Text (ss s) ; -- no punctuation + mkSentence : Utt -> Text = \t -> lin Text (postfixSS "." t | t) ; -- optional . + + mkPerson : Pron -> {name : NP ; isPron : Bool ; poss : Quant} = \p -> + {name = mkNP p ; isPron = True ; poss = mkQuant p} ; + +-- These are used in Words for each language. + + NPNationality : Type = {lang : NP ; country : NP ; prop : A} ; + + mkNPNationality : NP -> NP -> A -> NPNationality = \la,co,pro -> + {lang = la ; + country = co ; + prop = pro + } ; + + NPDay : Type = {name : NP ; point : Syntax.Adv ; habitual : Syntax.Adv} ; + + mkNPDay : NP -> Syntax.Adv -> Syntax.Adv -> NPDay = \d,p,h -> + {name = d ; + point = p ; + habitual = h + } ; + + NPPlace : Type = {name : NP ; at : Syntax.Adv ; to : Syntax.Adv} ; + CNPlace : Type = {name : CN ; at : Prep ; to : Prep; isPl : Bool} ; + + mkCNPlace : CN -> Prep -> Prep -> CNPlace = \p,i,t -> { + name = p ; + at = i ; + to = t ; + isPl = False + } ; + + mkCNPlacePl : CN -> Prep -> Prep -> CNPlace = \p,i,t -> { + name = p ; + at = i ; + to = t ; + isPl = True + } ; + + placeNP : Det -> CNPlace -> NPPlace = \det,kind -> + let name : NP = mkNP det kind.name in { + name = name ; + at = Syntax.mkAdv kind.at name ; + to = Syntax.mkAdv kind.to name + } ; + + NPPerson : Type = {name : NP ; isPron : Bool ; poss : Quant} ; + + relativePerson : GNumber -> CN -> (Num -> NP -> CN -> NP) -> NPPerson -> NPPerson = + \n,x,f,p -> + let num = if_then_else Num n plNum sgNum in { + name = case p.isPron of { + True => mkNP p.poss num x ; + _ => f num p.name x + } ; + isPron = False ; + poss = mkQuant he_Pron -- not used because not pron + } ; + + GNumber : PType = Bool ; + sing = False ; plur = True ; + +-- for languages without GenNP, use "the wife of p" + mkRelative : Bool -> CN -> NPPerson -> NPPerson = \n,x,p -> + relativePerson n x + (\a,b,c -> mkNP (mkNP the_Quant a c) (Syntax.mkAdv possess_Prep b)) p ; + +-- for languages with GenNP, use "p's wife" +-- relativePerson n x (\a,b,c -> mkNP (GenNP b) a c) p ; + + phrasePlease : Utt -> Text = \u -> --- lin Text (mkPhr noPConj u please_Voc) | + lin Text u ; + +------------------------------------------------------------------------------------------ +-- New things added 30/11/2011 by AR +------------------------------------------------------------------------------------------ + + lincat + VerbPhrase = VP ; + Modality = VV ; + lin + ADoVerbPhrase p vp = mkCl p.name vp ; + AModVerbPhrase m p vp = mkCl p.name (mkVP m vp) ; + ADoVerbPhrasePlace p vp x = mkCl p.name (mkVP vp x.at) ; + AModVerbPhrasePlace m p vp x = mkCl p.name (mkVP m (mkVP vp x.at)) ; + + QWhereDoVerbPhrase p vp = mkQS (mkQCl where_IAdv (mkCl p.name vp)) ; + QWhereModVerbPhrase m p vp = mkQS (mkQCl where_IAdv (mkCl p.name (mkVP m vp))) ; + + MWant = want_VV ; + MCan = can_VV ; + MKnow = can8know_VV ; + MMust = must_VV ; + + VPlay = mkVP play_V ; + VRun = mkVP run_V ; + VSit = mkVP sit_V ; + VSleep = mkVP sleep_V ; + VSwim = mkVP swim_V ; + VWalk = mkVP walk_V ; + VSit = mkVP sit_V ; + VStop = mkVP stop_V ; + VDrink = mkVP ; + VEat = mkVP ; + VRead = mkVP ; + VWait = mkVP ; + VWrite = mkVP ; + + V2Buy o = mkVP buy_V2 o ; + V2Drink o = mkVP drink_V2 o ; + V2Eat o = mkVP eat_V2 o ; + V2Wait o = mkVP wait_V2 o.name ; + + PImperativeFamPos v = phrasePlease (mkUtt (mkImp v)) ; + PImperativeFamNeg v = phrasePlease (mkUtt negativePol (mkImp v)) ; + PImperativePolPos v = phrasePlease (mkUtt politeImpForm (mkImp v)) ; + PImperativePolNeg v = phrasePlease (mkUtt politeImpForm negativePol (mkImp v)) ; + PImperativePlurPos v = phrasePlease (mkUtt pluralImpForm (mkImp v)) ; + PImperativePlurNeg v = phrasePlease (mkUtt pluralImpForm negativePol (mkImp v)) ; + +-- other new things allowed by the resource + +--- PBecause a b = SSubjS a because_Subj b ; + + He = mkPerson he_Pron ; + She = mkPerson she_Pron ; + WeMale, WeFemale = mkPerson we_Pron ; + YouPlurFamMale, YouPlurFamFemale = mkPerson youPl_Pron ; + YouPlurPolMale, YouPlurPolFemale = mkPerson youPl_Pron ; + TheyMale, TheyFemale = mkPerson they_Pron ; + +} diff --git a/testsuite/compiler/canonical/Words.gf b/testsuite/compiler/canonical/Words.gf new file mode 100644 index 000000000..08704990a --- /dev/null +++ b/testsuite/compiler/canonical/Words.gf @@ -0,0 +1,254 @@ +--2 Words and idiomatic phrases of the Phrasebook + + +-- (c) 2010 Aarne Ranta under LGPL --% + +abstract Words = Sentences ** { + + fun + +-- kinds of items (so far mostly food stuff) + + Apple : Kind ; + Beer : DrinkKind ; + Bread : MassKind ; + Cheese : MassKind ; + Chicken : MassKind ; + Coffee : DrinkKind ; + Fish : MassKind ; + Meat : MassKind ; + Milk : MassKind ; + Pizza : Kind ; + Salt : MassKind ; + Tea : DrinkKind ; + Water : DrinkKind ; + Wine : DrinkKind ; + +-- properties of kinds (so far mostly of food) + + Bad : Property ; + Boring : Property ; + Cheap : Property ; + Cold : Property ; + Delicious : Property ; + Expensive : Property ; + Fresh : Property ; + Good : Property ; + Suspect : Property ; + Warm : Property ; + +-- kinds of places + + Airport : PlaceKind ; + AmusementPark : PlaceKind ; + Bank : PlaceKind ; + Bar : PlaceKind ; + Cafeteria : PlaceKind ; + Center : PlaceKind ; + Cinema : PlaceKind ; + Church : PlaceKind ; + Disco : PlaceKind ; + Hospital : PlaceKind ; + Hotel : PlaceKind ; + Museum : PlaceKind ; + Park : PlaceKind ; + Parking : PlaceKind ; + Pharmacy : PlaceKind ; + PostOffice : PlaceKind ; + Pub : PlaceKind ; + Restaurant : PlaceKind ; + School : PlaceKind ; + Shop : PlaceKind ; + Station : PlaceKind ; + Supermarket : PlaceKind ; + Theatre : PlaceKind ; + Toilet : PlaceKind ; + University : PlaceKind ; + Zoo : PlaceKind ; + + CitRestaurant : Citizenship -> PlaceKind ; + +-- currency units + + DanishCrown : Currency ; + Dollar : Currency ; + Euro : Currency ; -- Germany, France, Italy, Finland, Spain, The Netherlands + Lei : Currency ; -- Romania + Leva : Currency ; -- Bulgaria + NorwegianCrown : Currency ; + Pound : Currency ; -- UK + Rouble : Currency ; -- Russia + Rupee : Currency ; -- India + SwedishCrown : Currency ; + Zloty : Currency ; -- Poland + Yuan : Currency ; -- China + + +-- nationalities, countries, languages, citizenships + + Belgian : Citizenship ; + Belgium : Country ; + Bulgarian : Nationality ; + Catalan : Nationality ; + Chinese : Nationality ; + Danish : Nationality ; + Dutch : Nationality ; + English : Nationality ; + Finnish : Nationality ; + Flemish : LAnguage ; + French : Nationality ; + German : Nationality ; + Hindi : LAnguage ; + India : Country ; + Indian : Citizenship ; + Italian : Nationality ; + Norwegian : Nationality ; + Polish : Nationality ; + Romanian : Nationality ; + Russian : Nationality ; + Spanish : Nationality ; + Swedish : Nationality ; + +-- means of transportation + + Bike : Transport ; + Bus : Transport ; + Car : Transport ; + Ferry : Transport ; + Plane : Transport ; + Subway : Transport ; + Taxi : Transport ; + Train : Transport ; + Tram : Transport ; + + ByFoot : ByTransport ; + + +-- Actions (which can be expressed by different structures in different languages). +-- Notice that also negations and questions can be formed from these. + + AHasAge : Person -> Number -> Action ; -- I am seventy years + AHasChildren: Person -> Number -> Action ; -- I have six children + AHasName : Person -> Name -> Action ; -- my name is Bond + AHasRoom : Person -> Number -> Action ; -- you have a room for five persons + AHasTable : Person -> Number -> Action ; -- you have a table for five persons + AHungry : Person -> Action ; -- I am hungry + AIll : Person -> Action ; -- I am ill + AKnow : Person -> Action ; -- I (don't) know + ALike : Person -> Item -> Action ; -- I like this pizza + ALive : Person -> Country -> Action ; -- I live in Sweden + ALove : Person -> Person -> Action ; -- I love you + AMarried : Person -> Action ; -- I am married + AReady : Person -> Action ; -- I am ready + AScared : Person -> Action ; -- I am scared + ASpeak : Person -> LAnguage -> Action ; -- I speak Finnish + AThirsty : Person -> Action ; -- I am thirsty + ATired : Person -> Action ; -- I am tired + AUnderstand : Person -> Action ; -- I (don't) understand + AWant : Person -> Object -> Action ; -- I want two apples + AWantGo : Person -> Place -> Action ; -- I want to go to the hospital + +-- Miscellaneous phrases. Notice that also negations and questions can be formed from +-- propositions. + + QWhatAge : Person -> Question ; -- how old are you + QWhatName : Person -> Question ; -- what is your name + HowMuchCost : Item -> Question ; -- how much does the pizza cost + ItCost : Item -> Price -> Proposition ; -- the pizza costs five euros + + PropOpen : Place -> Proposition ; -- the museum is open + PropClosed : Place -> Proposition ; -- the museum is closed + PropOpenDate : Place -> Date -> Proposition ; -- the museum is open today + PropClosedDate : Place -> Date -> Proposition ; -- the museum is closed today + PropOpenDay : Place -> Day -> Proposition ; -- the museum is open on Mondays + PropClosedDay : Place -> Day -> Proposition ; -- the museum is closed on Mondays + + PSeeYouPlaceDate : Place -> Date -> Greeting ; -- see you in the bar on Monday + PSeeYouPlace : Place -> Greeting ; -- see you in the bar + PSeeYouDate : Date -> Greeting ; -- see you on Monday + +-- family relations + + Wife, Husband : Person -> Person ; -- my wife, your husband + Son, Daughter : Person -> Person ; -- my son, your husband + Children : Person -> Person ; -- my children + +-- week days + + Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday : Day ; + + Tomorrow : Date ; + +-- transports + + HowFar : Place -> Question ; -- how far is the zoo ? + HowFarFrom : Place -> Place -> Question ; -- how far is the center from the hotel ? + HowFarFromBy : Place -> Place -> ByTransport -> Question ; + -- how far is the airport from the hotel by taxi ? + HowFarBy : Place -> ByTransport -> Question ; -- how far is the museum by bus ? + + WhichTranspPlace : Transport -> Place -> Question ; -- which bus goes to the hotel + IsTranspPlace : Transport -> Place -> Question ; -- is there a metro to the airport ? + +-- modifiers of places + + TheBest : Superlative ; + TheClosest : Superlative ; + TheCheapest : Superlative ; + TheMostExpensive : Superlative ; + TheMostPopular : Superlative ; + TheWorst : Superlative ; + + SuperlPlace : Superlative -> PlaceKind -> Place ; -- the best bar + + +-------------------------------------------------- +-- New 30/11/2011 AR +-------------------------------------------------- +{- 28/8/2012 still only available in Bul Eng Fin Swe Tha + + fun + Thai : Nationality ; + Baht : Currency ; -- Thailand + + Rice : MassKind ; + Pork : MassKind ; + Beef : MassKind ; + Noodles : PlurKind ; + Shrimps : PlurKind ; + + Chili : MassKind ; + Garlic : MassKind ; + + Durian : Kind ; + Mango : Kind ; + Pineapple : Kind ; + Egg : Kind ; + + Coke : DrinkKind ; + IceCream : DrinkKind ; --- both mass and plural + OrangeJuice : DrinkKind ; + Lemonade : DrinkKind ; + Salad : DrinkKind ; + + Beach : PlaceKind ; + + ItsRaining : Proposition ; + ItsWindy : Proposition ; + ItsWarm : Proposition ; + ItsCold : Proposition ; + SunShine : Proposition ; + + Smoke : VerbPhrase ; + + ADoctor : Person -> Action ; + AProfessor : Person -> Action ; + ALawyer : Person -> Action ; + AEngineer : Person -> Action ; + ATeacher : Person -> Action ; + ACook : Person -> Action ; + AStudent : Person -> Action ; + ABusinessman : Person -> Action ; +-} + +} diff --git a/testsuite/compiler/canonical/WordsBul.gf b/testsuite/compiler/canonical/WordsBul.gf new file mode 100644 index 000000000..527b3604a --- /dev/null +++ b/testsuite/compiler/canonical/WordsBul.gf @@ -0,0 +1,305 @@ +--2 Implementations of Words, with English as example + +concrete WordsBul of Words = SentencesBul ** + open + SyntaxBul, + (R = ResBul), + ParadigmsBul, + (L = LexiconBul), + (P = ParadigmsBul), + ExtraBul, + MorphoFunsBul, + Prelude in { + + flags + coding=utf8; + + lin + +-- Kinds; many of them are in the resource lexicon, others can be built by $mkN$. + + Apple = mkCN L.apple_N ; + Beer = mkCN L.beer_N ; + Bread = mkCN L.bread_N ; + Cheese = mkCN (mkN066 "сирене") ; + Chicken = mkCN (mkN065 "пиле") ; + Coffee = mkCN (mkN065 "кафе") ; + Fish = mkCN L.fish_N ; + Meat = mkCN (mkN054 "месо") ; + Milk = mkCN L.milk_N ; + Pizza = mkCN (mkN041 "пица") ; + Salt = mkCN L.salt_N ; + Tea = mkCN (mkN028 "чай") ; + Water = mkCN L.water_N ; + Wine = mkCN L.wine_N ; + +-- Properties; many of them are in the resource lexicon, others can be built by $mkA$. + + Bad = L.bad_A ; + Boring = mkA079 "еднообразен" ; + Cheap = mkA076 "евтин" ; + Cold = L.cold_A ; + Delicious = mkA079 "превъзходен" ; + Expensive = mkA076 "скъп" ; + Fresh = mkA076 "свеж" ; + Good = L.good_A ; + Suspect = mkA079 "подозрителен" ; + Warm = L.warm_A ; + +-- Places require different prepositions to express location; in some languages +-- also the directional preposition varies, but in English we use $to$, as +-- defined by $mkPlace$. + + Airport = mkPlace (mkN066 "летище") na_Prep ; + AmusementPark = mkCompoundPlace (mkA079 "увеселителен") (mkN001 "парк") in_Prep ; + Bank = mkPlace (mkN041 "банка") in_Prep ; + Bar = mkPlace (mkN001 "бар") in_Prep ; + Cafeteria = mkPlace (mkN065 "кафе") in_Prep ; + Center = mkPlace (mkN009a "център") in_Prep ; + Cinema = mkPlace (mkN054 "кино") na_Prep ; + Church = mkPlace (mkN041 "църква") in_Prep ; + Disco = mkPlace (mkN041 "дискотека") in_Prep ; + Hospital = mkPlace (mkN041 "болница") in_Prep ; + Hotel = mkPlace (mkN007 "хотел") in_Prep ; + Museum = mkPlace (mkN032 "музей") in_Prep ; + Park = mkPlace (mkN001 "парк") in_Prep ; + Parking = mkPlace (mkN007 "паркинг") na_Prep ; + Pharmacy = mkPlace (mkN041 "аптека") in_Prep ; + PostOffice = mkPlace (mkN041 "поща") in_Prep ; + Pub = mkPlace (mkN001 "бар") in_Prep ; + Restaurant = mkPlace (mkN007 "ресторант") in_Prep ; + School = mkPlace (mkN007 "училище") in_Prep ; + Shop = mkPlace (mkN007 "магазин") in_Prep ; + Station = mkPlace (mkN041 "гара") na_Prep ; + Supermarket = mkPlace (mkN007 "супермаркет") in_Prep ; + Theatre = mkPlace (mkN009 "театър") na_Prep ; + Toilet = mkPlace (mkN041 "тоалетна") in_Prep ; + University = mkPlace (mkN007 "университет") in_Prep ; + Zoo = mkPlace (mkN001 "зоопарк") in_Prep ; + + CitRestaurant cit = mkCNPlace (mkCN cit.s2 (mkN007 "ресторант")) in_Prep to_Prep ; + +-- Currencies; $crown$ is ambiguous between Danish and Swedish crowns. + + DanishCrown = mkCN (mkA078 "датски") (mkN041 "крона") | mkCN (mkN041 "крона") ; + Dollar = mkCN (mkN007 "долар") ; + Euro = mkCN (mkN054 "евро") ; + Lei = mkCN (mkN047 "лея") ; + Leva = mkCN (mkN001 "лев") ; + NorwegianCrown = mkCN (mkA078 "норвежки") (mkN041 "крона") | mkCN (mkN041 "крона") ; + Pound = mkCN (mkN007 "паунд") ; + Rouble = mkCN (mkN041 "рубла") ; + SwedishCrown = mkCN (mkA078 "шведски") (mkN041 "крона") | mkCN (mkN041 "крона") ; + Zloty = mkCN (mkN041 "злота") ; + Baht = mkCN (mkN007a "бат") ; + +-- Nationalities + + Belgian = mkCitizenship (mkN013 "белгиец") (mkN041 "белгийка") (mkA078 "белгийски") ; + Belgium = mkPN "Белгия" R.Fem ; + Bulgarian = mkNat (mkN018 "българин") (mkN041 "българка") (mkA078 "български") (mkPN "България" R.Fem) ; + Catalan = mkNat (mkN008a "каталонец") (mkN041 "каталонка") (mkA078 "каталонски") (mkPN "Каталуния" R.Fem) ; + Danish = mkNat (mkN018 "датчанин") (mkN041 "датчанка") (mkA078 "датски") (mkPN "Дания" R.Fem) ; + Dutch = mkNat (mkN008a "холандец") (mkN041 "холандка") (mkA078 "холандски") (mkPN "Холандия" R.Fem) ; + English = mkNat (mkN018 "англичанин") (mkN041 "англичанка") (mkA078 "английски") (mkPN "Англия" R.Fem) ; + Finnish = mkNat (mkN008a "финландец") (mkN041 "финландка") (mkA078 "финландски") (mkPN "Финландия" R.Fem) ; + Flemish = mkA078 "фламандски" ; + French = mkNat (mkN018 "французин") (mkN041 "французойка") (mkA078 "френски") (mkPN "Франция" R.Fem) ; + German = mkNat (mkN008a "германец") (mkN041 "германка") (mkA078 "немски") (mkPN "Германия" R.Fem) ; + Italian = mkNat (mkN008a "италианец") (mkN041 "италианка") (mkA078 "италиански") (mkPN "Италия" R.Fem) ; + Norwegian = mkNat (mkN008a "норвежец") (mkN041 "норвежка") (mkA078 "норвежки") (mkPN "Норвегия" R.Fem) ; + Polish = mkNat (mkN014 "поляк") (mkN047 "полякиня") (mkA078 "полски") (mkPN "Полша" R.Fem) ; + Romanian = mkNat (mkN008a "румънец") (mkN041 "румънка") (mkA078 "румънски") (mkPN "Румъния" R.Fem) ; + Russian = mkNat (mkN014 "руснак") (mkN047 "рускиня") (mkA078 "руски") (mkPN "Русия" R.Fem) ; + Swedish = mkNat (mkN007 "швед") (mkN041 "шведка") (mkA078 "шведски") (mkPN "Швеция" R.Fem) ; + Spanish = mkNat (mkN008a "испанец") (mkN041 "испанка") (mkA078 "испански") (mkPN "Испания" R.Fem) ; + Thai = mkNat (mkN008a "тайландец") (mkN041 "тайландка") (mkA078 "тайландски") (mkPN "Тайланд" R.Masc) ; + +-- Means of transportation + + Bike = mkTransport L.bike_N ; + Bus = mkTransport (mkN007 "автобус") ; + Car = mkTransport L.car_N ; + Ferry = mkTransport (mkN007 "ферибот") ; + Plane = mkTransport (mkN007 "самолет") ; + Subway = mkTransport (mkN054 "метро") ; + Taxi = mkTransport (mkN073 "такси") ; + Train = mkTransport (mkN001 "влак") ; + Tram = mkTransport (mkN032 "трамвай") ; + + ByFoot = P.mkAdv "пеша" ; + +-- Actions: the predication patterns are very often language-dependent. + + AHasAge p num = mkCl p.name (SyntaxBul.mkAdv na_Prep (mkNP num L.year_N)) ; + AHasChildren p num = mkCl p.name have_V2 (mkNP num L.child_N) ; + AHasRoom p num = mkCl p.name have_V2 (mkNP (mkNP a_Det (mkN047 "стая")) (SyntaxBul.mkAdv (mkPrep "за" R.Acc) (mkNP num (mkN014 "човек")))) ; + AHasTable p num = mkCl p.name have_V2 (mkNP (mkNP a_Det (mkN041 "маса")) (SyntaxBul.mkAdv (mkPrep "за" R.Acc) (mkNP num (mkN014 "човек")))) ; + AHasName p name = mkCl p.name (dirV2 (medialV (actionV (mkV186 "казвам") (mkV156 "кажа")) R.Acc)) name ; + AHungry p = mkCl p.name (mkA079 "гладен") ; + AIll p = mkCl p.name (mkA079 "болен") ; + AKnow p = mkCl p.name (actionV (mkV186 "знам") (mkV162 "зная")) ; + ALike p item = mkCl p.name (dirV2 (actionV (mkV186 "харесвам") (mkV186 "харесам"))) item ; + ALive p co = mkCl p.name (mkVP (mkVP (stateV (mkV160 "живея"))) (SyntaxBul.mkAdv in_Prep (mkNP co))) ; + ALove p q = mkCl p.name (dirV2 (actionV (mkV186 "обичам") (mkV152 "обикна"))) q.name ; + AMarried p = mkCl p.name (mkA076 (case p.name.gn of { + R.GSg R.Fem => "омъжен" ; + _ => "женен" + })) ; + AReady p = mkCl p.name (mkA076 "готов") ; + AScared p = mkCl p.name (mkA076 "уплашен") ; + ASpeak p lang = mkCl p.name (dirV2 (stateV (mkV173 "говоря"))) (mkNP (substantiveN lang (R.AMasc R.NonHuman))) ; + AThirsty p = mkCl p.name (mkA079 "жаден") ; + ATired p = mkCl p.name (mkA076 "уморен") ; + AUnderstand p = mkCl p.name (actionV (mkV186 "разбирам") (mkV170 "разбера")) ; + AWant p obj = mkCl p.name (dirV2 (stateV (mkV186 "искам"))) obj ; + AWantGo p place = mkCl p.name want_VV (mkVP (mkVP (actionV (mkV186 "отивам") (mkV146 "отида"))) place.to) ; + +-- miscellaneous + + QWhatName p = mkQS (mkQCl how_IAdv (mkCl p.name (medialV (actionV (mkV186 "казвам") (mkV156 "кажа")) R.Acc))) ; + QWhatAge p = mkQS (mkQCl (MorphoFunsBul.mkIAdv "на колко") (mkCl p.name (mkNP a_Quant plNum L.year_N))) ; + HowMuchCost item = mkQS (mkQCl how8much_IAdv (mkCl item (stateV (mkV186 "струвам")))) ; + ItCost item price = mkCl item (dirV2 (stateV (mkV186 "струвам"))) price ; + + PropOpen p = mkCl p.name open_AP ; + PropClosed p = mkCl p.name closed_AP ; + PropOpenDate p d = mkCl p.name (mkVP (mkVP open_AP) d) ; + PropClosedDate p d = mkCl p.name (mkVP (mkVP closed_AP) d) ; + PropOpenDay p d = mkCl p.name (mkVP (mkVP open_AP) d.habitual) ; + PropClosedDay p d = mkCl p.name (mkVP (mkVP closed_AP) d.habitual) ; + +-- Building phrases from strings is complicated: the solution is to use +-- mkText : Text -> Text -> Text ; + + PSeeYouDate d = mkText (lin Text (ss ("ще се видим"))) (mkPhrase (mkUtt d)) ; + PSeeYouPlace p = mkText (lin Text (ss ("ще се видим"))) (mkPhrase (mkUtt p.at)) ; + PSeeYouPlaceDate p d = + mkText (lin Text (ss ("ще се видим"))) + (mkText (mkPhrase (mkUtt p.at)) (mkPhrase (mkUtt d))) ; + +-- Relations are expressed as "my wife" or "my son's wife", as defined by $xOf$ +-- below. Languages without productive genitives must use an equivalent of +-- "the wife of my son" for non-pronouns. + + Wife = xOf sing (mkN041 "съпруга") ; + Husband = xOf sing (mkN015 "съпруг") ; + Son = xOf sing (mkN018 "син") ; + Daughter = xOf sing (mkN047 "дъщеря") ; + Children = xOf plur L.child_N ; + +-- week days + + Monday = mkDay (mkN014 "понеделник") ; + Tuesday = mkDay (mkN014 "вторник") ; + Wednesday = mkDay (mkN043 "сряда") ; + Thursday = mkDay (mkN014 "четвъртък") ; + Friday = mkDay (mkN014 "петък") ; + Saturday = mkDay (mkN041 "събота") ; + Sunday = mkDay (mkN047 "неделя") ; + + Tomorrow = P.mkAdv "утре" ; + +-- modifiers of places + + TheBest = mkSuperl L.good_A ; + TheClosest = mkSuperl L.near_A ; + TheCheapest = mkSuperl (mkA076 "евтин") ; + TheMostExpensive = mkSuperl (mkA076 "скъп") ; + TheMostPopular = mkSuperl (mkA079 "известен") ; + TheWorst = mkSuperl L.bad_A ; + + SuperlPlace sup p = placeNP sup p ; + + +-- transports + + HowFar place = mkQS (mkQCl far_IAdv place.name) ; + HowFarFrom x y = mkQS (mkQCl far_IAdv (mkNP y.name (SyntaxBul.mkAdv from_Prep x.name))) ; + HowFarFromBy x y t = + mkQS (mkQCl far_IAdv (mkNP (mkNP y.name (SyntaxBul.mkAdv from_Prep x.name)) t)) ; + HowFarBy y t = mkQS (mkQCl far_IAdv (mkNP y.name t)) ; + + WhichTranspPlace trans place = + mkQS (mkQCl (mkIP which_IDet trans.name) (mkVP (mkVP L.go_V) place.to)) ; + + IsTranspPlace trans place = + mkQS (mkQCl (mkCl (mkCN trans.name place.to))) ; + + Rice = mkCN (mkN040a "ориз") ; + Pork = mkCN (mkN054 "свинско") ; + Beef = mkCN (mkN054 "телешко") ; + Egg = mkCN (mkN066 "яйце") ; + Noodles = mkCN (mkN075 "спагети") ; + Shrimps = mkCN (mkN041 "скарида") ; + Chili = mkCN (mkN065 "чили") ; + Garlic = mkCN (mkN007 "чесън") ; + Durian = mkCN (mkN007 "дуриан") ; + Mango = mkCN (mkN065 "манго") ; + Pineapple = mkCN (mkN007 "ананас") ; + Coke = mkCN (mkN041 "кола") ; + IceCream = mkCN (mkN007 "сладолед") ; + Salad = mkCN (mkN041 "салата") ; + OrangeJuice = mkCN (mkA076 "портокалов") (mkN001 "сок") ; + Lemonade = mkCN (mkN041 "лимонада") ; + + Beach = mkPlace (mkN001 "плаж") na_Prep ; + + ItsRaining = mkCl (mkVP (stateV (mkV174 "валя"))) ; + ItsCold = mkCl (mkVP (mkA076 "студен")) ; + ItsWarm = mkCl (mkVP (mkA080 "топъл")) ; + ItsWindy = mkCl (mkVP (mkA076 "ветровит")) ; + SunShine = mkCl (progressiveVP (mkVP (actionV (mkV186 "пеквам") (mkV148 "пека")))) ; + + Smoke = mkVP (stateV (mkV176 "пуша")) ; + + ADoctor = mkProfession (mkN007a "доктор") ; + AProfessor = mkProfession (mkN007a "професор") ; + ALawyer = mkProfession (mkN007a "адвокат") ; + AEngineer = mkProfession (mkN007a "инженер") ; + ATeacher = mkProfession (mkN031a "учител") ; + ACook = mkProfession (mkN007b "готвач") ; + AStudent = mkProfession (mkN007a "студент") ; + ABusinessman = mkProfession (mkN007a "бизнесмен") ; + +-- auxiliaries + + oper + mkProfession : N -> NPPerson -> Cl = \n,p -> mkCl p.name n ; + + mkCitizenship : N -> N -> A -> Citizenship + = \male, female, adj -> lin Citizenship {s1 = table {R.Fem => female.s; _ => male.s}; s2 = adj} ; + + mkNat : N -> N -> A -> PN -> Nationality + = \male, female, adj, country -> lin Nationality {s1 = table {R.Fem => female.s; _ => male.s}; s2 = adj; s3 = country} ; + + mkDay : N -> {name : NP ; point : Adv ; habitual : Adv} = \d -> + let day : NP = mkNP d ; + in mkNPDay day + (SyntaxBul.mkAdv in_Prep day) + (SyntaxBul.mkAdv in_Prep (mkNP the_Quant plNum (mkCN d))) ; + + mkCompoundPlace : A -> N -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \a, n, p -> + mkCNPlace (mkCN a n) p to_Prep ; + + mkPlace : N -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \n,p -> + mkCNPlace (mkCN n) p to_Prep ; + + open_AP = mkAP (mkA076 "отворен") ; + closed_AP = mkAP (mkA076 "затворен") ; + + xOf : GNumber -> N -> NPPerson -> NPPerson = \n,x,p -> + relativePerson n (mkCN x) (\a,b,c -> mkNP (mkNP the_Quant a c) (SyntaxBul.mkAdv (mkPrep "" R.Dat) b)) p ; + + mkTransport : N -> {name : CN ; by : Adv} = \n -> { + name = mkCN n ; + by = SyntaxBul.mkAdv with_Prep (mkNP n) + } ; + + mkSuperl : A -> Det = \a -> SyntaxBul.mkDet the_Art (SyntaxBul.mkOrd a) ; + + far_IAdv = ExtraBul.IAdvAdv (ss "далече") ; + + na_Prep = mkPrep "на" R.Acc ; + +} diff --git a/testsuite/compiler/canonical/WordsGer.gf b/testsuite/compiler/canonical/WordsGer.gf new file mode 100644 index 000000000..4984eb080 --- /dev/null +++ b/testsuite/compiler/canonical/WordsGer.gf @@ -0,0 +1,262 @@ +-- (c) 2009 Aarne Ranta under LGPL +--# -coding=latin1 + +concrete WordsGer of Words = SentencesGer ** + open SyntaxGer, ParadigmsGer, IrregGer, (L = LexiconGer), ExtraGer, Prelude in { + + lin + +-- kinds of food + + Apple = mkCN L.apple_N ; + Beer = mkCN L.beer_N ; + Bread = mkCN L.bread_N ; + Cheese = mkCN (mkN "Kse" "Kse" "Kse" "Kse" "Kse" "Kse" masculine) ; + Chicken = mkCN (mkN "Huhn" "Huhn" "Huhn" "Huhn" "Hhner" "Hhner" neuter) ; + Coffee = mkCN (mkN "Kaffee" "Kaffee" "Kaffee" "Kaffee" "Kaffees" "Kaffee" masculine) ; + Fish = mkCN L.fish_N ; + Meat = mkCN (mkN "Fleisch" "Fleisch" "Fleisch" "Fleisch" "Fleisch" "Fleisch" neuter) ; + Milk = mkCN L.milk_N ; + Pizza = mkCN (mkN "Pizza" "Pizzen" feminine) ; + Salt = mkCN L.salt_N ; + Tea = mkCN (mkN "Tee" "Tee" "Tee" "Tee" "Tees" "Tees" masculine) ; + Water = mkCN L.water_N ; + Wine = mkCN L.wine_N ; + +-- properties + + Bad = L.bad_A ; + Cheap = mkA "billig" ; + Boring = mkA "langweilig" ; + Cold = L.cold_A ; + Delicious = mkA "lecker" ; + Expensive = mkA "teuer" ; + Fresh = mkA "frisch" ; + Good = L.good_A ; + Warm = L.warm_A ; + Suspect = mkA "verdchtig" ; + +-- places + + Airport = mkPlace (mkN "Flughafen" "Flughfen" masculine) on_Prep zu_Prep ; + Church = mkPlace (mkN "Kirche") in_Prep inAcc_Prep ; + Hospital = mkPlace (mkN "Krankenhaus" "Krankenhuser" neuter) in_Prep inAcc_Prep ; + Restaurant = mkPlace (mkN "Restaurant" "Restaurants" neuter) in_Prep inAcc_Prep ; + Station = mkPlace (mkN "Bahnhof" "Bahnhfe" masculine) on_Prep zu_Prep ; + University = mkPlace (mkN "Universitt" "Universitten" feminine) in_Prep zu_Prep ; + + AmusementPark = mkPlace (mkN "Vergngungspark" "Vergngungspark" "Vergngungspark" "Vergngungspark" "Vergngungsparks" "Vergngungsparks" masculine) in_Prep inAcc_Prep ; + Bank = mkPlace (mkN "Bank" "Bank" "Bank" "Bank" "Banken" "Banken" feminine) in_Prep zu_Prep ; + Bar = mkPlace (mkN "Bar" "Bar" "Bar" "Bar" "Bars" "Bars" feminine) in_Prep inAcc_Prep ; + Cafeteria = mkPlace (mkN "Cafeteria" "Cafeteria" "Cafeteria" "Cafeteria" "Cafeterien" "Cafeterien" feminine) in_Prep inAcc_Prep ; + Center = mkPlace (mkN "Zentrum" "Zentrum" "Zentrum" "Zentrum" "Zentren" "Zentren" neuter) in_Prep zu_Prep ; + Cinema = mkPlace (mkN "Kino" "Kino" "Kino" "Kino" "Kinos" "Kinos" neuter) in_Prep inAcc_Prep ; + Disco = mkPlace (mkN "Disco" "Disco" "Disco" "Disco" "Discos" "Discos" feminine) in_Prep inAcc_Prep ; + Hotel = mkPlace (mkN "Hotel" "Hotel" "Hotel" "Hotel" "Hotels" "Hotels" neuter) in_Prep inAcc_Prep ; + Museum = mkPlace (mkN "Museum" "Museum" "Museum" "Museum" "Museen" "Museen" neuter) in_Prep inAcc_Prep ; + Park = mkPlace (mkN "Park" "Park" "Park" "Park" "Parks" "Parks" masculine) in_Prep inAcc_Prep ; + Parking = mkPlace (mkN "Parkplatz" "Parkplatz" "Parkplatz" "Parkplatz" "Parkplatzen" "Parkplatzen" masculine) on_Prep zu_Prep ; + Pharmacy = mkPlace (mkN "Apotheke" "Apotheke" "Apotheke" "Apotheke" "Apotheken" "Apotheken" feminine) in_Prep zu_Prep ; + PostOffice = mkPlace (mkN "Post" "Post" "Post" "Post" "Posten" "Posten" feminine) in_Prep inAcc_Prep ; + Pub = mkPlace (mkN "Kneipe" "Kneipe" "Kneipe" "Kneipe" "Kneipen" "Kneipen" feminine) in_Prep inAcc_Prep; + School = mkPlace (mkN "Schule" "Schule" "Schule" "Schule" "Schulen" "Schule" feminine) in_Prep inAcc_Prep ; + Shop = mkPlace (mkN "Geschft" "Geschft" "Geschft" "Geschft" "Geschfte" "Geschfte" neuter) in_Prep inAcc_Prep ; + Supermarket = mkPlace (mkN "Supermarkt" "Supermarkt" "Supermarkt" "Supermarkt" "Supermrkten" "Supermrkte" masculine) in_Prep inAcc_Prep ; + Theatre = mkPlace (mkN "Theater" "Theater" "Theater" "Theaters" "Theatern" "Thaters" neuter) in_Prep inAcc_Prep ; + Toilet = mkPlace (mkN "Toilette" "Toilette" "Toilette" "Toilette" "Toiletten" "Toiletten" feminine) in_Prep (mkPrep "auf" accusative) ; + Zoo = mkPlace (mkN "Zoo" "Zoo" "Zoo" "Zoo" "Zoos" "Zoos" masculine) in_Prep inAcc_Prep ; + + +CitRestaurant cit = mkCNPlace (mkCN cit (mkN "Restaurant" "Restaurants" neuter)) in_Prep inAcc_Prep ; + + +-- currencies + + DanishCrown = mkCN (mkA "Dnisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; + Dollar = mkCN (mkN "Dollar" "Dollar" "Dollar" "Dollar" "Dollar" "Dollar" masculine) ; + Euro = mkCN (mkN "Euro" "Euro" "Euro" "Euro" "Euro" "Euro" neuter) ; + Lei = mkCN (mkN "Leu" "Leu" "Leu" "Leu" "Lei" "Lei" masculine) ; + SwedishCrown = mkCN (mkA "Schwedisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; + Leva = mkCN (mkN "Lewa" "Lewa" "Lewa" "Lewa" "Lewa" "Lewa" feminine); + NorwegianCrown = mkCN (mkA "Norwegisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; + Pound = mkCN (mkN "Pfund" "Pfund" "Pfund" "Pfund" "Pfund" "Pfund" neuter) ; + Rouble = mkCN (mkN "Rubel" "Rubel" "Rubel" "Rubel" "Rubels" "Rubels" masculine); + Zloty = mkCN (mkN "Zloty" "Zloty" "Zloty" "Zloty" "Zloty" "Zloty" masculine); + + + +-- nationalities + + Belgian = mkA "belgisch" ; + Belgium = mkNP (mkPN "Belgien") ; + Bulgarian = mkNat "Bulgarien" "Bulgarisch" "bulgarisch" ; + Catalan = mkNat "Katalonien" "Katalanisch" "katalanisch" ; + Danish = mkNat "Dnemark" "Dnisch" "dnisch" ; + Dutch = mkNat "den Niederlanden" "Niederlndisch" "niederlndisch" ; + English = mkNat "England" "Englisch" "englisch" ; + Finnish = mkNat "Finnland" "Finnisch" "finnisch" ; + Flemish = mkCN (mkN "Flmisch" "Flmisch" neuter) ; + French = mkNat "Frankreich" "Franzsisch" "franzsisch" ; + German = mkNat "Deutschland" "Deutsch" "deutsche" ; + Italian = mkNat "Italien" "Italienisch" "italienisch" ; + Norwegian = mkNat "Norwegen" "Norwegisch" "norwegisch" ; + Polish = mkNat "Polen" "Polnisch" "polnisch" ; + Romanian = mkNat "Rumnien" "Rumnisch" "rumnisch" ; + Russian = mkNat "Russland" "Russisch" "russisch" ; + Spanish = mkNat "Spanien" "Spanisch" "spanisch" ; + Swedish = mkNat "Schweden" "Schwedisch" "schwedisch" ; + + + +-- actions + + AHasAge p num = prop (mkCl p.name (mkNP num L.year_N)) ; + AHasName p name = prop (mkCl p.name (mkV2 heien_V) name) ; + AHungry p = prop (mkCl p.name (mkA "hungrig")) ; + AHasChildren p num = prop (mkCl p.name have_V2 (mkNP num L.child_N)) ; + AHasRoom p num = prop (mkCl p.name have_V2 + (mkNP (mkNP a_Det (mkN "Zimmer" "Zimmer" neuter)) + (SyntaxGer.mkAdv for_Prep (mkNP num (mkN "Persone"))))) ; + AHasTable p num = prop (mkCl p.name have_V2 + (mkNP (mkNP a_Det (mkN "Tisch")) + (SyntaxGer.mkAdv for_Prep (mkNP num (mkN "Persone"))))) ; + AIll p = prop (mkCl p.name (mkA "krank")) ; + AKnow p = prop (mkCl p.name wissen_V) ; + ALike p item = prop (mkCl p.name (mkV2 mgen_V) item) ; + ALive p co = prop (mkCl p.name (mkVP (mkVP (mkV "wohnen")) (SyntaxGer.mkAdv in_Prep co))) ; + ALove p q = prop (mkCl p.name (mkV2 (mkV "lieben")) q.name) ; + AMarried p = prop (mkCl p.name (mkA "verheiratet")) ; + AReady p = prop (mkCl p.name (mkA "bereit")) ; + AScared p = prop (mkCl p.name have_V2 (mkNP (mkN "Angst" "Angsten" feminine))) ; + ASpeak p lang = mkProp (mkCl p.name (mkV2 sprechen_V) (mkNP lang)) + (mkS (mkCl p.name (mkV2 sprechen_V) (mkNP no_Quant lang))) ; + AThirsty p = prop (mkCl p.name (mkA "durstig")) ; + ATired p = prop (mkCl p.name (mkA "mde")) ; + AUnderstand p = prop (mkCl p.name (fixprefixV "ver" stehen_V)) ; + AWant p obj = prop (mkCl p.name want_VV (mkVP have_V2 obj)) ; + AWantGo p place = prop (mkCl p.name want_VV (mkVP (mkVP L.go_V) place.to)) ; + +-- miscellaneous + + QWhatName p = mkQS (mkQCl how_IAdv (mkCl p.name heien_V)) ; + QWhatAge p = mkQS (mkQCl (ICompAP (mkAP L.old_A)) p.name) ; + + PropOpen p = prop (mkCl p.name open_Adv) ; + PropClosed p = prop (mkCl p.name closed_Adv) ; + PropOpenDate p d = prop (mkCl p.name (mkVP (mkVP d) open_Adv)) ; + PropClosedDate p d = prop (mkCl p.name (mkVP (mkVP d) closed_Adv)) ; + PropOpenDay p d = prop (mkCl p.name (mkVP (mkVP d.habitual) open_Adv)) ; + PropClosedDay p d = prop (mkCl p.name (mkVP (mkVP d.habitual) closed_Adv)) ; + + HowMuchCost item = mkQS (mkQCl how8much_IAdv (mkCl item (mkV "kosten"))) ; + ItCost item price = prop (mkCl item (mkV2 (mkV "kosten")) price) ; + +-- Building phrases from strings is complicated: the solution is to use +-- mkText : Text -> Text -> Text ; + + PSeeYouDate d = mkText (lin Text (ss ("wir sehen uns"))) (mkPhrase (mkUtt d)) ; + PSeeYouPlace p = mkText (lin Text (ss ("wir sehen uns"))) (mkPhrase (mkUtt p.at)) ; + PSeeYouPlaceDate p d = + mkText (lin Text (ss ("wir sehen uns"))) + (mkText (mkPhrase (mkUtt d)) (mkPhrase (mkUtt p.at))) ; + + +-- Relations are expressed as "my wife" or "my son's wife", as defined by $xOf$ +-- below. Languages without productive genitives must use an equivalent of +-- "the wife of my son" for non-pronouns. + + Wife = xOf sing (mkN "Frau" "Frauen" feminine) ; + Husband = xOf sing L.man_N ; + Son = xOf sing (mkN "Sohn" "Shne" masculine) ; + Daughter = xOf sing (mkN "Tochter" "Tchter" feminine) ; + Children = xOf plur L.child_N ; + +-- week days + + Monday = mkDay "Montag" ; + Tuesday = mkDay "Dienstag" ; + Wednesday = mkDay "Mittwoch" ; + Thursday = mkDay "Donnerstag" ; + Friday = mkDay "Freitag" ; + Saturday = mkDay "Samstag" ; + Sunday = mkDay "Sonntag" ; + + Tomorrow = ParadigmsGer.mkAdv "morgen" ; + + TheBest = mkSuperl L.good_A ; + TheClosest = mkSuperl L.near_A ; + TheCheapest = mkSuperl (mkA "billig") ; + TheMostExpensive = mkSuperl (mkA "teuer") ; + TheMostPopular = mkSuperl (mkA "beliebt") ; + TheWorst = mkSuperl (mkA "schlimm") ; + + SuperlPlace sup p = placeNP sup p ; + + +-- means of transportation + + Bike = mkTransport L.bike_N ; + Bus = mkTransport (mkN "Bus" "Bus" "Bus" "Bus" "Buss" "Buss" masculine) ; + Car = mkTransport L.car_N ; + Ferry = mkTransport (mkN "Fhre" "Fhre" "Fhre" "Fhre" "Fhren" "Fhren" feminine) ; + Plane = mkTransport (mkN "Flugzeug" "Flugzeug" "Flugzeug" "Flugzeug" "Flugzeuge" "Flugzeuge" neuter) ; + Subway = mkTransport (mkN "U-Bahn" "U-Bahn" "U-Bahn" "U-Bahn" "U-Bahnen" "U-Bahnen" feminine) ; + Taxi = mkTransport (mkN "Taxi" "Taxi" "Taxi" "Taxi" "Taxis" "Taxis" neuter) ; + Train = mkTransport (mkN "Zug" "Zug" "Zug" "Zug" "Zge" "Zge" masculine) ; + Tram = mkTransport (mkN "Straenbahn" "Straenbahn" "Straenbahn" "Straenbahn" "Straenbahnen" "Straenbahnen" feminine) ; + + ByFoot = ParadigmsGer.mkAdv "zu Fu" ; + + + HowFar place = mkQS (mkQCl far_IAdv place.name) ; + HowFarFrom x y = mkQS (mkQCl far_IAdv (mkNP (mkNP y.name (SyntaxGer.mkAdv von_Prep x.name)) (ParadigmsGer.mkAdv "entfernt"))) ; + HowFarFromBy x y t = + mkQS (mkQCl far_IAdv (mkCl (mkVP (SyntaxGer.mkAdv zu_Prep (mkNP (mkNP y.name (SyntaxGer.mkAdv von_Prep x.name)) t))))) ; + HowFarBy y t = mkQS (mkQCl far_IAdv (mkCl (mkVP (SyntaxGer.mkAdv zu_Prep (mkNP y.name t))))) ; + + WhichTranspPlace trans place = + mkQS (mkQCl (mkIP which_IDet trans.name) (mkVP (mkVP L.go_V) place.to)) ; + + IsTranspPlace trans place = + mkQS (mkQCl (mkCl (mkCN trans.name place.to))) ; + + + + + oper + + mkNat : Str -> Str -> Str -> {lang : CN ; prop : A ; country : NP} = \co, la, adj -> + {lang = mkCN (mkN la la neuter) ; + prop = mkA adj ; country = mkNP (mkPN co)} ; + + mkDay : Str -> {name : NP ; point : Adv ; habitual : Adv} = \d -> + let day = mkNP (mkPN d masculine) in + {name = day ; + point = SyntaxGer.mkAdv (mkPrep "am" dative) day ; ---- am + habitual = ParadigmsGer.mkAdv (d + "s") ---- + } ; + + mkPlace : N -> Prep -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \p,at,to -> { + name = mkCN p ; + at = at ; + to = to ; + isPl = False + } ; + + open_Adv = ParadigmsGer.mkAdv "geffnet" ; ---- Adv to get right word order easily + closed_Adv = ParadigmsGer.mkAdv "geschlossen" ; + + xOf : GNumber -> N -> NPPerson -> NPPerson = \n,x,p -> mkRelative n (mkCN x) p ; + + + mkSuperl : A -> Det = \a -> SyntaxGer.mkDet the_Art (SyntaxGer.mkOrd a) ; + + + mkTransport : N -> {name : CN ; by : Adv} = \n -> { + name = mkCN n ; + by = SyntaxGer.mkAdv by8means_Prep (mkNP the_Det n) + } ; + + far_IAdv = ss "wie weit" ** {lock_IAdv = <>} ; + +} diff --git a/testsuite/compiler/canonical/run.sh b/testsuite/compiler/canonical/run.sh new file mode 100755 index 000000000..b9cc7e25b --- /dev/null +++ b/testsuite/compiler/canonical/run.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +# https://github.com/GrammaticalFramework/gf-core/issues/100 +stack run -- --batch --output-format=canonical_gf PhrasebookBul.gf +stack run -- --batch canonical/PhrasebookBul.gf + +# https://github.com/GrammaticalFramework/gf-core/issues/101 +stack run -- --batch --output-format=canonical_gf PhrasebookGer.gf +for s in c2 objCtrl; do + grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null + if [ $? -ne 1 ]; then + echo "$s found" + exit 1 + fi +done + +# https://github.com/GrammaticalFramework/gf-core/issues/102 +stack run -- --batch --output-format=canonical_gf FoodsFin.gf +diff canonical/FoodsFin.gf ./FoodsFin.gf.gold +if [ $? -ne 0 ]; then + echo "Compiled grammar doesn't match gold version" + exit 1 +fi From 4436cb101e0756ad2a452fe81f0db2f18c14d60e Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 30 Jun 2021 13:47:15 +0200 Subject: [PATCH 53/75] Move testsuite/compiler/canonical on level up, update test script --- testsuite/{compiler => }/canonical/.gitignore | 0 .../gold/FoodsFin.gf} | 0 .../canonical => canonical/grammars}/Foods.gf | 0 .../grammars}/FoodsFin.gf | 0 .../grammars}/FoodsI.gf | 0 .../grammars}/Greetings.gf | 0 .../grammars}/GreetingsBul.gf | 0 .../grammars}/GreetingsGer.gf | 0 .../grammars}/LexFoods.gf | 0 .../grammars}/LexFoodsFin.gf | 0 .../grammars}/Phrasebook.gf | 0 .../grammars}/PhrasebookBul.gf | 0 .../grammars}/PhrasebookGer.gf | 0 .../grammars}/Sentences.gf | 0 .../grammars}/SentencesBul.gf | 0 .../grammars}/SentencesGer.gf | 0 .../grammars}/SentencesI.gf | 0 .../canonical => canonical/grammars}/Words.gf | 0 .../grammars}/WordsBul.gf | 0 .../grammars}/WordsGer.gf | 0 testsuite/canonical/run.sh | 42 +++++++++++++++++++ testsuite/compiler/canonical/run.sh | 23 ---------- 22 files changed, 42 insertions(+), 23 deletions(-) rename testsuite/{compiler => }/canonical/.gitignore (100%) rename testsuite/{compiler/canonical/FoodsFin.gf.gold => canonical/gold/FoodsFin.gf} (100%) rename testsuite/{compiler/canonical => canonical/grammars}/Foods.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/FoodsFin.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/FoodsI.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/Greetings.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/GreetingsBul.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/GreetingsGer.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/LexFoods.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/LexFoodsFin.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/Phrasebook.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/PhrasebookBul.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/PhrasebookGer.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/Sentences.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/SentencesBul.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/SentencesGer.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/SentencesI.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/Words.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/WordsBul.gf (100%) rename testsuite/{compiler/canonical => canonical/grammars}/WordsGer.gf (100%) create mode 100755 testsuite/canonical/run.sh delete mode 100755 testsuite/compiler/canonical/run.sh diff --git a/testsuite/compiler/canonical/.gitignore b/testsuite/canonical/.gitignore similarity index 100% rename from testsuite/compiler/canonical/.gitignore rename to testsuite/canonical/.gitignore diff --git a/testsuite/compiler/canonical/FoodsFin.gf.gold b/testsuite/canonical/gold/FoodsFin.gf similarity index 100% rename from testsuite/compiler/canonical/FoodsFin.gf.gold rename to testsuite/canonical/gold/FoodsFin.gf diff --git a/testsuite/compiler/canonical/Foods.gf b/testsuite/canonical/grammars/Foods.gf similarity index 100% rename from testsuite/compiler/canonical/Foods.gf rename to testsuite/canonical/grammars/Foods.gf diff --git a/testsuite/compiler/canonical/FoodsFin.gf b/testsuite/canonical/grammars/FoodsFin.gf similarity index 100% rename from testsuite/compiler/canonical/FoodsFin.gf rename to testsuite/canonical/grammars/FoodsFin.gf diff --git a/testsuite/compiler/canonical/FoodsI.gf b/testsuite/canonical/grammars/FoodsI.gf similarity index 100% rename from testsuite/compiler/canonical/FoodsI.gf rename to testsuite/canonical/grammars/FoodsI.gf diff --git a/testsuite/compiler/canonical/Greetings.gf b/testsuite/canonical/grammars/Greetings.gf similarity index 100% rename from testsuite/compiler/canonical/Greetings.gf rename to testsuite/canonical/grammars/Greetings.gf diff --git a/testsuite/compiler/canonical/GreetingsBul.gf b/testsuite/canonical/grammars/GreetingsBul.gf similarity index 100% rename from testsuite/compiler/canonical/GreetingsBul.gf rename to testsuite/canonical/grammars/GreetingsBul.gf diff --git a/testsuite/compiler/canonical/GreetingsGer.gf b/testsuite/canonical/grammars/GreetingsGer.gf similarity index 100% rename from testsuite/compiler/canonical/GreetingsGer.gf rename to testsuite/canonical/grammars/GreetingsGer.gf diff --git a/testsuite/compiler/canonical/LexFoods.gf b/testsuite/canonical/grammars/LexFoods.gf similarity index 100% rename from testsuite/compiler/canonical/LexFoods.gf rename to testsuite/canonical/grammars/LexFoods.gf diff --git a/testsuite/compiler/canonical/LexFoodsFin.gf b/testsuite/canonical/grammars/LexFoodsFin.gf similarity index 100% rename from testsuite/compiler/canonical/LexFoodsFin.gf rename to testsuite/canonical/grammars/LexFoodsFin.gf diff --git a/testsuite/compiler/canonical/Phrasebook.gf b/testsuite/canonical/grammars/Phrasebook.gf similarity index 100% rename from testsuite/compiler/canonical/Phrasebook.gf rename to testsuite/canonical/grammars/Phrasebook.gf diff --git a/testsuite/compiler/canonical/PhrasebookBul.gf b/testsuite/canonical/grammars/PhrasebookBul.gf similarity index 100% rename from testsuite/compiler/canonical/PhrasebookBul.gf rename to testsuite/canonical/grammars/PhrasebookBul.gf diff --git a/testsuite/compiler/canonical/PhrasebookGer.gf b/testsuite/canonical/grammars/PhrasebookGer.gf similarity index 100% rename from testsuite/compiler/canonical/PhrasebookGer.gf rename to testsuite/canonical/grammars/PhrasebookGer.gf diff --git a/testsuite/compiler/canonical/Sentences.gf b/testsuite/canonical/grammars/Sentences.gf similarity index 100% rename from testsuite/compiler/canonical/Sentences.gf rename to testsuite/canonical/grammars/Sentences.gf diff --git a/testsuite/compiler/canonical/SentencesBul.gf b/testsuite/canonical/grammars/SentencesBul.gf similarity index 100% rename from testsuite/compiler/canonical/SentencesBul.gf rename to testsuite/canonical/grammars/SentencesBul.gf diff --git a/testsuite/compiler/canonical/SentencesGer.gf b/testsuite/canonical/grammars/SentencesGer.gf similarity index 100% rename from testsuite/compiler/canonical/SentencesGer.gf rename to testsuite/canonical/grammars/SentencesGer.gf diff --git a/testsuite/compiler/canonical/SentencesI.gf b/testsuite/canonical/grammars/SentencesI.gf similarity index 100% rename from testsuite/compiler/canonical/SentencesI.gf rename to testsuite/canonical/grammars/SentencesI.gf diff --git a/testsuite/compiler/canonical/Words.gf b/testsuite/canonical/grammars/Words.gf similarity index 100% rename from testsuite/compiler/canonical/Words.gf rename to testsuite/canonical/grammars/Words.gf diff --git a/testsuite/compiler/canonical/WordsBul.gf b/testsuite/canonical/grammars/WordsBul.gf similarity index 100% rename from testsuite/compiler/canonical/WordsBul.gf rename to testsuite/canonical/grammars/WordsBul.gf diff --git a/testsuite/compiler/canonical/WordsGer.gf b/testsuite/canonical/grammars/WordsGer.gf similarity index 100% rename from testsuite/compiler/canonical/WordsGer.gf rename to testsuite/canonical/grammars/WordsGer.gf diff --git a/testsuite/canonical/run.sh b/testsuite/canonical/run.sh new file mode 100755 index 000000000..7e5a90f12 --- /dev/null +++ b/testsuite/canonical/run.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env sh + +FAILURES=0 + +# https://github.com/GrammaticalFramework/gf-core/issues/100 +stack run -- --batch --output-format=canonical_gf grammars/PhrasebookBul.gf +stack run -- --batch canonical/PhrasebookBul.gf +if [ $? -ne 0 ]; then + echo "Canonical grammar doesn't compile: FAIL" + FAILURES=$((FAILURES+1)) +else + echo "Canonical grammar compiles: OK" +fi + +# https://github.com/GrammaticalFramework/gf-core/issues/101 +stack run -- --batch --output-format=canonical_gf grammars/PhrasebookGer.gf +for s in c2 objCtrl; do + grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null + if [ $? -ne 1 ]; then + echo "Canonical grammar contains `$s`: FAIL" + FAILURES=$((FAILURES+1)) + else + echo "Canonical grammar does not contain `$s`: OK" + fi +done + +# https://github.com/GrammaticalFramework/gf-core/issues/102 +stack run -- --batch --output-format=canonical_gf grammars/FoodsFin.gf +diff canonical/FoodsFin.gf gold/FoodsFin.gf +if [ $? -ne 0 ]; then + echo "Canonical grammar doesn't match gold version: FAIL" + FAILURES=$((FAILURES+1)) +else + echo "Canonical grammar matches gold version: OK" +fi + +if [ $FAILURES -ne 0 ]; then + echo "Failures: $FAILURES" + exit 1 +else + echo "All tests passed" +fi diff --git a/testsuite/compiler/canonical/run.sh b/testsuite/compiler/canonical/run.sh deleted file mode 100755 index b9cc7e25b..000000000 --- a/testsuite/compiler/canonical/run.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env sh - -# https://github.com/GrammaticalFramework/gf-core/issues/100 -stack run -- --batch --output-format=canonical_gf PhrasebookBul.gf -stack run -- --batch canonical/PhrasebookBul.gf - -# https://github.com/GrammaticalFramework/gf-core/issues/101 -stack run -- --batch --output-format=canonical_gf PhrasebookGer.gf -for s in c2 objCtrl; do - grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null - if [ $? -ne 1 ]; then - echo "$s found" - exit 1 - fi -done - -# https://github.com/GrammaticalFramework/gf-core/issues/102 -stack run -- --batch --output-format=canonical_gf FoodsFin.gf -diff canonical/FoodsFin.gf ./FoodsFin.gf.gold -if [ $? -ne 0 ]; then - echo "Compiled grammar doesn't match gold version" - exit 1 -fi From 587004f985b9a0172b531abd76253a224b8cf77d Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Wed, 30 Jun 2021 14:14:54 +0200 Subject: [PATCH 54/75] Sort record fields in lin definitions Fixes #102 --- src/compiler/GF/Compile/GrammarToCanonical.hs | 4 +- src/compiler/GF/Grammar/Macros.hs | 38 +++++++++---------- testsuite/canonical/gold/FoodsFin.gf | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 2b701382c..8810c5911 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -11,7 +11,7 @@ import GF.Data.ErrM import GF.Text.Pretty import GF.Grammar.Grammar import GF.Grammar.Lookup(lookupOrigInfo,allOrigInfos,allParamValues) -import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp,term2patt) +import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp,term2patt,sortRec) import GF.Grammar.Lockfield(isLockLabel) import GF.Grammar.Predef(cPredef,cInts) import GF.Compile.Compute.Predef(predef) @@ -162,7 +162,7 @@ convert' gr vs = ppT S t p -> selection (ppT t) (ppT p) C t1 t2 -> concatValue (ppT t1) (ppT t2) App f a -> ap (ppT f) (ppT a) - R r -> RecordValue (fields r) + R r -> RecordValue (fields (sortRec r)) P t l -> projection (ppT t) (lblId l) Vr x -> VarValue (gId x) Cn x -> VarValue (gId x) -- hmm diff --git a/src/compiler/GF/Grammar/Macros.hs b/src/compiler/GF/Grammar/Macros.hs index b088fe49c..280aee141 100644 --- a/src/compiler/GF/Grammar/Macros.hs +++ b/src/compiler/GF/Grammar/Macros.hs @@ -5,7 +5,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/11/11 16:38:00 $ +-- > CVS $Date: 2005/11/11 16:38:00 $ -- > CVS $Author: bringert $ -- > CVS $Revision: 1.24 $ -- @@ -51,14 +51,14 @@ typeForm t = _ -> error (render ("no normal form of type" <+> ppTerm Unqualified 0 t)) typeFormCnc :: Type -> (Context, Type) -typeFormCnc t = +typeFormCnc t = case t of Prod b x a t -> let (x', v) = typeFormCnc t in ((b,x,a):x',v) _ -> ([],t) valCat :: Type -> Cat -valCat typ = +valCat typ = let (_,cat,_) = typeForm typ in cat @@ -99,7 +99,7 @@ isHigherOrderType t = fromErr True $ do -- pessimistic choice contextOfType :: Monad m => Type -> m Context contextOfType typ = case typ of Prod b x a t -> liftM ((b,x,a):) $ contextOfType t - _ -> return [] + _ -> return [] termForm :: Monad m => Term -> m ([(BindType,Ident)], Term, [Term]) termForm t = case t of @@ -108,8 +108,8 @@ termForm t = case t of return ((b,x):x', fun, args) App c a -> do (_,fun, args) <- termForm c - return ([],fun,args ++ [a]) - _ -> + return ([],fun,args ++ [a]) + _ -> return ([],t,[]) termFormCnc :: Term -> ([(BindType,Ident)], Term) @@ -254,7 +254,7 @@ mkTable :: [Term] -> Term -> Term mkTable tt t = foldr Table t tt mkCTable :: [(BindType,Ident)] -> Term -> Term -mkCTable ids v = foldr ccase v ids where +mkCTable ids v = foldr ccase v ids where ccase (_,x) t = T TRaw [(PV x,t)] mkHypo :: Term -> Hypo @@ -287,7 +287,7 @@ plusRecType t1 t2 = case (t1, t2) of filter (`elem` (map fst r1)) (map fst r2) of [] -> return (RecType (r1 ++ r2)) ls -> raise $ render ("clashing labels" <+> hsep ls) - _ -> raise $ render ("cannot add record types" <+> ppTerm Unqualified 0 t1 <+> "and" <+> ppTerm Unqualified 0 t2) + _ -> raise $ render ("cannot add record types" <+> ppTerm Unqualified 0 t1 <+> "and" <+> ppTerm Unqualified 0 t2) --plusRecord :: Term -> Term -> Err Term plusRecord t1 t2 = @@ -304,7 +304,7 @@ defLinType = RecType [(theLinLabel, typeStr)] -- | refreshing variables mkFreshVar :: [Ident] -> Ident -mkFreshVar olds = varX (maxVarIndex olds + 1) +mkFreshVar olds = varX (maxVarIndex olds + 1) -- | trying to preserve a given symbol mkFreshVarX :: [Ident] -> Ident -> Ident @@ -313,7 +313,7 @@ mkFreshVarX olds x = if (elem x olds) then (varX (maxVarIndex olds + 1)) else x maxVarIndex :: [Ident] -> Int maxVarIndex = maximum . ((-1):) . map varIndex -mkFreshVars :: Int -> [Ident] -> [Ident] +mkFreshVars :: Int -> [Ident] -> [Ident] mkFreshVars n olds = [varX (maxVarIndex olds + i) | i <- [1..n]] -- | quick hack for refining with var in editor @@ -413,11 +413,11 @@ patt2term pt = case pt of PC c pp -> mkApp (Con c) (map patt2term pp) PP c pp -> mkApp (QC c) (map patt2term pp) - PR r -> R [assign l (patt2term p) | (l,p) <- r] + PR r -> R [assign l (patt2term p) | (l,p) <- r] PT _ p -> patt2term p PInt i -> EInt i PFloat i -> EFloat i - PString s -> K s + PString s -> K s PAs x p -> appCons cAs [Vr x, patt2term p] --- an encoding PChar -> appCons cChar [] --- an encoding @@ -436,7 +436,7 @@ composSafeOp op = runIdentity . composOp (return . op) -- | to define compositional term functions composOp :: Monad m => (Term -> m Term) -> Term -> m Term -composOp co trm = +composOp co trm = case trm of App c a -> liftM2 App (co c) (co a) Abs b x t -> liftM (Abs b x) (co t) @@ -552,13 +552,13 @@ strsFromTerm t = case t of v0 <- mapM (strsFromTerm . fst) vs c0 <- mapM (strsFromTerm . snd) vs --let vs' = zip v0 c0 - return [strTok (str2strings def) vars | + return [strTok (str2strings def) vars | def <- d0, - vars <- [[(str2strings v, map sstr c) | (v,c) <- zip vv c0] | + vars <- [[(str2strings v, map sstr c) | (v,c) <- zip vv c0] | vv <- sequence v0] ] FV ts -> mapM strsFromTerm ts >>= return . concat - Strs ts -> mapM strsFromTerm ts >>= return . concat + Strs ts -> mapM strsFromTerm ts >>= return . concat _ -> raise (render ("cannot get Str from term" <+> ppTerm Unqualified 0 t)) getTableType :: TInfo -> Err Type @@ -590,11 +590,11 @@ noExist = FV [] defaultLinType :: Type defaultLinType = mkRecType linLabel [typeStr] --- normalize records and record types; put s first +-- | normalize records and record types; put s first sortRec :: [(Label,a)] -> [(Label,a)] sortRec = sortBy ordLabel where - ordLabel (r1,_) (r2,_) = + ordLabel (r1,_) (r2,_) = case (showIdent (label2ident r1), showIdent (label2ident r2)) of ("s",_) -> LT (_,"s") -> GT @@ -605,7 +605,7 @@ sortRec = sortBy ordLabel where -- | dependency check, detecting circularities and returning topo-sorted list allDependencies :: (ModuleName -> Bool) -> Map.Map Ident Info -> [(Ident,[Ident])] -allDependencies ism b = +allDependencies ism b = [(f, nub (concatMap opty (pts i))) | (f,i) <- Map.toList b] where opersIn t = case t of diff --git a/testsuite/canonical/gold/FoodsFin.gf b/testsuite/canonical/gold/FoodsFin.gf index 55c2fa6c9..de63d2b36 100644 --- a/testsuite/canonical/gold/FoodsFin.gf +++ b/testsuite/canonical/gold/FoodsFin.gf @@ -99,4 +99,4 @@ lin Expensive = ResFin_NPossIllat ParamX_Pl => "kalliisii"; ResFin_NCompound => "kallis"}}; hasPrefix = Prelude_False; p = ""}; -} +} \ No newline at end of file From 32be75ca7dbba046005b9ba06bdaa5e8b5f38ab4 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 09:22:57 +0200 Subject: [PATCH 55/75] Reduce Phrasebook grammars in testsuite/canonical to bare minimum --- testsuite/canonical/gold/PhrasebookGer.gf | 251 ++++++++++++++ testsuite/canonical/grammars/Greetings.gf | 28 -- testsuite/canonical/grammars/GreetingsBul.gf | 31 -- testsuite/canonical/grammars/GreetingsGer.gf | 31 -- testsuite/canonical/grammars/Phrasebook.gf | 11 +- testsuite/canonical/grammars/PhrasebookBul.gf | 28 +- testsuite/canonical/grammars/PhrasebookGer.gf | 12 +- testsuite/canonical/grammars/Sentences.gf | 222 ------------- testsuite/canonical/grammars/SentencesBul.gf | 54 ---- testsuite/canonical/grammars/SentencesGer.gf | 50 --- testsuite/canonical/grammars/SentencesI.gf | 302 ----------------- testsuite/canonical/grammars/Words.gf | 254 --------------- testsuite/canonical/grammars/WordsBul.gf | 305 ------------------ testsuite/canonical/grammars/WordsGer.gf | 262 --------------- testsuite/canonical/run.sh | 32 +- 15 files changed, 313 insertions(+), 1560 deletions(-) create mode 100644 testsuite/canonical/gold/PhrasebookGer.gf delete mode 100644 testsuite/canonical/grammars/Greetings.gf delete mode 100644 testsuite/canonical/grammars/GreetingsBul.gf delete mode 100644 testsuite/canonical/grammars/GreetingsGer.gf delete mode 100644 testsuite/canonical/grammars/Sentences.gf delete mode 100644 testsuite/canonical/grammars/SentencesBul.gf delete mode 100644 testsuite/canonical/grammars/SentencesGer.gf delete mode 100644 testsuite/canonical/grammars/SentencesI.gf delete mode 100644 testsuite/canonical/grammars/Words.gf delete mode 100644 testsuite/canonical/grammars/WordsBul.gf delete mode 100644 testsuite/canonical/grammars/WordsGer.gf diff --git a/testsuite/canonical/gold/PhrasebookGer.gf b/testsuite/canonical/gold/PhrasebookGer.gf new file mode 100644 index 000000000..22d750b78 --- /dev/null +++ b/testsuite/canonical/gold/PhrasebookGer.gf @@ -0,0 +1,251 @@ +concrete PhrasebookGer of Phrasebook = { +param Prelude_Bool = Prelude_False | Prelude_True; +param ResGer_Agr = ResGer_Ag ResGer_Gender ParamX_Number ParamX_Person; +param ParamX_Number = ParamX_Sg | ParamX_Pl; +param ParamX_Person = ParamX_P1 | ParamX_P2 | ParamX_P3; +param ResGer_Gender = ResGer_Masc | ResGer_Fem | ResGer_Neutr; +param ResGer_Control = ResGer_SubjC | ResGer_ObjC | ResGer_NoC; +param ResGer_PCase = ResGer_NPC ResGer_Case | ResGer_NPP ResGer_CPrep; +param ResGer_CPrep = + ResGer_CAnDat | ResGer_CInAcc | ResGer_CInDat | ResGer_CZuDat | + ResGer_CVonDat; +param ResGer_Case = ResGer_Nom | ResGer_Acc | ResGer_Dat | ResGer_Gen; +param ResGer_VAux = ResGer_VHaben | ResGer_VSein; +param ResGer_VForm = + ResGer_VInf Prelude_Bool | ResGer_VFin Prelude_Bool ResGer_VFormFin | + ResGer_VImper ParamX_Number | ResGer_VPresPart ResGer_AForm | + ResGer_VPastPart ResGer_AForm; +param ResGer_AForm = ResGer_APred | ResGer_AMod ResGer_GenNum ResGer_Case; +param ResGer_GenNum = ResGer_GSg ResGer_Gender | ResGer_GPl; +param ResGer_VFormFin = + ResGer_VPresInd ParamX_Number ParamX_Person | + ResGer_VPresSubj ParamX_Number ParamX_Person; +param ResGer_VType = ResGer_VAct | ResGer_VRefl ResGer_Case; +lincat PlaceKind = {s : Str}; + VerbPhrase = + {s : + {s : ResGer_VForm => Str; aux : ResGer_VAux; particle : Str; + prefix : Str; vtype : ResGer_VType}; + a1 : Str; a2 : Str; adj : Str; ext : Str; + inf : {s : Str; ctrl : ResGer_Control; isAux : Prelude_Bool}; + infExt : Str; isAux : Prelude_Bool; + nn : + ResGer_Agr => + {p1 : Str; p2 : Str; p3 : Str; p4 : Str; p5 : Str; p6 : Str}; + subjc : + {s : Str; c : ResGer_PCase; isPrep : Prelude_Bool; s2 : Str}}; +lin VRead = + {s = + {s = + table {ResGer_VInf Prelude_False => "lesen"; + ResGer_VInf Prelude_True => "zu" ++ "lesen"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Sg ParamX_P1) => + "lese"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Sg ParamX_P2) => + "liest"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Sg ParamX_P3) => + "liest"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Pl ParamX_P1) => + "lesen"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Pl ParamX_P2) => + "lest"; + ResGer_VFin Prelude_False + (ResGer_VPresInd ParamX_Pl ParamX_P3) => + "lesen"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Sg ParamX_P1) => + "lese"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Sg ParamX_P2) => + "lesest"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Sg ParamX_P3) => + "lese"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Pl ParamX_P1) => + "lesen"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Pl ParamX_P2) => + "leset"; + ResGer_VFin Prelude_False + (ResGer_VPresSubj ParamX_Pl ParamX_P3) => + "lesen"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Sg ParamX_P1) => + "lese"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Sg ParamX_P2) => + "liest"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Sg ParamX_P3) => + "liest"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Pl ParamX_P1) => + "lesen"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Pl ParamX_P2) => + "lest"; + ResGer_VFin Prelude_True + (ResGer_VPresInd ParamX_Pl ParamX_P3) => + "lesen"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Sg ParamX_P1) => + "lese"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Sg ParamX_P2) => + "lesest"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Sg ParamX_P3) => + "lese"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Pl ParamX_P1) => + "lesen"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Pl ParamX_P2) => + "leset"; + ResGer_VFin Prelude_True + (ResGer_VPresSubj ParamX_Pl ParamX_P3) => + "lesen"; + ResGer_VImper ParamX_Sg => "les"; + ResGer_VImper ParamX_Pl => "lest"; + ResGer_VPresPart ResGer_APred => "lesend"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Nom) => + "lesender"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Acc) => + "lesenden"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Dat) => + "lesendem"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Gen) => + "lesenden"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Nom) => + "lesende"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Acc) => + "lesende"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Dat) => + "lesender"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Gen) => + "lesender"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Nom) => + "lesendes"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Acc) => + "lesendes"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Dat) => + "lesendem"; + ResGer_VPresPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Gen) => + "lesenden"; + ResGer_VPresPart (ResGer_AMod ResGer_GPl ResGer_Nom) => + "lesende"; + ResGer_VPresPart (ResGer_AMod ResGer_GPl ResGer_Acc) => + "lesende"; + ResGer_VPresPart (ResGer_AMod ResGer_GPl ResGer_Dat) => + "lesenden"; + ResGer_VPresPart (ResGer_AMod ResGer_GPl ResGer_Gen) => + "lesender"; + ResGer_VPastPart ResGer_APred => "gelesen"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Nom) => + "gelesener"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Acc) => + "gelesenen"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Dat) => + "gelesenem"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Masc) + ResGer_Gen) => + "gelesenen"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Nom) => + "gelesene"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Acc) => + "gelesene"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Dat) => + "gelesener"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Fem) + ResGer_Gen) => + "gelesener"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Nom) => + "gelesenes"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Acc) => + "gelesenes"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Dat) => + "gelesenem"; + ResGer_VPastPart (ResGer_AMod (ResGer_GSg ResGer_Neutr) + ResGer_Gen) => + "gelesenen"; + ResGer_VPastPart (ResGer_AMod ResGer_GPl ResGer_Nom) => + "gelesene"; + ResGer_VPastPart (ResGer_AMod ResGer_GPl ResGer_Acc) => + "gelesene"; + ResGer_VPastPart (ResGer_AMod ResGer_GPl ResGer_Dat) => + "gelesenen"; + ResGer_VPastPart (ResGer_AMod ResGer_GPl ResGer_Gen) => + "gelesener"}; + aux = ResGer_VHaben; particle = ""; prefix = ""; + vtype = ResGer_VAct}; + a1 = ""; a2 = ""; adj = ""; + ext = ""; inf = {s = ""; ctrl = ResGer_NoC; isAux = Prelude_True}; + infExt = ""; isAux = Prelude_False; + nn = + table {ResGer_Ag ResGer_Masc ParamX_Sg ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Masc ParamX_Sg ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Masc ParamX_Sg ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Masc ParamX_Pl ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Masc ParamX_Pl ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Masc ParamX_Pl ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Sg ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Sg ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Sg ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Pl ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Pl ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Fem ParamX_Pl ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Sg ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Sg ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Sg ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Pl ParamX_P1 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Pl ParamX_P2 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; + ResGer_Ag ResGer_Neutr ParamX_Pl ParamX_P3 => + {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}}; + subjc = + {s = ""; c = ResGer_NPC ResGer_Nom; isPrep = Prelude_False; + s2 = ""}}; +} \ No newline at end of file diff --git a/testsuite/canonical/grammars/Greetings.gf b/testsuite/canonical/grammars/Greetings.gf deleted file mode 100644 index 580b1560b..000000000 --- a/testsuite/canonical/grammars/Greetings.gf +++ /dev/null @@ -1,28 +0,0 @@ -abstract Greetings = Sentences [Greeting] ** { - -fun - GBye : Greeting ; - GCheers : Greeting ; - GDamn : Greeting ; - GExcuse, GExcusePol : Greeting ; - GGoodDay : Greeting ; - GGoodEvening : Greeting ; - GGoodMorning : Greeting ; - GGoodNight : Greeting ; - GGoodbye : Greeting ; - GHello : Greeting ; - GHelp : Greeting ; - GHowAreYou : Greeting ; - GLookOut : Greeting ; - GNiceToMeetYou : Greeting ; - GPleaseGive, GPleaseGivePol : Greeting ; - GSeeYouSoon : Greeting ; - GSorry, GSorryPol : Greeting ; - GThanks : Greeting ; - GTheCheck : Greeting ; - GCongratulations : Greeting ; - GHappyBirthday : Greeting ; - GGoodLuck : Greeting ; - GWhatTime : Greeting ; - -} diff --git a/testsuite/canonical/grammars/GreetingsBul.gf b/testsuite/canonical/grammars/GreetingsBul.gf deleted file mode 100644 index f271d7717..000000000 --- a/testsuite/canonical/grammars/GreetingsBul.gf +++ /dev/null @@ -1,31 +0,0 @@ -concrete GreetingsBul of Greetings = SentencesBul [Greeting,mkGreeting] ** open Prelude in { - -flags - coding=utf8; - -lin - GBye = mkGreeting "чао" ; - GCheers = mkGreeting "наздраве" ; - GDamn = mkGreeting "по дяволите" ; - GExcuse, GExcusePol = mkGreeting "извинете" ; - GGoodDay = mkGreeting "добър ден" ; - GGoodEvening = mkGreeting "добра вечер" ; - GGoodMorning = mkGreeting "добро утро" ; - GGoodNight = mkGreeting "лека нощ" ; - GGoodbye = mkGreeting "довиждане" ; - GHello = mkGreeting "здравей" ; - GHelp = mkGreeting "помощ" ; - GHowAreYou = mkGreeting "как си" ; - GLookOut = mkGreeting "погледни" ; - GNiceToMeetYou = mkGreeting "радвам се да се видим" ; - GPleaseGive, GPleaseGivePol = mkGreeting "моля" ; - GSeeYouSoon = mkGreeting "до скоро" ; - GSorry, GSorryPol = mkGreeting "извинете" ; - GThanks = mkGreeting "благодаря ти" ; - GTheCheck = mkGreeting "сметката" ; - GCongratulations = mkGreeting "поздравления"; - GHappyBirthday = mkGreeting "честит рожден ден" ; - GGoodLuck = mkGreeting "успех" ; - GWhatTime = mkGreeting "колко е часът" ; - -} diff --git a/testsuite/canonical/grammars/GreetingsGer.gf b/testsuite/canonical/grammars/GreetingsGer.gf deleted file mode 100644 index f027d70ac..000000000 --- a/testsuite/canonical/grammars/GreetingsGer.gf +++ /dev/null @@ -1,31 +0,0 @@ ---# -path=.:abstract:prelude:german:api:common ---# -coding=latin1 -concrete GreetingsGer of Greetings = SentencesGer [Greeting,mkGreeting] ** open Prelude in { - -lin - GBye = mkGreeting "tsch" ; - GCheers = mkGreeting "zum Wohl" ; - GDamn = mkGreeting "verdammt" ; - GExcuse, GExcusePol = mkGreeting "Entschuldigung" ; - GGoodDay = mkGreeting "guten Tag" ; - GGoodEvening = mkGreeting "guten Abend" ; - GGoodMorning = mkGreeting "guten Morgen" ; - GGoodNight = mkGreeting "gute Nacht" ; - GGoodbye = mkGreeting "auf Wiedersehen" ; - GHello = mkGreeting "Hallo" ; - GHelp = mkGreeting "Hilfe" ; - GHowAreYou = mkGreeting "wie geht's" ; - GLookOut = mkGreeting "Achtung" ; - GNiceToMeetYou = mkGreeting "nett, Sie zu treffen" ; - GPleaseGive, GPleaseGivePol = mkGreeting "bitte" ; - GSeeYouSoon = mkGreeting "bis bald" ; - GSorry, GSorryPol = mkGreeting "Entschuldigung" ; - GThanks = mkGreeting "Danke" ; - GTheCheck = mkGreeting "die Rechnung" ; - GCongratulations = mkGreeting "herzlichen Glckwunsch"; - GHappyBirthday = mkGreeting "alles Gute zum Geburtstag" ; - GGoodLuck = mkGreeting "viel Glck" ; - GWhatTime = mkGreeting "wieviel Uhr ist es" | mkGreeting "wie spt ist es" ; - -} - diff --git a/testsuite/canonical/grammars/Phrasebook.gf b/testsuite/canonical/grammars/Phrasebook.gf index 9ebc13106..eff538f62 100644 --- a/testsuite/canonical/grammars/Phrasebook.gf +++ b/testsuite/canonical/grammars/Phrasebook.gf @@ -1,8 +1,9 @@ -abstract Phrasebook = - Greetings, - Words - ** { +abstract Phrasebook = { -flags startcat = Phrase ; +cat PlaceKind ; +fun Airport : PlaceKind ; + +cat VerbPhrase ; +fun VRead : VerbPhrase ; } diff --git a/testsuite/canonical/grammars/PhrasebookBul.gf b/testsuite/canonical/grammars/PhrasebookBul.gf index bbc092963..347d69297 100644 --- a/testsuite/canonical/grammars/PhrasebookBul.gf +++ b/testsuite/canonical/grammars/PhrasebookBul.gf @@ -1,9 +1,31 @@ --# -path=.:present -concrete PhrasebookBul of Phrasebook = - GreetingsBul, - WordsBul ** open +concrete PhrasebookBul of Phrasebook = + open SyntaxBul, + (R = ResBul), + ParadigmsBul, Prelude in { + lincat + PlaceKind = CNPlace ; + + oper + CNPlace : Type = {name : CN ; at : Prep ; to : Prep; isPl : Bool} ; + + mkPlace : N -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \n,p -> + mkCNPlace (mkCN n) p to_Prep ; + + mkCNPlace : CN -> Prep -> Prep -> CNPlace = \p,i,t -> { + name = p ; + at = i ; + to = t ; + isPl = False + } ; + + na_Prep = mkPrep "на" R.Acc ; + + lin + Airport = mkPlace (mkN066 "летище") na_Prep ; + } diff --git a/testsuite/canonical/grammars/PhrasebookGer.gf b/testsuite/canonical/grammars/PhrasebookGer.gf index 69a61187c..c6402297c 100644 --- a/testsuite/canonical/grammars/PhrasebookGer.gf +++ b/testsuite/canonical/grammars/PhrasebookGer.gf @@ -1,10 +1,14 @@ --# -path=.:present -concrete PhrasebookGer of Phrasebook = - GreetingsGer, - WordsGer ** open +concrete PhrasebookGer of Phrasebook = + open SyntaxGer, - Prelude in { + LexiconGer in { + lincat + VerbPhrase = VP ; + + lin + VRead = mkVP ; } diff --git a/testsuite/canonical/grammars/Sentences.gf b/testsuite/canonical/grammars/Sentences.gf deleted file mode 100644 index 6798c2127..000000000 --- a/testsuite/canonical/grammars/Sentences.gf +++ /dev/null @@ -1,222 +0,0 @@ ---1 The Ontology of the Phrasebook - ---2 Syntactic Structures of the Phrasebook - --- This module contains phrases that can be defined by a functor over the --- resource grammar API. The phrases that are likely to have different implementations --- are in the module Words. But the distinction is not quite sharp; thus it may happen --- that the functor instantiations make exceptions. - -abstract Sentences = Numeral ** { - --- The ontology of the phrasebook is defined by the following types. The commented ones --- are defined in other modules. - - cat - Phrase ; -- complete phrase, the unit of translation e.g. "Where are you?" - Word ; -- word that could be used as phrase e.g. "Monday" - Message ; -- sequence of phrases, longest unit e.g. "Hello! Where are you?" - Greeting ; -- idiomatic greeting e.g. "hello" - Sentence ; -- declarative sentence e.g. "I am in the bar" - Question ; -- question, either yes/no or wh e.g. "where are you" - Proposition ; -- can be turned into sentence or question e.g. "this pizza is good" - Object ; -- the object of wanting, ordering, etc e.g. "three pizzas and a beer" - PrimObject ; -- single object of wanting, ordering, etc e.g. "three pizzas" - Item ; -- a single entity e.g. "this pizza" - Kind ; -- a type of an item e.g. "pizza" - MassKind ; -- a type mass (uncountable) e.g. "water" - PlurKind ; -- a type usually only in plural e.g. "noodles" - DrinkKind ; -- a drinkable, countable type e.g. "beer" - Quality ; -- qualification of an item, can be complex e.g. "very good" - Property ; -- basic property of an item, one word e.g. "good" - Place ; -- location e.g. "the bar" - PlaceKind ; -- type of location e.g. "bar" - Currency ; -- currency unit e.g. "leu" - Price ; -- number of currency units e.g. "eleven leu" - Person ; -- agent wanting or doing something e.g. "you" - Action ; -- proposition about a Person e.g. "you are here" - Nationality ; -- complex of language, property, country e.g. "Swedish, Sweden" - LAnguage ; -- language (can be without nationality) e.g. "Flemish" - Citizenship ; -- property (can be without language) e.g. "Belgian" - Country ; -- country (can be without language) e.g. "Belgium" - Day ; -- weekday type e.g. "Friday" - Date ; -- definite date e.g. "on Friday" - Name ; -- name of person e.g. "NN" - Number ; -- number expression 1 .. 999,999 e.g. "twenty" - Transport ; -- transportation device e.g. "car" - ByTransport ; -- mean of transportation e.g. "by tram" - Superlative ; -- superlative modifiers of places e.g. "the best restaurant" - - - fun - --- To build a whole message - - MPhrase : Phrase -> Message ; - MContinue : Phrase -> Message -> Message ; - --- Many of the categories are accessible as Phrases, i.e. as translation units. --- To regulate whether words appear on the top level, change their status between --- Word and Phrase, or uncomment PWord, - - -- PWord : Word -> Phrase ; - - PGreetingMale : Greeting -> Phrase ; -- depends on speaker e.g. in Thai - PGreetingFemale : Greeting -> Phrase ; - PSentence : Sentence -> Phrase ; - PQuestion : Question -> Phrase ; - - PNumber : Number -> Phrase ; - PPrice : Price -> Phrase ; - PObject : Object -> Word ; - PKind : Kind -> Word ; - PMassKind : MassKind -> Word ; - PQuality : Quality -> Word ; - PPlace : Place -> Word ; - PPlaceKind : PlaceKind -> Word ; - PCurrency : Currency -> Word ; - PLanguage : LAnguage -> Word ; - PCitizenship : Citizenship -> Word ; - PCountry : Country -> Word ; - PDay : Day -> Word ; - PByTransport : ByTransport -> Word ; - PTransport : Transport -> Word ; - - PYes, PNo, PYesToNo : Greeting ; -- yes, no, si/doch (pos. answer to neg. question) - --- To order something. - - GObjectPlease : Object -> Greeting ; -- a pizza and beer, please! - --- This is the way to build propositions about inanimate items. - - Is : Item -> Quality -> Proposition ; -- this pizza is good - IsMass : MassKind -> Quality -> Proposition ; -- Belgian beer is good - --- To use propositions on higher levels. - - SProp : Proposition -> Sentence ; -- this pizza is good - SPropNot : Proposition -> Sentence ; -- this pizza isn't good - QProp : Proposition -> Question ; -- is this pizza good - - WherePlace : Place -> Question ; -- where is the bar - WherePerson : Person -> Question ; -- where are you - --- This is the way to build propositions about persons. - - PropAction : Action -> Proposition ; -- (you (are|aren't) | are you) Swedish - --- Here are some general syntactic constructions. - - ObjItem : Item -> PrimObject ; -- this pizza - ObjNumber : Number -> Kind -> PrimObject ; -- five pizzas - ObjIndef : Kind -> PrimObject ; -- a pizza - ObjPlural : Kind -> PrimObject ; -- pizzas - ObjPlur : PlurKind -> PrimObject ; -- noodles - ObjMass : MassKind -> PrimObject ; -- water - ObjAndObj : PrimObject -> Object -> Object ; -- this pizza and a beer - OneObj : PrimObject -> Object ; -- this pizza - - SuchKind : Quality -> Kind -> Kind ; -- Italian pizza - SuchMassKind : Quality -> MassKind -> MassKind ; -- Italian water - Very : Property -> Quality ; -- very Italian - Too : Property -> Quality ; -- too Italian - PropQuality : Property -> Quality ; -- Italian - - MassDrink : DrinkKind -> MassKind ; -- beer - DrinkNumber : Number -> DrinkKind -> PrimObject ; -- five beers - --- Determiners. - - This, That, These, Those : Kind -> Item ; -- this pizza,...,those pizzas - The, Thes : Kind -> Item ; -- the pizza, the pizzas - ThisMass, ThatMass, TheMass : MassKind -> Item ; -- this/that/the water - ThesePlur, ThosePlur, ThesPlur : PlurKind -> Item ; -- these/those/the potatoes - - AmountCurrency : Number -> Currency -> Price ; -- five euros - - ThePlace : PlaceKind -> Place ; -- the bar - APlace : PlaceKind -> Place ; -- a bar - - IMale, IFemale, -- I, said by man/woman (affects agreement) - YouFamMale, YouFamFemale, -- familiar you, said to man/woman (affects agreement) - YouPolMale, YouPolFemale : Person ; -- polite you, said to man/woman (affects agreement) - - LangNat : Nationality -> LAnguage ; -- Swedish - CitiNat : Nationality -> Citizenship ; -- Swedish - CountryNat : Nationality -> Country ; -- Sweden - PropCit : Citizenship -> Property ; -- Swedish - - OnDay : Day -> Date ; -- on Friday - Today : Date ; -- today - - PersonName : Name -> Person ; -- person referred by name - NameNN : Name ; -- the name "NN" - ----- NameString : String -> Name ; ---- creates ambiguities with all words --% - - NNumeral : Numeral -> Number ; -- numeral in words, e.g. "twenty" - --- Actions are typically language-dependent, not only lexically but also --- structurally. However, these ones are mostly functorial. - - SHave : Person -> Object -> Sentence ; -- you have beer - SHaveNo : Person -> Kind -> Sentence ; -- you have no apples - SHaveNoMass : Person -> MassKind -> Sentence ; -- you have no beer - QDoHave : Person -> Object -> Question ; -- do you have beer - - AHaveCurr : Person -> Currency -> Action ; -- you have dollars - ACitizen : Person -> Citizenship -> Action ; -- you are Swedish - ABePlace : Person -> Place -> Action ; -- you are in the bar - - ByTransp : Transport -> ByTransport ; -- by bus - - AKnowSentence : Person -> Sentence -> Action ; -- you know that I am in the bar - AKnowPerson : Person -> Person -> Action ; -- you know me - AKnowQuestion : Person -> Question -> Action ; -- you know how far the bar is - ------------------------------------------------------------------------------------------- --- New things added 30/11/2011 by AR ------------------------------------------------------------------------------------------- - - cat - VerbPhrase ; -- things one does, can do, must do, wants to do, e.g. swim - Modality ; -- can, want, must - fun - ADoVerbPhrase : Person -> VerbPhrase -> Action ; -- I swim - AModVerbPhrase : Modality -> Person -> VerbPhrase -> Action ; -- I can swim - ADoVerbPhrasePlace : Person -> VerbPhrase -> Place -> Action ; -- I swim in the hotel - AModVerbPhrasePlace : Modality -> Person -> VerbPhrase -> Place -> Action ; -- I can swim in the hotel - - QWhereDoVerbPhrase : Person -> VerbPhrase -> Question ; -- where do you swim - QWhereModVerbPhrase : Modality -> Person -> VerbPhrase -> Question ; -- where can I swim - - MCan, MKnow, MMust, MWant : Modality ; - --- lexical items given in the resource Lexicon - - VPlay, VRun, VSit, VSleep, VSwim, VWalk : VerbPhrase ; - VDrink, VEat, VRead, VWait, VWrite, VSit, VStop : VerbPhrase ; - V2Buy, V2Drink, V2Eat : Object -> VerbPhrase ; - V2Wait : Person -> VerbPhrase ; - - PImperativeFamPos, -- eat - PImperativeFamNeg, -- don't eat - PImperativePolPos, -- essen Sie - PImperativePolNeg, -- essen Sie nicht - PImperativePlurPos, -- esst - PImperativePlurNeg : -- esst nicht - VerbPhrase -> Phrase ; - --- other new things allowed by the resource - ---- PBecause : Sentence -> Sentence -> Phrase ; -- I want to swim because it is hot - - He, She, -- he, she - WeMale, WeFemale, -- we, said by men/women (affects agreement) - YouPlurFamMale, YouPlurFamFemale, -- plural familiar you, said to men/women (affects agreement) - YouPlurPolMale, YouPlurPolFemale, -- plural polite you, said to men/women (affects agreement) - TheyMale, TheyFemale : Person ; -- they, said of men/women (affects agreement) - -} - diff --git a/testsuite/canonical/grammars/SentencesBul.gf b/testsuite/canonical/grammars/SentencesBul.gf deleted file mode 100644 index b2968bc85..000000000 --- a/testsuite/canonical/grammars/SentencesBul.gf +++ /dev/null @@ -1,54 +0,0 @@ -concrete SentencesBul of Sentences = - NumeralBul ** SentencesI - [IMale, IFemale, YouFamMale, YouFamFemale, YouPolMale, - YouPolFemale, ACitizen, Citizenship, PCitizenship, - LangNat, CitiNat, CountryNat, PropCit, - Nationality, Country, LAnguage, PLanguage, PCountry - ] with - (Syntax = SyntaxBul), - (Symbolic = SymbolicBul), - (Lexicon = LexiconBul) ** open ExtraBul, (R = ResBul) in { - -lincat - Citizenship = {s1 : R.Gender => R.NForm => Str; -- there are two nouns for every citizenship - one for males and one for females - s2 : A -- furthermore, adjective for Property - } ; - Nationality = {s1 : R.Gender => R.NForm => Str; -- there are two nouns for every citizenship - one for males and one for females - s2 : A; -- furthermore, adjective for Property - s3 : PN -- country name - } ; - LAnguage = A ; - Country = PN ; - -lin IMale = mkPerson i_Pron ; - IFemale = mkPerson i8fem_Pron ; - -lin YouFamMale = mkPerson youSg_Pron ; - YouFamFemale = mkPerson youSg8fem_Pron ; - YouPolMale, YouPolFemale = mkPerson youPol_Pron ; - -lin ACitizen p cit = - let noun : N - = case p.name.gn of { - R.GSg g => lin N {s = \\nf => cit.s1 ! g ! nf; - rel = cit.s2.s; relType = R.AdjMod; - g = case g of {R.Masc=>R.AMasc R.Human; R.Fem=>R.AFem; R.Neut=>R.ANeut} - } ; - R.GPl => lin N {s = \\nf => cit.s1 ! R.Masc ! nf; - rel = cit.s2.s; relType = R.AdjMod; - g = R.AMasc R.Human - } - } ; - in mkCl p.name noun ; - - PCitizenship cit = - mkPhrase (mkUtt (mkAP cit.s2)) ; - - LangNat n = n.s2 ; - CitiNat n = n ; - CountryNat n = n.s3 ; - PropCit cit = cit.s2 ; - - PLanguage x = mkPhrase (mkUtt (mkAP x)) ; - PCountry x = mkPhrase (mkUtt (mkNP x)) ; - -} diff --git a/testsuite/canonical/grammars/SentencesGer.gf b/testsuite/canonical/grammars/SentencesGer.gf deleted file mode 100644 index cc0922d5f..000000000 --- a/testsuite/canonical/grammars/SentencesGer.gf +++ /dev/null @@ -1,50 +0,0 @@ -concrete SentencesGer of Sentences = NumeralGer ** SentencesI - - [PYesToNo,SHaveNo,SHaveNoMass, - Proposition, Action, Is, IsMass, SProp, SPropNot, QProp, - AHaveCurr, ACitizen, ABePlace, AKnowSentence, AKnowPerson, AKnowQuestion, - Nationality, LAnguage, - ADoVerbPhrase, AModVerbPhrase, ADoVerbPhrasePlace, AModVerbPhrasePlace, - YouPlurPolMale, YouPlurPolFemale - ] with - (Syntax = SyntaxGer), - (Symbolic = SymbolicGer), - (Lexicon = LexiconGer) ** open Prelude, SyntaxGer in { - - lin - PYesToNo = mkPhrase (lin Utt (ss "doch")) ; - SHaveNo p k = mkS (mkCl p.name have_V2 (mkNP no_Quant plNum k)) ; - SHaveNoMass p k = mkS (mkCl p.name have_V2 (mkNP no_Quant k)) ; - - lincat - Proposition, Action = Prop ; - oper - Prop = {pos : Cl ; neg : S} ; -- x F y ; x F nicht/kein y - mkProp : Cl -> S -> Prop = \pos,neg -> {pos = pos ; neg = neg} ; - prop : Cl -> Prop = \cl -> mkProp cl (mkS negativePol cl) ; - lin - Is i q = prop (mkCl i q) ; - IsMass m q = prop (mkCl (mkNP m) q) ; - SProp p = mkS p.pos ; - SPropNot p = p.neg ; - QProp p = mkQS (mkQCl p.pos) ; - - AHaveCurr p curr = prop (mkCl p.name have_V2 (mkNP aPl_Det curr)) ; - ACitizen p n = prop (mkCl p.name n) ; - ABePlace p place = prop (mkCl p.name place.at) ; - - AKnowSentence p s = prop (mkCl p.name Lexicon.know_VS s) ; - AKnowQuestion p s = prop (mkCl p.name Lexicon.know_VQ s) ; - AKnowPerson p q = prop (mkCl p.name Lexicon.know_V2 q.name) ; - - lincat - Nationality = {lang : CN ; country : NP ; prop : A} ; - LAnguage = CN ; -- kein Deutsch - --- the new things - lin - ADoVerbPhrase p vp = prop (mkCl p.name vp) ; - AModVerbPhrase m p vp = prop (mkCl p.name (mkVP m vp)) ; - ADoVerbPhrasePlace p vp x = prop (mkCl p.name (mkVP vp x.at)) ; - AModVerbPhrasePlace m p vp x = prop (mkCl p.name (mkVP m (mkVP vp x.at))) ; - YouPlurPolMale, YouPlurPolFemale = mkPerson youPol_Pron ; -} diff --git a/testsuite/canonical/grammars/SentencesI.gf b/testsuite/canonical/grammars/SentencesI.gf deleted file mode 100644 index 913aa11ad..000000000 --- a/testsuite/canonical/grammars/SentencesI.gf +++ /dev/null @@ -1,302 +0,0 @@ ---1 Implementation of MOLTO Phrasebook - ---2 The functor for (mostly) common structures - -incomplete concrete SentencesI of Sentences = Numeral ** - open - Syntax, - Lexicon, - Symbolic, -- for names as strings - Prelude - in { - lincat - Phrase = Text ; - Word = Text ; - Message = Text ; - Greeting = Text ; - Sentence = S ; - Question = QS ; - Proposition = Cl ; - Item = NP ; - Kind = CN ; - MassKind = CN ; - MassKind = CN ; - PlurKind = CN ; - DrinkKind = CN ; - Quality = AP ; - Property = A ; - Object = NP ; - PrimObject = NP ; - Place = NPPlace ; -- {name : NP ; at : Syntax.Adv ; to : Syntax.Adv} ; - PlaceKind = CNPlace ; -- {name : CN ; at : Prep ; to : Prep} ; - Currency = CN ; - Price = NP ; - Action = Cl ; - Person = NPPerson ; -- {name : NP ; isPron : Bool ; poss : Quant} ; - Nationality = NPNationality ; -- {lang : NP ; country : NP ; prop : A} ; - LAnguage = NP ; - Citizenship = A ; - Country = NP ; - Day = NPDay ; -- {name : NP ; point : Syntax.Adv ; habitual : Syntax.Adv} ; - Date = Syntax.Adv ; - Name = NP ; - Number = Card ; - ByTransport = Syntax.Adv ; - Transport = {name : CN ; by : Syntax.Adv} ; - Superlative = Det ; - lin - MPhrase p = p ; - MContinue p m = mkText p m ; - - PSentence s = mkText s | lin Text (mkUtt s) ; -- optional '.' - PQuestion s = mkText s | lin Text (mkUtt s) ; -- optional '?' - - PGreetingMale, PGreetingFemale = \g -> mkText (lin Phr (ss g.s)) exclMarkPunct | g ; - - -- PWord w = w ; - - PNumber x = mkSentence (mkUtt x) ; - PPrice x = mkSentence (mkUtt x) ; - - PObject x = mkPhrase (mkUtt x) ; - PKind x = mkPhrase (mkUtt x) ; - PMassKind x = mkPhrase (mkUtt x) ; - PQuality x = mkPhrase (mkUtt x) ; - PPlace x = mkPhrase (mkUtt x.name) ; - PPlaceKind x = mkPhrase (mkUtt x.name) ; - PCurrency x = mkPhrase (mkUtt x) ; - PLanguage x = mkPhrase (mkUtt x) ; - PCountry x = mkPhrase (mkUtt x) ; - PCitizenship x = mkPhrase (mkUtt (mkAP x)) ; - PDay d = mkPhrase (mkUtt d.name) ; - PTransport t = mkPhrase (mkUtt t.name) ; - PByTransport t = mkPhrase (mkUtt t) ; - - PYes = mkPhrase yes_Utt ; - PNo = mkPhrase no_Utt ; - PYesToNo = mkPhrase yes_Utt ; - - GObjectPlease o = lin Text (mkPhr noPConj (mkUtt o) please_Voc) | lin Text (mkUtt o) ; - - Is = mkCl ; - IsMass m q = mkCl (mkNP m) q ; - - SProp = mkS ; - SPropNot = mkS negativePol ; - QProp p = mkQS (mkQCl p) ; - - WherePlace place = mkQS (mkQCl where_IAdv place.name) ; - WherePerson person = mkQS (mkQCl where_IAdv person.name) ; - - PropAction a = a ; - - AmountCurrency num curr = mkNP num curr ; - - ObjItem i = i ; - ObjNumber n k = mkNP n k ; - ObjIndef k = mkNP a_Quant k ; - ObjPlural k = mkNP aPl_Det k ; - ObjPlur k = mkNP aPl_Det k ; - ObjMass k = mkNP k ; - ObjAndObj = mkNP and_Conj ; - OneObj o = o ; - - MassDrink d = d ; - DrinkNumber n k = mkNP n k ; - - This kind = mkNP this_Quant kind ; - That kind = mkNP that_Quant kind ; - These kind = mkNP this_Quant plNum kind ; - Those kind = mkNP that_Quant plNum kind ; - The kind = mkNP the_Quant kind ; - Thes kind = mkNP the_Quant plNum kind ; - ThisMass kind = mkNP this_Quant kind ; - ThatMass kind = mkNP that_Quant kind ; - TheMass kind = mkNP the_Quant kind ; - ThesePlur kind = mkNP this_Quant plNum kind ; - ThosePlur kind = mkNP that_Quant plNum kind ; - ThesPlur kind = mkNP the_Quant plNum kind ; - - SuchKind quality kind = mkCN quality kind ; - SuchMassKind quality kind = mkCN quality kind ; - Very property = mkAP very_AdA (mkAP property) ; - Too property = mkAP too_AdA (mkAP property) ; - PropQuality property = mkAP property ; - - ThePlace kind = let dd : Det = if_then_else Det kind.isPl thePl_Det theSg_Det - in placeNP dd kind ; - APlace kind = let dd : Det = if_then_else Det kind.isPl aPl_Det aSg_Det - in placeNP dd kind ; - - IMale, IFemale = mkPerson i_Pron ; - YouFamMale, YouFamFemale = mkPerson youSg_Pron ; - YouPolMale, YouPolFemale = mkPerson youPol_Pron ; - - LangNat n = n.lang ; - CitiNat n = n.prop ; - CountryNat n = n.country ; - PropCit c = c ; - - OnDay d = d.point ; - Today = today_Adv ; - - PersonName n = - {name = n ; isPron = False ; poss = mkQuant he_Pron} ; -- poss not used ----- NameString s = symb s ; --% - NameNN = symb "NN" ; - - NNumeral n = mkCard ; - - SHave p obj = mkS (mkCl p.name have_V2 obj) ; - SHaveNo p k = mkS negativePol (mkCl p.name have_V2 (mkNP aPl_Det k)) ; - SHaveNoMass p m = mkS negativePol (mkCl p.name have_V2 (mkNP m)) ; - QDoHave p obj = mkQS (mkQCl (mkCl p.name have_V2 obj)) ; - - AHaveCurr p curr = mkCl p.name have_V2 (mkNP aPl_Det curr) ; - ACitizen p n = mkCl p.name n ; - ABePlace p place = mkCl p.name place.at ; - ByTransp t = t.by ; - - AKnowSentence p s = mkCl p.name Lexicon.know_VS s ; - AKnowQuestion p s = mkCl p.name Lexicon.know_VQ s ; - AKnowPerson p q = mkCl p.name Lexicon.know_V2 q.name ; - -oper - --- These operations are used internally in Sentences. - - mkPhrase : Utt -> Text = \u -> lin Text u ; -- no punctuation - mkGreeting : Str -> Text = \s -> lin Text (ss s) ; -- no punctuation - mkSentence : Utt -> Text = \t -> lin Text (postfixSS "." t | t) ; -- optional . - - mkPerson : Pron -> {name : NP ; isPron : Bool ; poss : Quant} = \p -> - {name = mkNP p ; isPron = True ; poss = mkQuant p} ; - --- These are used in Words for each language. - - NPNationality : Type = {lang : NP ; country : NP ; prop : A} ; - - mkNPNationality : NP -> NP -> A -> NPNationality = \la,co,pro -> - {lang = la ; - country = co ; - prop = pro - } ; - - NPDay : Type = {name : NP ; point : Syntax.Adv ; habitual : Syntax.Adv} ; - - mkNPDay : NP -> Syntax.Adv -> Syntax.Adv -> NPDay = \d,p,h -> - {name = d ; - point = p ; - habitual = h - } ; - - NPPlace : Type = {name : NP ; at : Syntax.Adv ; to : Syntax.Adv} ; - CNPlace : Type = {name : CN ; at : Prep ; to : Prep; isPl : Bool} ; - - mkCNPlace : CN -> Prep -> Prep -> CNPlace = \p,i,t -> { - name = p ; - at = i ; - to = t ; - isPl = False - } ; - - mkCNPlacePl : CN -> Prep -> Prep -> CNPlace = \p,i,t -> { - name = p ; - at = i ; - to = t ; - isPl = True - } ; - - placeNP : Det -> CNPlace -> NPPlace = \det,kind -> - let name : NP = mkNP det kind.name in { - name = name ; - at = Syntax.mkAdv kind.at name ; - to = Syntax.mkAdv kind.to name - } ; - - NPPerson : Type = {name : NP ; isPron : Bool ; poss : Quant} ; - - relativePerson : GNumber -> CN -> (Num -> NP -> CN -> NP) -> NPPerson -> NPPerson = - \n,x,f,p -> - let num = if_then_else Num n plNum sgNum in { - name = case p.isPron of { - True => mkNP p.poss num x ; - _ => f num p.name x - } ; - isPron = False ; - poss = mkQuant he_Pron -- not used because not pron - } ; - - GNumber : PType = Bool ; - sing = False ; plur = True ; - --- for languages without GenNP, use "the wife of p" - mkRelative : Bool -> CN -> NPPerson -> NPPerson = \n,x,p -> - relativePerson n x - (\a,b,c -> mkNP (mkNP the_Quant a c) (Syntax.mkAdv possess_Prep b)) p ; - --- for languages with GenNP, use "p's wife" --- relativePerson n x (\a,b,c -> mkNP (GenNP b) a c) p ; - - phrasePlease : Utt -> Text = \u -> --- lin Text (mkPhr noPConj u please_Voc) | - lin Text u ; - ------------------------------------------------------------------------------------------- --- New things added 30/11/2011 by AR ------------------------------------------------------------------------------------------- - - lincat - VerbPhrase = VP ; - Modality = VV ; - lin - ADoVerbPhrase p vp = mkCl p.name vp ; - AModVerbPhrase m p vp = mkCl p.name (mkVP m vp) ; - ADoVerbPhrasePlace p vp x = mkCl p.name (mkVP vp x.at) ; - AModVerbPhrasePlace m p vp x = mkCl p.name (mkVP m (mkVP vp x.at)) ; - - QWhereDoVerbPhrase p vp = mkQS (mkQCl where_IAdv (mkCl p.name vp)) ; - QWhereModVerbPhrase m p vp = mkQS (mkQCl where_IAdv (mkCl p.name (mkVP m vp))) ; - - MWant = want_VV ; - MCan = can_VV ; - MKnow = can8know_VV ; - MMust = must_VV ; - - VPlay = mkVP play_V ; - VRun = mkVP run_V ; - VSit = mkVP sit_V ; - VSleep = mkVP sleep_V ; - VSwim = mkVP swim_V ; - VWalk = mkVP walk_V ; - VSit = mkVP sit_V ; - VStop = mkVP stop_V ; - VDrink = mkVP ; - VEat = mkVP ; - VRead = mkVP ; - VWait = mkVP ; - VWrite = mkVP ; - - V2Buy o = mkVP buy_V2 o ; - V2Drink o = mkVP drink_V2 o ; - V2Eat o = mkVP eat_V2 o ; - V2Wait o = mkVP wait_V2 o.name ; - - PImperativeFamPos v = phrasePlease (mkUtt (mkImp v)) ; - PImperativeFamNeg v = phrasePlease (mkUtt negativePol (mkImp v)) ; - PImperativePolPos v = phrasePlease (mkUtt politeImpForm (mkImp v)) ; - PImperativePolNeg v = phrasePlease (mkUtt politeImpForm negativePol (mkImp v)) ; - PImperativePlurPos v = phrasePlease (mkUtt pluralImpForm (mkImp v)) ; - PImperativePlurNeg v = phrasePlease (mkUtt pluralImpForm negativePol (mkImp v)) ; - --- other new things allowed by the resource - ---- PBecause a b = SSubjS a because_Subj b ; - - He = mkPerson he_Pron ; - She = mkPerson she_Pron ; - WeMale, WeFemale = mkPerson we_Pron ; - YouPlurFamMale, YouPlurFamFemale = mkPerson youPl_Pron ; - YouPlurPolMale, YouPlurPolFemale = mkPerson youPl_Pron ; - TheyMale, TheyFemale = mkPerson they_Pron ; - -} diff --git a/testsuite/canonical/grammars/Words.gf b/testsuite/canonical/grammars/Words.gf deleted file mode 100644 index 08704990a..000000000 --- a/testsuite/canonical/grammars/Words.gf +++ /dev/null @@ -1,254 +0,0 @@ ---2 Words and idiomatic phrases of the Phrasebook - - --- (c) 2010 Aarne Ranta under LGPL --% - -abstract Words = Sentences ** { - - fun - --- kinds of items (so far mostly food stuff) - - Apple : Kind ; - Beer : DrinkKind ; - Bread : MassKind ; - Cheese : MassKind ; - Chicken : MassKind ; - Coffee : DrinkKind ; - Fish : MassKind ; - Meat : MassKind ; - Milk : MassKind ; - Pizza : Kind ; - Salt : MassKind ; - Tea : DrinkKind ; - Water : DrinkKind ; - Wine : DrinkKind ; - --- properties of kinds (so far mostly of food) - - Bad : Property ; - Boring : Property ; - Cheap : Property ; - Cold : Property ; - Delicious : Property ; - Expensive : Property ; - Fresh : Property ; - Good : Property ; - Suspect : Property ; - Warm : Property ; - --- kinds of places - - Airport : PlaceKind ; - AmusementPark : PlaceKind ; - Bank : PlaceKind ; - Bar : PlaceKind ; - Cafeteria : PlaceKind ; - Center : PlaceKind ; - Cinema : PlaceKind ; - Church : PlaceKind ; - Disco : PlaceKind ; - Hospital : PlaceKind ; - Hotel : PlaceKind ; - Museum : PlaceKind ; - Park : PlaceKind ; - Parking : PlaceKind ; - Pharmacy : PlaceKind ; - PostOffice : PlaceKind ; - Pub : PlaceKind ; - Restaurant : PlaceKind ; - School : PlaceKind ; - Shop : PlaceKind ; - Station : PlaceKind ; - Supermarket : PlaceKind ; - Theatre : PlaceKind ; - Toilet : PlaceKind ; - University : PlaceKind ; - Zoo : PlaceKind ; - - CitRestaurant : Citizenship -> PlaceKind ; - --- currency units - - DanishCrown : Currency ; - Dollar : Currency ; - Euro : Currency ; -- Germany, France, Italy, Finland, Spain, The Netherlands - Lei : Currency ; -- Romania - Leva : Currency ; -- Bulgaria - NorwegianCrown : Currency ; - Pound : Currency ; -- UK - Rouble : Currency ; -- Russia - Rupee : Currency ; -- India - SwedishCrown : Currency ; - Zloty : Currency ; -- Poland - Yuan : Currency ; -- China - - --- nationalities, countries, languages, citizenships - - Belgian : Citizenship ; - Belgium : Country ; - Bulgarian : Nationality ; - Catalan : Nationality ; - Chinese : Nationality ; - Danish : Nationality ; - Dutch : Nationality ; - English : Nationality ; - Finnish : Nationality ; - Flemish : LAnguage ; - French : Nationality ; - German : Nationality ; - Hindi : LAnguage ; - India : Country ; - Indian : Citizenship ; - Italian : Nationality ; - Norwegian : Nationality ; - Polish : Nationality ; - Romanian : Nationality ; - Russian : Nationality ; - Spanish : Nationality ; - Swedish : Nationality ; - --- means of transportation - - Bike : Transport ; - Bus : Transport ; - Car : Transport ; - Ferry : Transport ; - Plane : Transport ; - Subway : Transport ; - Taxi : Transport ; - Train : Transport ; - Tram : Transport ; - - ByFoot : ByTransport ; - - --- Actions (which can be expressed by different structures in different languages). --- Notice that also negations and questions can be formed from these. - - AHasAge : Person -> Number -> Action ; -- I am seventy years - AHasChildren: Person -> Number -> Action ; -- I have six children - AHasName : Person -> Name -> Action ; -- my name is Bond - AHasRoom : Person -> Number -> Action ; -- you have a room for five persons - AHasTable : Person -> Number -> Action ; -- you have a table for five persons - AHungry : Person -> Action ; -- I am hungry - AIll : Person -> Action ; -- I am ill - AKnow : Person -> Action ; -- I (don't) know - ALike : Person -> Item -> Action ; -- I like this pizza - ALive : Person -> Country -> Action ; -- I live in Sweden - ALove : Person -> Person -> Action ; -- I love you - AMarried : Person -> Action ; -- I am married - AReady : Person -> Action ; -- I am ready - AScared : Person -> Action ; -- I am scared - ASpeak : Person -> LAnguage -> Action ; -- I speak Finnish - AThirsty : Person -> Action ; -- I am thirsty - ATired : Person -> Action ; -- I am tired - AUnderstand : Person -> Action ; -- I (don't) understand - AWant : Person -> Object -> Action ; -- I want two apples - AWantGo : Person -> Place -> Action ; -- I want to go to the hospital - --- Miscellaneous phrases. Notice that also negations and questions can be formed from --- propositions. - - QWhatAge : Person -> Question ; -- how old are you - QWhatName : Person -> Question ; -- what is your name - HowMuchCost : Item -> Question ; -- how much does the pizza cost - ItCost : Item -> Price -> Proposition ; -- the pizza costs five euros - - PropOpen : Place -> Proposition ; -- the museum is open - PropClosed : Place -> Proposition ; -- the museum is closed - PropOpenDate : Place -> Date -> Proposition ; -- the museum is open today - PropClosedDate : Place -> Date -> Proposition ; -- the museum is closed today - PropOpenDay : Place -> Day -> Proposition ; -- the museum is open on Mondays - PropClosedDay : Place -> Day -> Proposition ; -- the museum is closed on Mondays - - PSeeYouPlaceDate : Place -> Date -> Greeting ; -- see you in the bar on Monday - PSeeYouPlace : Place -> Greeting ; -- see you in the bar - PSeeYouDate : Date -> Greeting ; -- see you on Monday - --- family relations - - Wife, Husband : Person -> Person ; -- my wife, your husband - Son, Daughter : Person -> Person ; -- my son, your husband - Children : Person -> Person ; -- my children - --- week days - - Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday : Day ; - - Tomorrow : Date ; - --- transports - - HowFar : Place -> Question ; -- how far is the zoo ? - HowFarFrom : Place -> Place -> Question ; -- how far is the center from the hotel ? - HowFarFromBy : Place -> Place -> ByTransport -> Question ; - -- how far is the airport from the hotel by taxi ? - HowFarBy : Place -> ByTransport -> Question ; -- how far is the museum by bus ? - - WhichTranspPlace : Transport -> Place -> Question ; -- which bus goes to the hotel - IsTranspPlace : Transport -> Place -> Question ; -- is there a metro to the airport ? - --- modifiers of places - - TheBest : Superlative ; - TheClosest : Superlative ; - TheCheapest : Superlative ; - TheMostExpensive : Superlative ; - TheMostPopular : Superlative ; - TheWorst : Superlative ; - - SuperlPlace : Superlative -> PlaceKind -> Place ; -- the best bar - - --------------------------------------------------- --- New 30/11/2011 AR --------------------------------------------------- -{- 28/8/2012 still only available in Bul Eng Fin Swe Tha - - fun - Thai : Nationality ; - Baht : Currency ; -- Thailand - - Rice : MassKind ; - Pork : MassKind ; - Beef : MassKind ; - Noodles : PlurKind ; - Shrimps : PlurKind ; - - Chili : MassKind ; - Garlic : MassKind ; - - Durian : Kind ; - Mango : Kind ; - Pineapple : Kind ; - Egg : Kind ; - - Coke : DrinkKind ; - IceCream : DrinkKind ; --- both mass and plural - OrangeJuice : DrinkKind ; - Lemonade : DrinkKind ; - Salad : DrinkKind ; - - Beach : PlaceKind ; - - ItsRaining : Proposition ; - ItsWindy : Proposition ; - ItsWarm : Proposition ; - ItsCold : Proposition ; - SunShine : Proposition ; - - Smoke : VerbPhrase ; - - ADoctor : Person -> Action ; - AProfessor : Person -> Action ; - ALawyer : Person -> Action ; - AEngineer : Person -> Action ; - ATeacher : Person -> Action ; - ACook : Person -> Action ; - AStudent : Person -> Action ; - ABusinessman : Person -> Action ; --} - -} diff --git a/testsuite/canonical/grammars/WordsBul.gf b/testsuite/canonical/grammars/WordsBul.gf deleted file mode 100644 index 527b3604a..000000000 --- a/testsuite/canonical/grammars/WordsBul.gf +++ /dev/null @@ -1,305 +0,0 @@ ---2 Implementations of Words, with English as example - -concrete WordsBul of Words = SentencesBul ** - open - SyntaxBul, - (R = ResBul), - ParadigmsBul, - (L = LexiconBul), - (P = ParadigmsBul), - ExtraBul, - MorphoFunsBul, - Prelude in { - - flags - coding=utf8; - - lin - --- Kinds; many of them are in the resource lexicon, others can be built by $mkN$. - - Apple = mkCN L.apple_N ; - Beer = mkCN L.beer_N ; - Bread = mkCN L.bread_N ; - Cheese = mkCN (mkN066 "сирене") ; - Chicken = mkCN (mkN065 "пиле") ; - Coffee = mkCN (mkN065 "кафе") ; - Fish = mkCN L.fish_N ; - Meat = mkCN (mkN054 "месо") ; - Milk = mkCN L.milk_N ; - Pizza = mkCN (mkN041 "пица") ; - Salt = mkCN L.salt_N ; - Tea = mkCN (mkN028 "чай") ; - Water = mkCN L.water_N ; - Wine = mkCN L.wine_N ; - --- Properties; many of them are in the resource lexicon, others can be built by $mkA$. - - Bad = L.bad_A ; - Boring = mkA079 "еднообразен" ; - Cheap = mkA076 "евтин" ; - Cold = L.cold_A ; - Delicious = mkA079 "превъзходен" ; - Expensive = mkA076 "скъп" ; - Fresh = mkA076 "свеж" ; - Good = L.good_A ; - Suspect = mkA079 "подозрителен" ; - Warm = L.warm_A ; - --- Places require different prepositions to express location; in some languages --- also the directional preposition varies, but in English we use $to$, as --- defined by $mkPlace$. - - Airport = mkPlace (mkN066 "летище") na_Prep ; - AmusementPark = mkCompoundPlace (mkA079 "увеселителен") (mkN001 "парк") in_Prep ; - Bank = mkPlace (mkN041 "банка") in_Prep ; - Bar = mkPlace (mkN001 "бар") in_Prep ; - Cafeteria = mkPlace (mkN065 "кафе") in_Prep ; - Center = mkPlace (mkN009a "център") in_Prep ; - Cinema = mkPlace (mkN054 "кино") na_Prep ; - Church = mkPlace (mkN041 "църква") in_Prep ; - Disco = mkPlace (mkN041 "дискотека") in_Prep ; - Hospital = mkPlace (mkN041 "болница") in_Prep ; - Hotel = mkPlace (mkN007 "хотел") in_Prep ; - Museum = mkPlace (mkN032 "музей") in_Prep ; - Park = mkPlace (mkN001 "парк") in_Prep ; - Parking = mkPlace (mkN007 "паркинг") na_Prep ; - Pharmacy = mkPlace (mkN041 "аптека") in_Prep ; - PostOffice = mkPlace (mkN041 "поща") in_Prep ; - Pub = mkPlace (mkN001 "бар") in_Prep ; - Restaurant = mkPlace (mkN007 "ресторант") in_Prep ; - School = mkPlace (mkN007 "училище") in_Prep ; - Shop = mkPlace (mkN007 "магазин") in_Prep ; - Station = mkPlace (mkN041 "гара") na_Prep ; - Supermarket = mkPlace (mkN007 "супермаркет") in_Prep ; - Theatre = mkPlace (mkN009 "театър") na_Prep ; - Toilet = mkPlace (mkN041 "тоалетна") in_Prep ; - University = mkPlace (mkN007 "университет") in_Prep ; - Zoo = mkPlace (mkN001 "зоопарк") in_Prep ; - - CitRestaurant cit = mkCNPlace (mkCN cit.s2 (mkN007 "ресторант")) in_Prep to_Prep ; - --- Currencies; $crown$ is ambiguous between Danish and Swedish crowns. - - DanishCrown = mkCN (mkA078 "датски") (mkN041 "крона") | mkCN (mkN041 "крона") ; - Dollar = mkCN (mkN007 "долар") ; - Euro = mkCN (mkN054 "евро") ; - Lei = mkCN (mkN047 "лея") ; - Leva = mkCN (mkN001 "лев") ; - NorwegianCrown = mkCN (mkA078 "норвежки") (mkN041 "крона") | mkCN (mkN041 "крона") ; - Pound = mkCN (mkN007 "паунд") ; - Rouble = mkCN (mkN041 "рубла") ; - SwedishCrown = mkCN (mkA078 "шведски") (mkN041 "крона") | mkCN (mkN041 "крона") ; - Zloty = mkCN (mkN041 "злота") ; - Baht = mkCN (mkN007a "бат") ; - --- Nationalities - - Belgian = mkCitizenship (mkN013 "белгиец") (mkN041 "белгийка") (mkA078 "белгийски") ; - Belgium = mkPN "Белгия" R.Fem ; - Bulgarian = mkNat (mkN018 "българин") (mkN041 "българка") (mkA078 "български") (mkPN "България" R.Fem) ; - Catalan = mkNat (mkN008a "каталонец") (mkN041 "каталонка") (mkA078 "каталонски") (mkPN "Каталуния" R.Fem) ; - Danish = mkNat (mkN018 "датчанин") (mkN041 "датчанка") (mkA078 "датски") (mkPN "Дания" R.Fem) ; - Dutch = mkNat (mkN008a "холандец") (mkN041 "холандка") (mkA078 "холандски") (mkPN "Холандия" R.Fem) ; - English = mkNat (mkN018 "англичанин") (mkN041 "англичанка") (mkA078 "английски") (mkPN "Англия" R.Fem) ; - Finnish = mkNat (mkN008a "финландец") (mkN041 "финландка") (mkA078 "финландски") (mkPN "Финландия" R.Fem) ; - Flemish = mkA078 "фламандски" ; - French = mkNat (mkN018 "французин") (mkN041 "французойка") (mkA078 "френски") (mkPN "Франция" R.Fem) ; - German = mkNat (mkN008a "германец") (mkN041 "германка") (mkA078 "немски") (mkPN "Германия" R.Fem) ; - Italian = mkNat (mkN008a "италианец") (mkN041 "италианка") (mkA078 "италиански") (mkPN "Италия" R.Fem) ; - Norwegian = mkNat (mkN008a "норвежец") (mkN041 "норвежка") (mkA078 "норвежки") (mkPN "Норвегия" R.Fem) ; - Polish = mkNat (mkN014 "поляк") (mkN047 "полякиня") (mkA078 "полски") (mkPN "Полша" R.Fem) ; - Romanian = mkNat (mkN008a "румънец") (mkN041 "румънка") (mkA078 "румънски") (mkPN "Румъния" R.Fem) ; - Russian = mkNat (mkN014 "руснак") (mkN047 "рускиня") (mkA078 "руски") (mkPN "Русия" R.Fem) ; - Swedish = mkNat (mkN007 "швед") (mkN041 "шведка") (mkA078 "шведски") (mkPN "Швеция" R.Fem) ; - Spanish = mkNat (mkN008a "испанец") (mkN041 "испанка") (mkA078 "испански") (mkPN "Испания" R.Fem) ; - Thai = mkNat (mkN008a "тайландец") (mkN041 "тайландка") (mkA078 "тайландски") (mkPN "Тайланд" R.Masc) ; - --- Means of transportation - - Bike = mkTransport L.bike_N ; - Bus = mkTransport (mkN007 "автобус") ; - Car = mkTransport L.car_N ; - Ferry = mkTransport (mkN007 "ферибот") ; - Plane = mkTransport (mkN007 "самолет") ; - Subway = mkTransport (mkN054 "метро") ; - Taxi = mkTransport (mkN073 "такси") ; - Train = mkTransport (mkN001 "влак") ; - Tram = mkTransport (mkN032 "трамвай") ; - - ByFoot = P.mkAdv "пеша" ; - --- Actions: the predication patterns are very often language-dependent. - - AHasAge p num = mkCl p.name (SyntaxBul.mkAdv na_Prep (mkNP num L.year_N)) ; - AHasChildren p num = mkCl p.name have_V2 (mkNP num L.child_N) ; - AHasRoom p num = mkCl p.name have_V2 (mkNP (mkNP a_Det (mkN047 "стая")) (SyntaxBul.mkAdv (mkPrep "за" R.Acc) (mkNP num (mkN014 "човек")))) ; - AHasTable p num = mkCl p.name have_V2 (mkNP (mkNP a_Det (mkN041 "маса")) (SyntaxBul.mkAdv (mkPrep "за" R.Acc) (mkNP num (mkN014 "човек")))) ; - AHasName p name = mkCl p.name (dirV2 (medialV (actionV (mkV186 "казвам") (mkV156 "кажа")) R.Acc)) name ; - AHungry p = mkCl p.name (mkA079 "гладен") ; - AIll p = mkCl p.name (mkA079 "болен") ; - AKnow p = mkCl p.name (actionV (mkV186 "знам") (mkV162 "зная")) ; - ALike p item = mkCl p.name (dirV2 (actionV (mkV186 "харесвам") (mkV186 "харесам"))) item ; - ALive p co = mkCl p.name (mkVP (mkVP (stateV (mkV160 "живея"))) (SyntaxBul.mkAdv in_Prep (mkNP co))) ; - ALove p q = mkCl p.name (dirV2 (actionV (mkV186 "обичам") (mkV152 "обикна"))) q.name ; - AMarried p = mkCl p.name (mkA076 (case p.name.gn of { - R.GSg R.Fem => "омъжен" ; - _ => "женен" - })) ; - AReady p = mkCl p.name (mkA076 "готов") ; - AScared p = mkCl p.name (mkA076 "уплашен") ; - ASpeak p lang = mkCl p.name (dirV2 (stateV (mkV173 "говоря"))) (mkNP (substantiveN lang (R.AMasc R.NonHuman))) ; - AThirsty p = mkCl p.name (mkA079 "жаден") ; - ATired p = mkCl p.name (mkA076 "уморен") ; - AUnderstand p = mkCl p.name (actionV (mkV186 "разбирам") (mkV170 "разбера")) ; - AWant p obj = mkCl p.name (dirV2 (stateV (mkV186 "искам"))) obj ; - AWantGo p place = mkCl p.name want_VV (mkVP (mkVP (actionV (mkV186 "отивам") (mkV146 "отида"))) place.to) ; - --- miscellaneous - - QWhatName p = mkQS (mkQCl how_IAdv (mkCl p.name (medialV (actionV (mkV186 "казвам") (mkV156 "кажа")) R.Acc))) ; - QWhatAge p = mkQS (mkQCl (MorphoFunsBul.mkIAdv "на колко") (mkCl p.name (mkNP a_Quant plNum L.year_N))) ; - HowMuchCost item = mkQS (mkQCl how8much_IAdv (mkCl item (stateV (mkV186 "струвам")))) ; - ItCost item price = mkCl item (dirV2 (stateV (mkV186 "струвам"))) price ; - - PropOpen p = mkCl p.name open_AP ; - PropClosed p = mkCl p.name closed_AP ; - PropOpenDate p d = mkCl p.name (mkVP (mkVP open_AP) d) ; - PropClosedDate p d = mkCl p.name (mkVP (mkVP closed_AP) d) ; - PropOpenDay p d = mkCl p.name (mkVP (mkVP open_AP) d.habitual) ; - PropClosedDay p d = mkCl p.name (mkVP (mkVP closed_AP) d.habitual) ; - --- Building phrases from strings is complicated: the solution is to use --- mkText : Text -> Text -> Text ; - - PSeeYouDate d = mkText (lin Text (ss ("ще се видим"))) (mkPhrase (mkUtt d)) ; - PSeeYouPlace p = mkText (lin Text (ss ("ще се видим"))) (mkPhrase (mkUtt p.at)) ; - PSeeYouPlaceDate p d = - mkText (lin Text (ss ("ще се видим"))) - (mkText (mkPhrase (mkUtt p.at)) (mkPhrase (mkUtt d))) ; - --- Relations are expressed as "my wife" or "my son's wife", as defined by $xOf$ --- below. Languages without productive genitives must use an equivalent of --- "the wife of my son" for non-pronouns. - - Wife = xOf sing (mkN041 "съпруга") ; - Husband = xOf sing (mkN015 "съпруг") ; - Son = xOf sing (mkN018 "син") ; - Daughter = xOf sing (mkN047 "дъщеря") ; - Children = xOf plur L.child_N ; - --- week days - - Monday = mkDay (mkN014 "понеделник") ; - Tuesday = mkDay (mkN014 "вторник") ; - Wednesday = mkDay (mkN043 "сряда") ; - Thursday = mkDay (mkN014 "четвъртък") ; - Friday = mkDay (mkN014 "петък") ; - Saturday = mkDay (mkN041 "събота") ; - Sunday = mkDay (mkN047 "неделя") ; - - Tomorrow = P.mkAdv "утре" ; - --- modifiers of places - - TheBest = mkSuperl L.good_A ; - TheClosest = mkSuperl L.near_A ; - TheCheapest = mkSuperl (mkA076 "евтин") ; - TheMostExpensive = mkSuperl (mkA076 "скъп") ; - TheMostPopular = mkSuperl (mkA079 "известен") ; - TheWorst = mkSuperl L.bad_A ; - - SuperlPlace sup p = placeNP sup p ; - - --- transports - - HowFar place = mkQS (mkQCl far_IAdv place.name) ; - HowFarFrom x y = mkQS (mkQCl far_IAdv (mkNP y.name (SyntaxBul.mkAdv from_Prep x.name))) ; - HowFarFromBy x y t = - mkQS (mkQCl far_IAdv (mkNP (mkNP y.name (SyntaxBul.mkAdv from_Prep x.name)) t)) ; - HowFarBy y t = mkQS (mkQCl far_IAdv (mkNP y.name t)) ; - - WhichTranspPlace trans place = - mkQS (mkQCl (mkIP which_IDet trans.name) (mkVP (mkVP L.go_V) place.to)) ; - - IsTranspPlace trans place = - mkQS (mkQCl (mkCl (mkCN trans.name place.to))) ; - - Rice = mkCN (mkN040a "ориз") ; - Pork = mkCN (mkN054 "свинско") ; - Beef = mkCN (mkN054 "телешко") ; - Egg = mkCN (mkN066 "яйце") ; - Noodles = mkCN (mkN075 "спагети") ; - Shrimps = mkCN (mkN041 "скарида") ; - Chili = mkCN (mkN065 "чили") ; - Garlic = mkCN (mkN007 "чесън") ; - Durian = mkCN (mkN007 "дуриан") ; - Mango = mkCN (mkN065 "манго") ; - Pineapple = mkCN (mkN007 "ананас") ; - Coke = mkCN (mkN041 "кола") ; - IceCream = mkCN (mkN007 "сладолед") ; - Salad = mkCN (mkN041 "салата") ; - OrangeJuice = mkCN (mkA076 "портокалов") (mkN001 "сок") ; - Lemonade = mkCN (mkN041 "лимонада") ; - - Beach = mkPlace (mkN001 "плаж") na_Prep ; - - ItsRaining = mkCl (mkVP (stateV (mkV174 "валя"))) ; - ItsCold = mkCl (mkVP (mkA076 "студен")) ; - ItsWarm = mkCl (mkVP (mkA080 "топъл")) ; - ItsWindy = mkCl (mkVP (mkA076 "ветровит")) ; - SunShine = mkCl (progressiveVP (mkVP (actionV (mkV186 "пеквам") (mkV148 "пека")))) ; - - Smoke = mkVP (stateV (mkV176 "пуша")) ; - - ADoctor = mkProfession (mkN007a "доктор") ; - AProfessor = mkProfession (mkN007a "професор") ; - ALawyer = mkProfession (mkN007a "адвокат") ; - AEngineer = mkProfession (mkN007a "инженер") ; - ATeacher = mkProfession (mkN031a "учител") ; - ACook = mkProfession (mkN007b "готвач") ; - AStudent = mkProfession (mkN007a "студент") ; - ABusinessman = mkProfession (mkN007a "бизнесмен") ; - --- auxiliaries - - oper - mkProfession : N -> NPPerson -> Cl = \n,p -> mkCl p.name n ; - - mkCitizenship : N -> N -> A -> Citizenship - = \male, female, adj -> lin Citizenship {s1 = table {R.Fem => female.s; _ => male.s}; s2 = adj} ; - - mkNat : N -> N -> A -> PN -> Nationality - = \male, female, adj, country -> lin Nationality {s1 = table {R.Fem => female.s; _ => male.s}; s2 = adj; s3 = country} ; - - mkDay : N -> {name : NP ; point : Adv ; habitual : Adv} = \d -> - let day : NP = mkNP d ; - in mkNPDay day - (SyntaxBul.mkAdv in_Prep day) - (SyntaxBul.mkAdv in_Prep (mkNP the_Quant plNum (mkCN d))) ; - - mkCompoundPlace : A -> N -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \a, n, p -> - mkCNPlace (mkCN a n) p to_Prep ; - - mkPlace : N -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \n,p -> - mkCNPlace (mkCN n) p to_Prep ; - - open_AP = mkAP (mkA076 "отворен") ; - closed_AP = mkAP (mkA076 "затворен") ; - - xOf : GNumber -> N -> NPPerson -> NPPerson = \n,x,p -> - relativePerson n (mkCN x) (\a,b,c -> mkNP (mkNP the_Quant a c) (SyntaxBul.mkAdv (mkPrep "" R.Dat) b)) p ; - - mkTransport : N -> {name : CN ; by : Adv} = \n -> { - name = mkCN n ; - by = SyntaxBul.mkAdv with_Prep (mkNP n) - } ; - - mkSuperl : A -> Det = \a -> SyntaxBul.mkDet the_Art (SyntaxBul.mkOrd a) ; - - far_IAdv = ExtraBul.IAdvAdv (ss "далече") ; - - na_Prep = mkPrep "на" R.Acc ; - -} diff --git a/testsuite/canonical/grammars/WordsGer.gf b/testsuite/canonical/grammars/WordsGer.gf deleted file mode 100644 index 4984eb080..000000000 --- a/testsuite/canonical/grammars/WordsGer.gf +++ /dev/null @@ -1,262 +0,0 @@ --- (c) 2009 Aarne Ranta under LGPL ---# -coding=latin1 - -concrete WordsGer of Words = SentencesGer ** - open SyntaxGer, ParadigmsGer, IrregGer, (L = LexiconGer), ExtraGer, Prelude in { - - lin - --- kinds of food - - Apple = mkCN L.apple_N ; - Beer = mkCN L.beer_N ; - Bread = mkCN L.bread_N ; - Cheese = mkCN (mkN "Kse" "Kse" "Kse" "Kse" "Kse" "Kse" masculine) ; - Chicken = mkCN (mkN "Huhn" "Huhn" "Huhn" "Huhn" "Hhner" "Hhner" neuter) ; - Coffee = mkCN (mkN "Kaffee" "Kaffee" "Kaffee" "Kaffee" "Kaffees" "Kaffee" masculine) ; - Fish = mkCN L.fish_N ; - Meat = mkCN (mkN "Fleisch" "Fleisch" "Fleisch" "Fleisch" "Fleisch" "Fleisch" neuter) ; - Milk = mkCN L.milk_N ; - Pizza = mkCN (mkN "Pizza" "Pizzen" feminine) ; - Salt = mkCN L.salt_N ; - Tea = mkCN (mkN "Tee" "Tee" "Tee" "Tee" "Tees" "Tees" masculine) ; - Water = mkCN L.water_N ; - Wine = mkCN L.wine_N ; - --- properties - - Bad = L.bad_A ; - Cheap = mkA "billig" ; - Boring = mkA "langweilig" ; - Cold = L.cold_A ; - Delicious = mkA "lecker" ; - Expensive = mkA "teuer" ; - Fresh = mkA "frisch" ; - Good = L.good_A ; - Warm = L.warm_A ; - Suspect = mkA "verdchtig" ; - --- places - - Airport = mkPlace (mkN "Flughafen" "Flughfen" masculine) on_Prep zu_Prep ; - Church = mkPlace (mkN "Kirche") in_Prep inAcc_Prep ; - Hospital = mkPlace (mkN "Krankenhaus" "Krankenhuser" neuter) in_Prep inAcc_Prep ; - Restaurant = mkPlace (mkN "Restaurant" "Restaurants" neuter) in_Prep inAcc_Prep ; - Station = mkPlace (mkN "Bahnhof" "Bahnhfe" masculine) on_Prep zu_Prep ; - University = mkPlace (mkN "Universitt" "Universitten" feminine) in_Prep zu_Prep ; - - AmusementPark = mkPlace (mkN "Vergngungspark" "Vergngungspark" "Vergngungspark" "Vergngungspark" "Vergngungsparks" "Vergngungsparks" masculine) in_Prep inAcc_Prep ; - Bank = mkPlace (mkN "Bank" "Bank" "Bank" "Bank" "Banken" "Banken" feminine) in_Prep zu_Prep ; - Bar = mkPlace (mkN "Bar" "Bar" "Bar" "Bar" "Bars" "Bars" feminine) in_Prep inAcc_Prep ; - Cafeteria = mkPlace (mkN "Cafeteria" "Cafeteria" "Cafeteria" "Cafeteria" "Cafeterien" "Cafeterien" feminine) in_Prep inAcc_Prep ; - Center = mkPlace (mkN "Zentrum" "Zentrum" "Zentrum" "Zentrum" "Zentren" "Zentren" neuter) in_Prep zu_Prep ; - Cinema = mkPlace (mkN "Kino" "Kino" "Kino" "Kino" "Kinos" "Kinos" neuter) in_Prep inAcc_Prep ; - Disco = mkPlace (mkN "Disco" "Disco" "Disco" "Disco" "Discos" "Discos" feminine) in_Prep inAcc_Prep ; - Hotel = mkPlace (mkN "Hotel" "Hotel" "Hotel" "Hotel" "Hotels" "Hotels" neuter) in_Prep inAcc_Prep ; - Museum = mkPlace (mkN "Museum" "Museum" "Museum" "Museum" "Museen" "Museen" neuter) in_Prep inAcc_Prep ; - Park = mkPlace (mkN "Park" "Park" "Park" "Park" "Parks" "Parks" masculine) in_Prep inAcc_Prep ; - Parking = mkPlace (mkN "Parkplatz" "Parkplatz" "Parkplatz" "Parkplatz" "Parkplatzen" "Parkplatzen" masculine) on_Prep zu_Prep ; - Pharmacy = mkPlace (mkN "Apotheke" "Apotheke" "Apotheke" "Apotheke" "Apotheken" "Apotheken" feminine) in_Prep zu_Prep ; - PostOffice = mkPlace (mkN "Post" "Post" "Post" "Post" "Posten" "Posten" feminine) in_Prep inAcc_Prep ; - Pub = mkPlace (mkN "Kneipe" "Kneipe" "Kneipe" "Kneipe" "Kneipen" "Kneipen" feminine) in_Prep inAcc_Prep; - School = mkPlace (mkN "Schule" "Schule" "Schule" "Schule" "Schulen" "Schule" feminine) in_Prep inAcc_Prep ; - Shop = mkPlace (mkN "Geschft" "Geschft" "Geschft" "Geschft" "Geschfte" "Geschfte" neuter) in_Prep inAcc_Prep ; - Supermarket = mkPlace (mkN "Supermarkt" "Supermarkt" "Supermarkt" "Supermarkt" "Supermrkten" "Supermrkte" masculine) in_Prep inAcc_Prep ; - Theatre = mkPlace (mkN "Theater" "Theater" "Theater" "Theaters" "Theatern" "Thaters" neuter) in_Prep inAcc_Prep ; - Toilet = mkPlace (mkN "Toilette" "Toilette" "Toilette" "Toilette" "Toiletten" "Toiletten" feminine) in_Prep (mkPrep "auf" accusative) ; - Zoo = mkPlace (mkN "Zoo" "Zoo" "Zoo" "Zoo" "Zoos" "Zoos" masculine) in_Prep inAcc_Prep ; - - -CitRestaurant cit = mkCNPlace (mkCN cit (mkN "Restaurant" "Restaurants" neuter)) in_Prep inAcc_Prep ; - - --- currencies - - DanishCrown = mkCN (mkA "Dnisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; - Dollar = mkCN (mkN "Dollar" "Dollar" "Dollar" "Dollar" "Dollar" "Dollar" masculine) ; - Euro = mkCN (mkN "Euro" "Euro" "Euro" "Euro" "Euro" "Euro" neuter) ; - Lei = mkCN (mkN "Leu" "Leu" "Leu" "Leu" "Lei" "Lei" masculine) ; - SwedishCrown = mkCN (mkA "Schwedisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; - Leva = mkCN (mkN "Lewa" "Lewa" "Lewa" "Lewa" "Lewa" "Lewa" feminine); - NorwegianCrown = mkCN (mkA "Norwegisch") (mkN "Krone" "Kronen" feminine) | mkCN (mkN "Krone" "Kronen" feminine) ; - Pound = mkCN (mkN "Pfund" "Pfund" "Pfund" "Pfund" "Pfund" "Pfund" neuter) ; - Rouble = mkCN (mkN "Rubel" "Rubel" "Rubel" "Rubel" "Rubels" "Rubels" masculine); - Zloty = mkCN (mkN "Zloty" "Zloty" "Zloty" "Zloty" "Zloty" "Zloty" masculine); - - - --- nationalities - - Belgian = mkA "belgisch" ; - Belgium = mkNP (mkPN "Belgien") ; - Bulgarian = mkNat "Bulgarien" "Bulgarisch" "bulgarisch" ; - Catalan = mkNat "Katalonien" "Katalanisch" "katalanisch" ; - Danish = mkNat "Dnemark" "Dnisch" "dnisch" ; - Dutch = mkNat "den Niederlanden" "Niederlndisch" "niederlndisch" ; - English = mkNat "England" "Englisch" "englisch" ; - Finnish = mkNat "Finnland" "Finnisch" "finnisch" ; - Flemish = mkCN (mkN "Flmisch" "Flmisch" neuter) ; - French = mkNat "Frankreich" "Franzsisch" "franzsisch" ; - German = mkNat "Deutschland" "Deutsch" "deutsche" ; - Italian = mkNat "Italien" "Italienisch" "italienisch" ; - Norwegian = mkNat "Norwegen" "Norwegisch" "norwegisch" ; - Polish = mkNat "Polen" "Polnisch" "polnisch" ; - Romanian = mkNat "Rumnien" "Rumnisch" "rumnisch" ; - Russian = mkNat "Russland" "Russisch" "russisch" ; - Spanish = mkNat "Spanien" "Spanisch" "spanisch" ; - Swedish = mkNat "Schweden" "Schwedisch" "schwedisch" ; - - - --- actions - - AHasAge p num = prop (mkCl p.name (mkNP num L.year_N)) ; - AHasName p name = prop (mkCl p.name (mkV2 heien_V) name) ; - AHungry p = prop (mkCl p.name (mkA "hungrig")) ; - AHasChildren p num = prop (mkCl p.name have_V2 (mkNP num L.child_N)) ; - AHasRoom p num = prop (mkCl p.name have_V2 - (mkNP (mkNP a_Det (mkN "Zimmer" "Zimmer" neuter)) - (SyntaxGer.mkAdv for_Prep (mkNP num (mkN "Persone"))))) ; - AHasTable p num = prop (mkCl p.name have_V2 - (mkNP (mkNP a_Det (mkN "Tisch")) - (SyntaxGer.mkAdv for_Prep (mkNP num (mkN "Persone"))))) ; - AIll p = prop (mkCl p.name (mkA "krank")) ; - AKnow p = prop (mkCl p.name wissen_V) ; - ALike p item = prop (mkCl p.name (mkV2 mgen_V) item) ; - ALive p co = prop (mkCl p.name (mkVP (mkVP (mkV "wohnen")) (SyntaxGer.mkAdv in_Prep co))) ; - ALove p q = prop (mkCl p.name (mkV2 (mkV "lieben")) q.name) ; - AMarried p = prop (mkCl p.name (mkA "verheiratet")) ; - AReady p = prop (mkCl p.name (mkA "bereit")) ; - AScared p = prop (mkCl p.name have_V2 (mkNP (mkN "Angst" "Angsten" feminine))) ; - ASpeak p lang = mkProp (mkCl p.name (mkV2 sprechen_V) (mkNP lang)) - (mkS (mkCl p.name (mkV2 sprechen_V) (mkNP no_Quant lang))) ; - AThirsty p = prop (mkCl p.name (mkA "durstig")) ; - ATired p = prop (mkCl p.name (mkA "mde")) ; - AUnderstand p = prop (mkCl p.name (fixprefixV "ver" stehen_V)) ; - AWant p obj = prop (mkCl p.name want_VV (mkVP have_V2 obj)) ; - AWantGo p place = prop (mkCl p.name want_VV (mkVP (mkVP L.go_V) place.to)) ; - --- miscellaneous - - QWhatName p = mkQS (mkQCl how_IAdv (mkCl p.name heien_V)) ; - QWhatAge p = mkQS (mkQCl (ICompAP (mkAP L.old_A)) p.name) ; - - PropOpen p = prop (mkCl p.name open_Adv) ; - PropClosed p = prop (mkCl p.name closed_Adv) ; - PropOpenDate p d = prop (mkCl p.name (mkVP (mkVP d) open_Adv)) ; - PropClosedDate p d = prop (mkCl p.name (mkVP (mkVP d) closed_Adv)) ; - PropOpenDay p d = prop (mkCl p.name (mkVP (mkVP d.habitual) open_Adv)) ; - PropClosedDay p d = prop (mkCl p.name (mkVP (mkVP d.habitual) closed_Adv)) ; - - HowMuchCost item = mkQS (mkQCl how8much_IAdv (mkCl item (mkV "kosten"))) ; - ItCost item price = prop (mkCl item (mkV2 (mkV "kosten")) price) ; - --- Building phrases from strings is complicated: the solution is to use --- mkText : Text -> Text -> Text ; - - PSeeYouDate d = mkText (lin Text (ss ("wir sehen uns"))) (mkPhrase (mkUtt d)) ; - PSeeYouPlace p = mkText (lin Text (ss ("wir sehen uns"))) (mkPhrase (mkUtt p.at)) ; - PSeeYouPlaceDate p d = - mkText (lin Text (ss ("wir sehen uns"))) - (mkText (mkPhrase (mkUtt d)) (mkPhrase (mkUtt p.at))) ; - - --- Relations are expressed as "my wife" or "my son's wife", as defined by $xOf$ --- below. Languages without productive genitives must use an equivalent of --- "the wife of my son" for non-pronouns. - - Wife = xOf sing (mkN "Frau" "Frauen" feminine) ; - Husband = xOf sing L.man_N ; - Son = xOf sing (mkN "Sohn" "Shne" masculine) ; - Daughter = xOf sing (mkN "Tochter" "Tchter" feminine) ; - Children = xOf plur L.child_N ; - --- week days - - Monday = mkDay "Montag" ; - Tuesday = mkDay "Dienstag" ; - Wednesday = mkDay "Mittwoch" ; - Thursday = mkDay "Donnerstag" ; - Friday = mkDay "Freitag" ; - Saturday = mkDay "Samstag" ; - Sunday = mkDay "Sonntag" ; - - Tomorrow = ParadigmsGer.mkAdv "morgen" ; - - TheBest = mkSuperl L.good_A ; - TheClosest = mkSuperl L.near_A ; - TheCheapest = mkSuperl (mkA "billig") ; - TheMostExpensive = mkSuperl (mkA "teuer") ; - TheMostPopular = mkSuperl (mkA "beliebt") ; - TheWorst = mkSuperl (mkA "schlimm") ; - - SuperlPlace sup p = placeNP sup p ; - - --- means of transportation - - Bike = mkTransport L.bike_N ; - Bus = mkTransport (mkN "Bus" "Bus" "Bus" "Bus" "Buss" "Buss" masculine) ; - Car = mkTransport L.car_N ; - Ferry = mkTransport (mkN "Fhre" "Fhre" "Fhre" "Fhre" "Fhren" "Fhren" feminine) ; - Plane = mkTransport (mkN "Flugzeug" "Flugzeug" "Flugzeug" "Flugzeug" "Flugzeuge" "Flugzeuge" neuter) ; - Subway = mkTransport (mkN "U-Bahn" "U-Bahn" "U-Bahn" "U-Bahn" "U-Bahnen" "U-Bahnen" feminine) ; - Taxi = mkTransport (mkN "Taxi" "Taxi" "Taxi" "Taxi" "Taxis" "Taxis" neuter) ; - Train = mkTransport (mkN "Zug" "Zug" "Zug" "Zug" "Zge" "Zge" masculine) ; - Tram = mkTransport (mkN "Straenbahn" "Straenbahn" "Straenbahn" "Straenbahn" "Straenbahnen" "Straenbahnen" feminine) ; - - ByFoot = ParadigmsGer.mkAdv "zu Fu" ; - - - HowFar place = mkQS (mkQCl far_IAdv place.name) ; - HowFarFrom x y = mkQS (mkQCl far_IAdv (mkNP (mkNP y.name (SyntaxGer.mkAdv von_Prep x.name)) (ParadigmsGer.mkAdv "entfernt"))) ; - HowFarFromBy x y t = - mkQS (mkQCl far_IAdv (mkCl (mkVP (SyntaxGer.mkAdv zu_Prep (mkNP (mkNP y.name (SyntaxGer.mkAdv von_Prep x.name)) t))))) ; - HowFarBy y t = mkQS (mkQCl far_IAdv (mkCl (mkVP (SyntaxGer.mkAdv zu_Prep (mkNP y.name t))))) ; - - WhichTranspPlace trans place = - mkQS (mkQCl (mkIP which_IDet trans.name) (mkVP (mkVP L.go_V) place.to)) ; - - IsTranspPlace trans place = - mkQS (mkQCl (mkCl (mkCN trans.name place.to))) ; - - - - - oper - - mkNat : Str -> Str -> Str -> {lang : CN ; prop : A ; country : NP} = \co, la, adj -> - {lang = mkCN (mkN la la neuter) ; - prop = mkA adj ; country = mkNP (mkPN co)} ; - - mkDay : Str -> {name : NP ; point : Adv ; habitual : Adv} = \d -> - let day = mkNP (mkPN d masculine) in - {name = day ; - point = SyntaxGer.mkAdv (mkPrep "am" dative) day ; ---- am - habitual = ParadigmsGer.mkAdv (d + "s") ---- - } ; - - mkPlace : N -> Prep -> Prep -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \p,at,to -> { - name = mkCN p ; - at = at ; - to = to ; - isPl = False - } ; - - open_Adv = ParadigmsGer.mkAdv "geffnet" ; ---- Adv to get right word order easily - closed_Adv = ParadigmsGer.mkAdv "geschlossen" ; - - xOf : GNumber -> N -> NPPerson -> NPPerson = \n,x,p -> mkRelative n (mkCN x) p ; - - - mkSuperl : A -> Det = \a -> SyntaxGer.mkDet the_Art (SyntaxGer.mkOrd a) ; - - - mkTransport : N -> {name : CN ; by : Adv} = \n -> { - name = mkCN n ; - by = SyntaxGer.mkAdv by8means_Prep (mkNP the_Det n) - } ; - - far_IAdv = ss "wie weit" ** {lock_IAdv = <>} ; - -} diff --git a/testsuite/canonical/run.sh b/testsuite/canonical/run.sh index 7e5a90f12..be7d1ff6c 100755 --- a/testsuite/canonical/run.sh +++ b/testsuite/canonical/run.sh @@ -12,17 +12,28 @@ else echo "Canonical grammar compiles: OK" fi +echo "" + # https://github.com/GrammaticalFramework/gf-core/issues/101 stack run -- --batch --output-format=canonical_gf grammars/PhrasebookGer.gf -for s in c2 objCtrl; do - grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null - if [ $? -ne 1 ]; then - echo "Canonical grammar contains `$s`: FAIL" - FAILURES=$((FAILURES+1)) - else - echo "Canonical grammar does not contain `$s`: OK" - fi -done +# for s in c2 objCtrl; do +# grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null +# if [ $? -ne 1 ]; then +# echo "Canonical grammar contains \`$s\`: FAIL" +# FAILURES=$((FAILURES+1)) +# else +# echo "Canonical grammar does not contain \`$s\`: OK" +# fi +# done +diff canonical/PhrasebookGer.gf gold/PhrasebookGer.gf +if [ $? -ne 0 ]; then + echo "Canonical grammar doesn't match gold version: FAIL" + FAILURES=$((FAILURES+1)) +else + echo "Canonical grammar matches gold version: OK" +fi + +echo "" # https://github.com/GrammaticalFramework/gf-core/issues/102 stack run -- --batch --output-format=canonical_gf grammars/FoodsFin.gf @@ -34,6 +45,9 @@ else echo "Canonical grammar matches gold version: OK" fi +echo "" + +# Summary if [ $FAILURES -ne 0 ]; then echo "Failures: $FAILURES" exit 1 From 13575b093f265eb8c089df0f40b43ba5fd0f67af Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 10:13:42 +0200 Subject: [PATCH 56/75] Add top-level signatures and general code cleanup --- src/compiler/GF/Compile/GrammarToCanonical.hs | 91 +++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 8810c5911..547f7416a 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -6,30 +6,35 @@ module GF.Compile.GrammarToCanonical( ) where import Data.List(nub,partition) import qualified Data.Map as M +import Data.Maybe(fromMaybe) import qualified Data.Set as S import GF.Data.ErrM import GF.Text.Pretty -import GF.Grammar.Grammar +import GF.Grammar.Grammar as G import GF.Grammar.Lookup(lookupOrigInfo,allOrigInfos,allParamValues) import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp,term2patt,sortRec) import GF.Grammar.Lockfield(isLockLabel) import GF.Grammar.Predef(cPredef,cInts) import GF.Compile.Compute.Predef(predef) import GF.Compile.Compute.Value(Predefined(..)) -import GF.Infra.Ident(ModuleName(..),Ident,ident2raw,rawIdentS,prefixIdent,showIdent,isWildIdent) -import GF.Infra.Option(optionsPGF) +import GF.Infra.Ident(ModuleName(..),Ident,ident2raw,rawIdentS,{-prefixIdent,-}showIdent,isWildIdent) +import GF.Infra.Option(Options,optionsPGF) import PGF.Internal(Literal(..)) -import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues) +import GF.Compile.Compute.ConcreteNew(GlobalEnv,normalForm,resourceValues) import GF.Grammar.Canonical as C -import Debug.Trace +import System.FilePath ((), (<.>)) +import Debug.Trace(trace,traceShow) + -- | Generate Canonical code for the named abstract syntax and all associated -- concrete syntaxes +grammar2canonical :: Options -> ModuleName -> G.Grammar -> C.Grammar grammar2canonical opts absname gr = Grammar (abstract2canonical absname gr) (map snd (concretes2canonical opts absname gr)) -- | Generate Canonical code for the named abstract syntax +abstract2canonical :: ModuleName -> G.Grammar -> Abstract abstract2canonical absname gr = Abstract (modId absname) (convFlags gr absname) cats funs where @@ -44,6 +49,7 @@ abstract2canonical absname gr = convHypo (bt,name,t) = case typeForm t of ([],(_,cat),[]) -> gId cat -- !! + tf -> error $ "abstract2canonical convHypo: " ++ show tf convType t = case typeForm t of @@ -57,15 +63,17 @@ abstract2canonical absname gr = -- | Generate Canonical code for the all concrete syntaxes associated with -- the named abstract syntax in given the grammar. +concretes2canonical :: Options -> ModuleName -> G.Grammar -> [(FilePath, Concrete)] concretes2canonical opts absname gr = [(cncname,concrete2canonical gr cenv absname cnc cncmod) | let cenv = resourceValues opts gr, cnc<-allConcretes gr absname, - let cncname = "canonical/"++render cnc ++ ".gf" :: FilePath + let cncname = "canonical" render cnc <.> "gf" Ok cncmod = lookupModule gr cnc ] -- | Generate Canonical GF for the given concrete module. +concrete2canonical :: G.Grammar -> GlobalEnv -> ModuleName -> ModuleName -> ModuleInfo -> Concrete concrete2canonical gr cenv absname cnc modinfo = Concrete (modId cnc) (modId absname) (convFlags gr cnc) (neededParamTypes S.empty (params defs)) @@ -85,6 +93,11 @@ concrete2canonical gr cenv absname cnc modinfo = else let ((got,need),def) = paramType gr q in def++neededParamTypes (S.union got have) (S.toList need++qs) +toCanonical :: G.Grammar + -> ModuleName + -> GlobalEnv + -> (Ident, Info) + -> [(S.Set QIdent, Either LincatDef LinDef)] toCanonical gr absname cenv (name,jment) = case jment of CncCat (Just (L loc typ)) _ _ pprn _ -> @@ -114,6 +127,7 @@ toCanonical gr absname cenv (name,jment) = unAbs n (Abs _ _ t) = unAbs (n-1) t unAbs _ t = t +tableTypes :: G.Grammar -> [Term] -> S.Set QIdent tableTypes gr ts = S.unions (map tabtys ts) where tabtys t = @@ -122,6 +136,7 @@ tableTypes gr ts = S.unions (map tabtys ts) T (TTyped t) cs -> S.union (paramTypes gr t) (tableTypes gr (map snd cs)) _ -> collectOp tabtys t +paramTypes :: G.Grammar -> G.Type -> S.Set QIdent paramTypes gr t = case t of RecType fs -> S.unions (map (paramTypes gr.snd) fs) @@ -140,11 +155,12 @@ paramTypes gr t = Ok (_,ResParam {}) -> S.singleton q _ -> ignore - ignore = trace ("Ignore: "++show t) S.empty - + ignore = trace ("Ignore: " ++ show t) S.empty +convert :: G.Grammar -> Term -> LinValue convert gr = convert' gr [] +convert' :: G.Grammar -> [Ident] -> Term -> LinValue convert' gr vs = ppT where ppT0 = convert' gr vs @@ -169,13 +185,13 @@ convert' gr vs = ppT Con c -> ParamConstant (Param (gId c) []) Sort k -> VarValue (gId k) EInt n -> LiteralValue (IntConstant n) - Q (m,n) -> if m==cPredef then ppPredef n else VarValue ((gQId m n)) - QC (m,n) -> ParamConstant (Param ((gQId m n)) []) + Q (m,n) -> if m==cPredef then ppPredef n else VarValue (gQId m n) + QC (m,n) -> ParamConstant (Param (gQId m n) []) K s -> LiteralValue (StrConstant s) Empty -> LiteralValue (StrConstant "") FV ts -> VariantValue (map ppT ts) Alts t' vs -> alts vs (ppT t') - _ -> error $ "convert' "++show t + _ -> error $ "convert' ppT: " ++ show t ppCase (p,t) = TableRow (ppP p) (ppTv (patVars p++vs) t) @@ -193,7 +209,7 @@ convert' gr vs = ppT ppP p = case p of PC c ps -> ParamPattern (Param (gId c) (map ppP ps)) - PP (m,c) ps -> ParamPattern (Param ((gQId m c)) (map ppP ps)) + PP (m,c) ps -> ParamPattern (Param (gQId m c) (map ppP ps)) PR r -> RecordPattern (fields r) {- PW -> WildPattern PV x -> VarP x @@ -202,6 +218,7 @@ convert' gr vs = ppT PFloat x -> Lit (show x) PT _ p -> ppP p PAs x p -> AsP x (ppP p) -} + _ -> error $ "convert' ppP: " ++ show p where fields = map field . filter (not.isLockLabel.fst) field (l,p) = RecordRow (lblId l) (ppP p) @@ -218,12 +235,12 @@ convert' gr vs = ppT pre Empty = [""] -- Empty == K "" pre (Strs ts) = concatMap pre ts pre (EPatt p) = pat p - pre t = error $ "pre "++show t + pre t = error $ "convert' alts pre: " ++ show t pat (PString s) = [s] pat (PAlt p1 p2) = pat p1++pat p2 pat (PSeq p1 p2) = [s1++s2 | s1<-pat p1, s2<-pat p2] - pat p = error $ "pat "++show p + pat p = error $ "convert' alts pat: "++show p fields = map field . filter (not.isLockLabel.fst) field (l,(_,t)) = RecordRow (lblId l) (ppT t) @@ -236,6 +253,7 @@ convert' gr vs = ppT ParamConstant (Param p (ps++[a])) _ -> error $ "convert' ap: "++render (ppA f <+> ppA a) +concatValue :: LinValue -> LinValue -> LinValue concatValue v1 v2 = case (v1,v2) of (LiteralValue (StrConstant ""),_) -> v2 @@ -243,8 +261,10 @@ concatValue v1 v2 = _ -> ConcatValue v1 v2 -- | Smart constructor for projections -projection r l = maybe (Projection r l) id (proj r l) +projection :: LinValue -> LabelId -> LinValue +projection r l = fromMaybe (Projection r l) (proj r l) +proj :: LinValue -> LabelId -> Maybe LinValue proj r l = case r of RecordValue r -> case [v | RecordRow l' v <- r, l'==l] of @@ -253,6 +273,7 @@ proj r l = _ -> Nothing -- | Smart constructor for selections +selection :: LinValue -> LinValue -> LinValue selection t v = -- Note: impossible cases can become possible after grammar transformation case t of @@ -276,13 +297,16 @@ selection t v = (keep,discard) = partition (mightMatchRow v) r _ -> Selection t v +impossible :: LinValue -> LinValue impossible = CommentedValue "impossible" +mightMatchRow :: LinValue -> TableRow rhs -> Bool mightMatchRow v (TableRow p _) = case p of WildPattern -> True _ -> mightMatch v p +mightMatch :: LinValue -> LinPattern -> Bool mightMatch v p = case v of ConcatValue _ _ -> False @@ -294,16 +318,18 @@ mightMatch v p = RecordValue rv -> case p of RecordPattern rp -> - and [maybe False (flip mightMatch p) (proj v l) | RecordRow l p<-rp] + and [maybe False (`mightMatch` p) (proj v l) | RecordRow l p<-rp] _ -> False _ -> True +patVars :: Patt -> [Ident] patVars p = case p of PV x -> [x] PAs x p -> x:patVars p _ -> collectPattOp patVars p +convType :: Term -> LinType convType = ppT where ppT t = @@ -315,9 +341,9 @@ convType = ppT Sort k -> convSort k -- EInt n -> tcon0 (identS ("({-"++show n++"-})")) -- type level numeric literal FV (t:ts) -> ppT t -- !! - QC (m,n) -> ParamType (ParamTypeId ((gQId m n))) - Q (m,n) -> ParamType (ParamTypeId ((gQId m n))) - _ -> error $ "Missing case in convType for: "++show t + QC (m,n) -> ParamType (ParamTypeId (gQId m n)) + Q (m,n) -> ParamType (ParamTypeId (gQId m n)) + _ -> error $ "convType ppT: " ++ show t convFields = map convField . filter (not.isLockLabel.fst) convField (l,r) = RecordRow (lblId l) (ppT r) @@ -326,15 +352,20 @@ convType = ppT "Float" -> FloatType "Int" -> IntType "Str" -> StrType - _ -> error ("convSort "++show k) + _ -> error $ "convType convSort: " ++ show k +toParamType :: Term -> ParamType toParamType t = case convType t of ParamType pt -> pt - _ -> error ("toParamType "++show t) + _ -> error $ "toParamType: " ++ show t +toParamId :: Term -> ParamId toParamId t = case toParamType t of ParamTypeId p -> p +paramType :: G.Grammar + -> (ModuleName, Ident) + -> ((S.Set (ModuleName, Ident), S.Set QIdent), [ParamDef]) paramType gr q@(_,n) = case lookupOrigInfo gr q of Ok (m,ResParam (Just (L _ ps)) _) @@ -342,7 +373,7 @@ paramType gr q@(_,n) = ((S.singleton (m,n),argTypes ps), [ParamDef name (map (param m) ps)] ) - where name = (gQId m n) + where name = gQId m n Ok (m,ResOper _ (Just (L _ t))) | m==cPredef && n==cInts -> ((S.empty,S.empty),[]) {- @@ -350,10 +381,10 @@ paramType gr q@(_,n) = [Type (ConAp ((gQId m n)) [identS "n"]) (TId (identS "Int"))])-} | otherwise -> ((S.singleton (m,n),paramTypes gr t), - [ParamAliasDef ((gQId m n)) (convType t)]) + [ParamAliasDef (gQId m n) (convType t)]) _ -> ((S.empty,S.empty),[]) where - param m (n,ctx) = Param ((gQId m n)) [toParamId t|(_,_,t)<-ctx] + param m (n,ctx) = Param (gQId m n) [toParamId t|(_,_,t)<-ctx] argTypes = S.unions . map argTypes1 argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx] @@ -364,7 +395,8 @@ lblId (LVar i) = LabelId (rawIdentS (show i)) -- hmm modId :: ModuleName -> C.ModId modId (MN m) = ModId (ident2raw m) -class FromIdent i where gId :: Ident -> i +class FromIdent i where + gId :: Ident -> i instance FromIdent VarId where gId i = if isWildIdent i then Anonymous else VarId (ident2raw i) @@ -374,14 +406,19 @@ instance FromIdent CatId where gId = CatId . ident2raw instance FromIdent ParamId where gId = ParamId . unqual instance FromIdent VarValueId where gId = VarValueId . unqual -class FromIdent i => QualIdent i where gQId :: ModuleName -> Ident -> i +class FromIdent i => QualIdent i where + gQId :: ModuleName -> Ident -> i -instance QualIdent ParamId where gQId m n = ParamId (qual m n) +instance QualIdent ParamId where gQId m n = ParamId (qual m n) instance QualIdent VarValueId where gQId m n = VarValueId (qual m n) +qual :: ModuleName -> Ident -> QualId qual m n = Qual (modId m) (ident2raw n) + +unqual :: Ident -> QualId unqual n = Unqual (ident2raw n) +convFlags :: G.Grammar -> ModuleName -> Flags convFlags gr mn = Flags [(rawIdentS n,convLit v) | (n,v)<-err (const []) (optionsPGF.mflags) (lookupModule gr mn)] From e5a2aed5b6e31fe89e94e9fd9c22e2488f85cae8 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 11:47:14 +0200 Subject: [PATCH 57/75] Remove record fields not in lincat Fixes #100, #101 --- src/compiler/GF/Compile/GrammarToCanonical.hs | 30 ++++++++++++------- testsuite/canonical/gold/PhrasebookBul.gf | 29 ++++++++++++++++++ testsuite/canonical/gold/PhrasebookGer.gf | 6 ++-- testsuite/canonical/run.sh | 9 +++++- 4 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 testsuite/canonical/gold/PhrasebookBul.gf diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 547f7416a..57a761a64 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -17,13 +17,13 @@ import GF.Grammar.Lockfield(isLockLabel) import GF.Grammar.Predef(cPredef,cInts) import GF.Compile.Compute.Predef(predef) import GF.Compile.Compute.Value(Predefined(..)) -import GF.Infra.Ident(ModuleName(..),Ident,ident2raw,rawIdentS,{-prefixIdent,-}showIdent,isWildIdent) +import GF.Infra.Ident(ModuleName(..),Ident,ident2raw,rawIdentS,showIdent,isWildIdent) import GF.Infra.Option(Options,optionsPGF) import PGF.Internal(Literal(..)) import GF.Compile.Compute.ConcreteNew(GlobalEnv,normalForm,resourceValues) import GF.Grammar.Canonical as C import System.FilePath ((), (<.>)) -import Debug.Trace(trace,traceShow) +import qualified Debug.Trace as T -- | Generate Canonical code for the named abstract syntax and all associated @@ -60,7 +60,6 @@ abstract2canonical absname gr = convHypo' (bt,name,t) = TypeBinding (gId name) (convType t) - -- | Generate Canonical code for the all concrete syntaxes associated with -- the named abstract syntax in given the grammar. concretes2canonical :: Options -> ModuleName -> G.Grammar -> [(FilePath, Concrete)] @@ -93,11 +92,7 @@ concrete2canonical gr cenv absname cnc modinfo = else let ((got,need),def) = paramType gr q in def++neededParamTypes (S.union got have) (S.toList need++qs) -toCanonical :: G.Grammar - -> ModuleName - -> GlobalEnv - -> (Ident, Info) - -> [(S.Set QIdent, Either LincatDef LinDef)] +toCanonical :: G.Grammar -> ModuleName -> GlobalEnv -> (Ident, Info) -> [(S.Set QIdent, Either LincatDef LinDef)] toCanonical gr absname cenv (name,jment) = case jment of CncCat (Just (L loc typ)) _ _ pprn _ -> @@ -110,7 +105,8 @@ toCanonical gr absname cenv (name,jment) = where tts = tableTypes gr [e'] - e' = unAbs (length params) $ + e' = cleanupRecordFields lincat $ + unAbs (length params) $ nf loc (mkAbs params (mkApp def (map Vr args))) params = [(b,x)|(b,x,_)<-ctx] args = map snd params @@ -121,7 +117,6 @@ toCanonical gr absname cenv (name,jment) = _ -> [] where nf loc = normalForm cenv (L loc name) --- aId n = prefixIdent "A." (gId n) unAbs 0 t = t unAbs n (Abs _ _ t) = unAbs (n-1) t @@ -155,7 +150,20 @@ paramTypes gr t = Ok (_,ResParam {}) -> S.singleton q _ -> ignore - ignore = trace ("Ignore: " ++ show t) S.empty + ignore = T.trace ("Ignore: " ++ show t) S.empty + +-- | Filter out record fields from definitions which don't appear in lincat. +cleanupRecordFields :: G.Type -> Term -> Term +cleanupRecordFields (RecType ls) (R as) = + let defnFields = M.fromList ls + in R + [ (lbl, (mty, t')) + | (lbl, (mty, t)) <- as + , M.member lbl defnFields + , let Just ty = M.lookup lbl defnFields + , let t' = cleanupRecordFields ty t + ] +cleanupRecordFields _ t = t convert :: G.Grammar -> Term -> LinValue convert gr = convert' gr [] diff --git a/testsuite/canonical/gold/PhrasebookBul.gf b/testsuite/canonical/gold/PhrasebookBul.gf new file mode 100644 index 000000000..eb10cc48c --- /dev/null +++ b/testsuite/canonical/gold/PhrasebookBul.gf @@ -0,0 +1,29 @@ +concrete PhrasebookBul of Phrasebook = { +param Prelude_Bool = Prelude_False | Prelude_True; +param ResBul_AGender = ResBul_AMasc ResBul_Animacy | ResBul_AFem | ResBul_ANeut; +param ResBul_Animacy = ResBul_Human | ResBul_NonHuman; +param ResBul_Case = ResBul_Acc | ResBul_Dat | ResBul_WithPrep | ResBul_CPrep; +param ResBul_NForm = + ResBul_NF ParamX_Number ResBul_Species | ResBul_NFSgDefNom | + ResBul_NFPlCount | ResBul_NFVocative; +param ParamX_Number = ParamX_Sg | ParamX_Pl; +param ResBul_Species = ResBul_Indef | ResBul_Def; +lincat PlaceKind = + {at : {s : Str; c : ResBul_Case}; isPl : Prelude_Bool; + name : {s : ResBul_NForm => Str; g : ResBul_AGender}; + to : {s : Str; c : ResBul_Case}}; + VerbPhrase = {s : Str}; +lin Airport = + {at = {s = "на"; c = ResBul_Acc}; isPl = Prelude_False; + name = + {s = + table {ResBul_NF ParamX_Sg ResBul_Indef => "летище"; + ResBul_NF ParamX_Sg ResBul_Def => "летището"; + ResBul_NF ParamX_Pl ResBul_Indef => "летища"; + ResBul_NF ParamX_Pl ResBul_Def => "летищата"; + ResBul_NFSgDefNom => "летището"; + ResBul_NFPlCount => "летища"; + ResBul_NFVocative => "летище"}; + g = ResBul_ANeut}; + to = {s = "до"; c = ResBul_CPrep}}; +} \ No newline at end of file diff --git a/testsuite/canonical/gold/PhrasebookGer.gf b/testsuite/canonical/gold/PhrasebookGer.gf index 22d750b78..912f3b7b1 100644 --- a/testsuite/canonical/gold/PhrasebookGer.gf +++ b/testsuite/canonical/gold/PhrasebookGer.gf @@ -205,9 +205,9 @@ lin VRead = "gelesener"}; aux = ResGer_VHaben; particle = ""; prefix = ""; vtype = ResGer_VAct}; - a1 = ""; a2 = ""; adj = ""; - ext = ""; inf = {s = ""; ctrl = ResGer_NoC; isAux = Prelude_True}; - infExt = ""; isAux = Prelude_False; + a1 = ""; a2 = ""; adj = ""; ext = ""; + inf = {s = ""; ctrl = ResGer_NoC; isAux = Prelude_True}; infExt = ""; + isAux = Prelude_False; nn = table {ResGer_Ag ResGer_Masc ParamX_Sg ParamX_P1 => {p1 = ""; p2 = ""; p3 = ""; p4 = ""; p5 = ""; p6 = ""}; diff --git a/testsuite/canonical/run.sh b/testsuite/canonical/run.sh index be7d1ff6c..c39f1e557 100755 --- a/testsuite/canonical/run.sh +++ b/testsuite/canonical/run.sh @@ -9,7 +9,14 @@ if [ $? -ne 0 ]; then echo "Canonical grammar doesn't compile: FAIL" FAILURES=$((FAILURES+1)) else - echo "Canonical grammar compiles: OK" + # echo "Canonical grammar compiles: OK" + diff canonical/PhrasebookBul.gf gold/PhrasebookBul.gf + if [ $? -ne 0 ]; then + echo "Canonical grammar doesn't match gold version: FAIL" + FAILURES=$((FAILURES+1)) + else + echo "Canonical grammar matches gold version: OK" + fi fi echo "" From 78b73fba20d45ed8c3f1c87455795fbf7d670950 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 13:53:33 +0200 Subject: [PATCH 58/75] Make cleanupRecordFields also recurse into variants It's possible that more constructors need to be handled --- src/compiler/GF/Compile/GrammarToCanonical.hs | 3 ++- testsuite/canonical/run.sh | 9 --------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 57a761a64..a600573ac 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -12,7 +12,7 @@ import GF.Data.ErrM import GF.Text.Pretty import GF.Grammar.Grammar as G import GF.Grammar.Lookup(lookupOrigInfo,allOrigInfos,allParamValues) -import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp,term2patt,sortRec) +import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,composSafeOp,mkAbs,mkApp,term2patt,sortRec) import GF.Grammar.Lockfield(isLockLabel) import GF.Grammar.Predef(cPredef,cInts) import GF.Compile.Compute.Predef(predef) @@ -163,6 +163,7 @@ cleanupRecordFields (RecType ls) (R as) = , let Just ty = M.lookup lbl defnFields , let t' = cleanupRecordFields ty t ] +cleanupRecordFields ty t@(FV _) = composSafeOp (cleanupRecordFields ty) t cleanupRecordFields _ t = t convert :: G.Grammar -> Term -> LinValue diff --git a/testsuite/canonical/run.sh b/testsuite/canonical/run.sh index c39f1e557..81c03c5d1 100755 --- a/testsuite/canonical/run.sh +++ b/testsuite/canonical/run.sh @@ -23,15 +23,6 @@ echo "" # https://github.com/GrammaticalFramework/gf-core/issues/101 stack run -- --batch --output-format=canonical_gf grammars/PhrasebookGer.gf -# for s in c2 objCtrl; do -# grep VRead --after-context=216 canonical/PhrasebookGer.gf | grep "$s" > /dev/null -# if [ $? -ne 1 ]; then -# echo "Canonical grammar contains \`$s\`: FAIL" -# FAILURES=$((FAILURES+1)) -# else -# echo "Canonical grammar does not contain \`$s\`: OK" -# fi -# done diff canonical/PhrasebookGer.gf gold/PhrasebookGer.gf if [ $? -ne 0 ]; then echo "Canonical grammar doesn't match gold version: FAIL" From a27b07542d731ee0287383feb7a97d5d4708b85e Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 14:05:30 +0200 Subject: [PATCH 59/75] Add run-on-grammar canonical test script --- testsuite/canonical/run-on-grammar.sh | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 testsuite/canonical/run-on-grammar.sh diff --git a/testsuite/canonical/run-on-grammar.sh b/testsuite/canonical/run-on-grammar.sh new file mode 100755 index 000000000..f621035e3 --- /dev/null +++ b/testsuite/canonical/run-on-grammar.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env sh + +# For a given grammar, compile into canonical format, +# then ensure that the canonical format itself is compilable. + +if [ $# -lt 1 ]; then + echo "Please specify concrete modules to test with, e.g.:" + echo "./run-on-grammar.sh ../../../gf-contrib/foods/FoodsEng.gf ../../../gf-contrib/foods/FoodsFin.gf" + exit 2 +fi + +FAILURES=0 + +for CNC_PATH in "$@"; do + CNC_FILE=$(basename "$CNC_PATH") + stack run -- --batch --output-format=canonical_gf "$CNC_PATH" + if [ $? -ne 0 ]; then + echo "Failed to compile into canonical" + FAILURES=$((FAILURES+1)) + continue + fi + + stack run -- --batch "canonical/$CNC_FILE" + if [ $? -ne 0 ]; then + echo "Failed to compile canonical" + FAILURES=$((FAILURES+1)) + fi +done + +# Summary +if [ $FAILURES -ne 0 ]; then + echo "Failures: $FAILURES" + exit 1 +else + echo "All tests passed" +fi From 71d99b9ecb2f59a5591bfdd9ab4695b00acbfd1c Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 14:21:29 +0200 Subject: [PATCH 60/75] Rename GF.Compile.Compute.ConcreteNew to GF.Compile.Compute.Concrete --- gf.cabal | 2 +- src/compiler/GF/Command/SourceCommands.hs | 4 +- src/compiler/GF/Compile/CheckGrammar.hs | 46 +- src/compiler/GF/Compile/Compute/Concrete.hs | 591 +++++++++++++++++- .../GF/Compile/Compute/ConcreteNew.hs | 588 ----------------- src/compiler/GF/Compile/Compute/Value.hs | 8 +- src/compiler/GF/Compile/GeneratePMCFG.hs | 12 +- src/compiler/GF/Compile/GrammarToCanonical.hs | 6 +- src/compiler/GF/Compile/Optimize.hs | 16 +- .../GF/Compile/TypeCheck/ConcreteNew.hs | 38 +- 10 files changed, 654 insertions(+), 657 deletions(-) delete mode 100644 src/compiler/GF/Compile/Compute/ConcreteNew.hs diff --git a/gf.cabal b/gf.cabal index 9a9e3903e..854f8cfbf 100644 --- a/gf.cabal +++ b/gf.cabal @@ -178,7 +178,7 @@ library GF.Command.TreeOperations GF.Compile.CFGtoPGF GF.Compile.CheckGrammar - GF.Compile.Compute.ConcreteNew + GF.Compile.Compute.Concrete GF.Compile.Compute.Predef GF.Compile.Compute.Value GF.Compile.ExampleBased diff --git a/src/compiler/GF/Command/SourceCommands.hs b/src/compiler/GF/Command/SourceCommands.hs index 0ba60d245..daf3f7f1e 100644 --- a/src/compiler/GF/Command/SourceCommands.hs +++ b/src/compiler/GF/Command/SourceCommands.hs @@ -18,7 +18,7 @@ import GF.Grammar.Parser (runP, pExp) import GF.Grammar.ShowTerm import GF.Grammar.Lookup (allOpers,allOpersTo) import GF.Compile.Rename(renameSourceTerm) -import qualified GF.Compile.Compute.ConcreteNew as CN(normalForm,resourceValues) +import GF.Compile.Compute.Concrete(normalForm,resourceValues) import GF.Compile.TypeCheck.RConcrete as TC(inferLType,ppType) import GF.Infra.Dependencies(depGraph) import GF.Infra.CheckM(runCheck) @@ -259,7 +259,7 @@ checkComputeTerm os sgr t = ((t,_),_) <- runCheck $ do t <- renameSourceTerm sgr mo t inferLType sgr [] t let opts = modifyFlags (\fs->fs{optTrace=isOpt "trace" os}) - t1 = CN.normalForm (CN.resourceValues opts sgr) (L NoLoc identW) t + t1 = normalForm (resourceValues opts sgr) (L NoLoc identW) t t2 = evalStr t1 checkPredefError t2 where diff --git a/src/compiler/GF/Compile/CheckGrammar.hs b/src/compiler/GF/Compile/CheckGrammar.hs index 24582bba2..e7839da34 100644 --- a/src/compiler/GF/Compile/CheckGrammar.hs +++ b/src/compiler/GF/Compile/CheckGrammar.hs @@ -5,7 +5,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/11/11 23:24:33 $ +-- > CVS $Date: 2005/11/11 23:24:33 $ -- > CVS $Author: aarne $ -- > CVS $Revision: 1.31 $ -- @@ -29,7 +29,7 @@ import GF.Infra.Option import GF.Compile.TypeCheck.Abstract import GF.Compile.TypeCheck.RConcrete import qualified GF.Compile.TypeCheck.ConcreteNew as CN -import qualified GF.Compile.Compute.ConcreteNew as CN +import qualified GF.Compile.Compute.Concrete as CN import GF.Grammar import GF.Grammar.Lexer @@ -74,9 +74,9 @@ checkRestrictedInheritance cwd sgr (name,mo) = checkInModule cwd mo NoLoc empty let (incl,excl) = partition (isInherited mi) (Map.keys (jments m)) let incld c = Set.member c (Set.fromList incl) let illegal c = Set.member c (Set.fromList excl) - let illegals = [(f,is) | + let illegals = [(f,is) | (f,cs) <- allDeps, incld f, let is = filter illegal cs, not (null is)] - case illegals of + case illegals of [] -> return () cs -> checkWarn ("In inherited module" <+> i <> ", dependence of excluded constants:" $$ nest 2 (vcat [f <+> "on" <+> fsep is | (f,is) <- cs])) @@ -92,12 +92,12 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc -- check that all abstract constants are in concrete; build default lin and lincats jsc <- foldM checkAbs jsc (Map.toList jsa) - + return (cm,cnc{jments=jsc}) where checkAbs js i@(c,info) = case info of - AbsFun (Just (L loc ty)) _ _ _ + AbsFun (Just (L loc ty)) _ _ _ -> do let mb_def = do let (cxt,(_,i),_) = typeForm ty info <- lookupIdent i js @@ -136,11 +136,11 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}") return $ Map.insert c (CncCat (Just (L NoLoc defLinType)) Nothing Nothing Nothing Nothing) js _ -> return js - + checkCnc js (c,info) = case info of CncFun _ d mn mf -> case lookupOrigInfo gr (am,c) of - Ok (_,AbsFun (Just (L _ ty)) _ _ _) -> + Ok (_,AbsFun (Just (L _ ty)) _ _ _) -> do (cont,val) <- linTypeOfType gr cm ty let linty = (snd (valCat ty),cont,val) return $ Map.insert c (CncFun (Just linty) d mn mf) js @@ -159,14 +159,14 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc _ -> return $ Map.insert c info js --- | General Principle: only Just-values are checked. +-- | General Principle: only Just-values are checked. -- A May-value has always been checked in its origin module. checkInfo :: Options -> FilePath -> SourceGrammar -> SourceModule -> Ident -> Info -> Check Info checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do checkReservedId c case info of - AbsCat (Just (L loc cont)) -> - mkCheck loc "the category" $ + AbsCat (Just (L loc cont)) -> + mkCheck loc "the category" $ checkContext gr cont AbsFun (Just (L loc typ0)) ma md moper -> do @@ -181,7 +181,7 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do CncCat mty mdef mref mpr mpmcfg -> do mty <- case mty of - Just (L loc typ) -> chIn loc "linearization type of" $ + Just (L loc typ) -> chIn loc "linearization type of" $ (if False --flag optNewComp opts then do (typ,_) <- CN.checkLType (CN.resourceValues opts gr) typ typeType typ <- computeLType gr [] typ @@ -191,19 +191,19 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do return (Just (L loc typ))) Nothing -> return Nothing mdef <- case (mty,mdef) of - (Just (L _ typ),Just (L loc def)) -> + (Just (L _ typ),Just (L loc def)) -> chIn loc "default linearization of" $ do (def,_) <- checkLType gr [] def (mkFunType [typeStr] typ) return (Just (L loc def)) _ -> return Nothing mref <- case (mty,mref) of - (Just (L _ typ),Just (L loc ref)) -> + (Just (L _ typ),Just (L loc ref)) -> chIn loc "reference linearization of" $ do (ref,_) <- checkLType gr [] ref (mkFunType [typ] typeStr) return (Just (L loc ref)) _ -> return Nothing mpr <- case mpr of - (Just (L loc t)) -> + (Just (L loc t)) -> chIn loc "print name of" $ do (t,_) <- checkLType gr [] t typeStr return (Just (L loc t)) @@ -212,13 +212,13 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do CncFun mty mt mpr mpmcfg -> do mt <- case (mty,mt) of - (Just (cat,cont,val),Just (L loc trm)) -> + (Just (cat,cont,val),Just (L loc trm)) -> chIn loc "linearization of" $ do (trm,_) <- checkLType gr [] trm (mkFunType (map (\(_,_,ty) -> ty) cont) val) -- erases arg vars return (Just (L loc trm)) _ -> return mt mpr <- case mpr of - (Just (L loc t)) -> + (Just (L loc t)) -> chIn loc "print name of" $ do (t,_) <- checkLType gr [] t typeStr return (Just (L loc t)) @@ -251,16 +251,16 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do ResOverload os tysts -> chIn NoLoc "overloading" $ do tysts' <- mapM (uncurry $ flip (\(L loc1 t) (L loc2 ty) -> checkLType gr [] t ty >>= \(t,ty) -> return (L loc1 t, L loc2 ty))) tysts -- return explicit ones tysts0 <- lookupOverload gr (m,c) -- check against inherited ones too - tysts1 <- mapM (uncurry $ flip (checkLType gr [])) + tysts1 <- mapM (uncurry $ flip (checkLType gr [])) [(mkFunType args val,tr) | (args,(val,tr)) <- tysts0] --- this can only be a partial guarantee, since matching --- with value type is only possible if expected type is given - checkUniq $ + checkUniq $ sort [let (xs,t) = typeFormCnc x in t : map (\(b,x,t) -> t) xs | (_,x) <- tysts1] return (ResOverload os [(y,x) | (x,y) <- tysts']) ResParam (Just (L loc pcs)) _ -> do - ts <- chIn loc "parameter type" $ + ts <- chIn loc "parameter type" $ liftM concat $ mapM mkPar pcs return (ResParam (Just (L loc pcs)) (Just ts)) @@ -274,9 +274,9 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do return $ map (mkApp (QC (m,f))) vs checkUniq xss = case xss of - x:y:xs + x:y:xs | x == y -> checkError $ "ambiguous for type" <+> - ppType (mkFunType (tail x) (head x)) + ppType (mkFunType (tail x) (head x)) | otherwise -> checkUniq $ y:xs _ -> return () @@ -294,7 +294,7 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do t' <- compAbsTyp ((x,Vr x):g) t return $ Prod b x a' t' Abs _ _ _ -> return t - _ -> composOp (compAbsTyp g) t + _ -> composOp (compAbsTyp g) t -- | for grammars obtained otherwise than by parsing ---- update!! diff --git a/src/compiler/GF/Compile/Compute/Concrete.hs b/src/compiler/GF/Compile/Compute/Concrete.hs index f411f2ca0..4b54c8c84 100644 --- a/src/compiler/GF/Compile/Compute/Concrete.hs +++ b/src/compiler/GF/Compile/Compute/Concrete.hs @@ -1,3 +1,588 @@ -module GF.Compile.Compute.Concrete{-(module M)-} where ---import GF.Compile.Compute.ConcreteLazy as M -- New ---import GF.Compile.Compute.ConcreteStrict as M -- Old, inefficient +-- | Functions for computing the values of terms in the concrete syntax, in +-- | preparation for PMCFG generation. +module GF.Compile.Compute.Concrete + (GlobalEnv, GLocation, resourceValues, geLoc, geGrammar, + normalForm, + Value(..), Bind(..), Env, value2term, eval, vapply + ) where +import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint + +import GF.Grammar hiding (Env, VGen, VApp, VRecType) +import GF.Grammar.Lookup(lookupResDefLoc,allParamValues) +import GF.Grammar.Predef(cPredef,cErrorType,cTok,cStr,cTrace,cPBool) +import GF.Grammar.PatternMatch(matchPattern,measurePatt) +import GF.Grammar.Lockfield(isLockLabel,lockRecType) --unlockRecord,lockLabel +import GF.Compile.Compute.Value hiding (Error) +import GF.Compile.Compute.Predef(predef,predefName,delta) +import GF.Data.Str(Str,glueStr,str2strings,str,sstr,plusStr,strTok) +import GF.Data.Operations(Err,err,errIn,maybeErr,mapPairsM) +import GF.Data.Utilities(mapFst,mapSnd) +import GF.Infra.Option +import Control.Monad(ap,liftM,liftM2) -- ,unless,mplus +import Data.List (findIndex,intersect,nub,elemIndex,(\\)) --,isInfixOf +--import Data.Char (isUpper,toUpper,toLower) +import GF.Text.Pretty +import qualified Data.Map as Map +import Debug.Trace(trace) + +-- * Main entry points + +normalForm :: GlobalEnv -> L Ident -> Term -> Term +normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc) + +nfx env@(GE _ _ _ loc) t = do + v <- eval env [] t + case value2term loc [] v of + Left i -> fail ("variable #"++show i++" is out of scope") + Right t -> return t + +eval :: GlobalEnv -> Env -> Term -> Err Value +eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t + where + cenv = CE gr rvs opts loc (map fst env) + +--apply env = apply' env + +-------------------------------------------------------------------------------- + +-- * Environments + +type ResourceValues = Map.Map ModuleName (Map.Map Ident (Err Value)) + +data GlobalEnv = GE Grammar ResourceValues Options GLocation +data CompleteEnv = CE {srcgr::Grammar,rvs::ResourceValues, + opts::Options, + gloc::GLocation,local::LocalScope} +type GLocation = L Ident +type LocalScope = [Ident] +type Stack = [Value] +type OpenValue = Stack->Value + +geLoc (GE _ _ _ loc) = loc +geGrammar (GE gr _ _ _) = gr + +ext b env = env{local=b:local env} +extend bs env = env{local=bs++local env} +global env = GE (srcgr env) (rvs env) (opts env) (gloc env) + +var :: CompleteEnv -> Ident -> Err OpenValue +var env x = maybe unbound pick' (elemIndex x (local env)) + where + unbound = fail ("Unknown variable: "++showIdent x) + pick' i = return $ \ vs -> maybe (err i vs) ok (pick i vs) + err i vs = bug $ "Stack problem: "++showIdent x++": " + ++unwords (map showIdent (local env)) + ++" => "++show (i,length vs) + ok v = --trace ("var "++show x++" = "++show v) $ + v + +pick :: Int -> Stack -> Maybe Value +pick 0 (v:_) = Just v +pick i (_:vs) = pick (i-1) vs +pick i vs = Nothing -- bug $ "pick "++show (i,vs) + +resource env (m,c) = +-- err bug id $ + if isPredefCat c + then value0 env =<< lockRecType c defLinType -- hmm + else maybe e id $ Map.lookup c =<< Map.lookup m (rvs env) + where e = fail $ "Not found: "++render m++"."++showIdent c + +-- | Convert operators once, not every time they are looked up +resourceValues :: Options -> SourceGrammar -> GlobalEnv +resourceValues opts gr = env + where + env = GE gr rvs opts (L NoLoc identW) + rvs = Map.mapWithKey moduleResources (moduleMap gr) + moduleResources m = Map.mapWithKey (moduleResource m) . jments + moduleResource m c _info = do L l t <- lookupResDefLoc gr (m,c) + let loc = L l c + qloc = L l (Q (m,c)) + eval (GE gr rvs opts loc) [] (traceRes qloc t) + + traceRes = if flag optTrace opts + then traceResource + else const id + +-- * Tracing + +-- | Insert a call to the trace function under the top-level lambdas +traceResource (L l q) t = + case termFormCnc t of + (abs,body) -> mkAbs abs (mkApp traceQ [args,body]) + where + args = R $ tuple2record (K lstr:[Vr x|(bt,x)<-abs,bt==Explicit]) + lstr = render (l<>":"<>ppTerm Qualified 0 q) + traceQ = Q (cPredef,cTrace) + +-- * Computing values + +-- | Computing the value of a top-level term +value0 :: CompleteEnv -> Term -> Err Value +value0 env = eval (global env) [] + +-- | Computing the value of a term +value :: CompleteEnv -> Term -> Err OpenValue +value env t0 = + -- Each terms is traversed only once by this function, using only statically + -- available information. Notably, the values of lambda bound variables + -- will be unknown during the term traversal phase. + -- The result is an OpenValue, which is a function that may be applied many + -- times to different dynamic values, but without the term traversal overhead + -- and without recomputing other statically known information. + -- For this to work, there should be no recursive calls under lambdas here. + -- Whenever we need to construct the OpenValue function with an explicit + -- lambda, we have to lift the recursive calls outside the lambda. + -- (See e.g. the rules for Let, Prod and Abs) +{- + trace (render $ text "value"<+>sep [ppL (gloc env)<>text ":", + brackets (fsep (map ppIdent (local env))), + ppTerm Unqualified 10 t0]) $ +--} + errIn (render t0) $ + case t0 of + Vr x -> var env x + Q x@(m,f) + | m == cPredef -> if f==cErrorType -- to be removed + then let p = identS "P" + in const # value0 env (mkProd [(Implicit,p,typeType)] (Vr p) []) + else if f==cPBool + then const # resource env x + else const . flip VApp [] # predef f + | otherwise -> const # resource env x --valueResDef (fst env) x + QC x -> return $ const (VCApp x []) + App e1 e2 -> apply' env e1 . (:[]) =<< value env e2 + Let (x,(oty,t)) body -> do vb <- value (ext x env) body + vt <- value env t + return $ \ vs -> vb (vt vs:vs) + Meta i -> return $ \ vs -> VMeta i (zip (local env) vs) [] + Prod bt x t1 t2 -> + do vt1 <- value env t1 + vt2 <- value (ext x env) t2 + return $ \ vs -> VProd bt (vt1 vs) x $ Bind $ \ vx -> vt2 (vx:vs) + Abs bt x t -> do vt <- value (ext x env) t + return $ VAbs bt x . Bind . \ vs vx -> vt (vx:vs) + EInt n -> return $ const (VInt n) + EFloat f -> return $ const (VFloat f) + K s -> return $ const (VString s) + Empty -> return $ const (VString "") + Sort s | s == cTok -> return $ const (VSort cStr) -- to be removed + | otherwise -> return $ const (VSort s) + ImplArg t -> (VImplArg.) # value env t + Table p res -> liftM2 VTblType # value env p <# value env res + RecType rs -> do lovs <- mapPairsM (value env) rs + return $ \vs->VRecType $ mapSnd ($vs) lovs + t@(ExtR t1 t2) -> ((extR t.)# both id) # both (value env) (t1,t2) + FV ts -> ((vfv .) # sequence) # mapM (value env) ts + R as -> do lovs <- mapPairsM (value env.snd) as + return $ \ vs->VRec $ mapSnd ($vs) lovs + T i cs -> valueTable env i cs + V ty ts -> do pvs <- paramValues env ty + ((VV ty pvs .) . sequence) # mapM (value env) ts + C t1 t2 -> ((ok2p vconcat.) # both id) # both (value env) (t1,t2) + S t1 t2 -> ((select env.) # both id) # both (value env) (t1,t2) + P t l -> --maybe (bug $ "project "++show l++" from "++show v) id $ + do ov <- value env t + return $ \ vs -> let v = ov vs + in maybe (VP v l) id (proj l v) + Alts t tts -> (\v vts -> VAlts # v <# mapM (both id) vts) # value env t <# mapM (both (value env)) tts + Strs ts -> ((VStrs.) # sequence) # mapM (value env) ts + Glue t1 t2 -> ((ok2p (glue env).) # both id) # both (value env) (t1,t2) + ELin c r -> (unlockVRec (gloc env) c.) # value env r + EPatt p -> return $ const (VPatt p) -- hmm + EPattType ty -> do vt <- value env ty + return (VPattType . vt) + Typed t ty -> value env t + t -> fail.render $ "value"<+>ppTerm Unqualified 10 t $$ show t + +vconcat vv@(v1,v2) = + case vv of + (VString "",_) -> v2 + (_,VString "") -> v1 + (VApp NonExist _,_) -> v1 + (_,VApp NonExist _) -> v2 + _ -> VC v1 v2 + +proj l v | isLockLabel l = return (VRec []) + ---- a workaround 18/2/2005: take this away and find the reason + ---- why earlier compilation destroys the lock field +proj l v = + case v of + VFV vs -> liftM vfv (mapM (proj l) vs) + VRec rs -> lookup l rs +-- VExtR v1 v2 -> proj l v2 `mplus` proj l v1 -- hmm + VS (VV pty pvs rs) v2 -> flip VS v2 . VV pty pvs # mapM (proj l) rs + _ -> return (ok1 VP v l) + +ok1 f v1@(VError {}) _ = v1 +ok1 f v1 v2 = f v1 v2 + +ok2 f v1@(VError {}) _ = v1 +ok2 f _ v2@(VError {}) = v2 +ok2 f v1 v2 = f v1 v2 + +ok2p f (v1@VError {},_) = v1 +ok2p f (_,v2@VError {}) = v2 +ok2p f vv = f vv + +unlockVRec loc c0 v0 = v0 +{- +unlockVRec loc c0 v0 = unlockVRec' c0 v0 + where + unlockVRec' ::Ident -> Value -> Value + unlockVRec' c v = + case v of + -- VClosure env t -> err bug (VClosure env) (unlockRecord c t) + VAbs bt x (Bind f) -> VAbs bt x (Bind $ \ v -> unlockVRec' c (f v)) + VRec rs -> plusVRec rs lock + -- _ -> VExtR v (VRec lock) -- hmm + _ -> {-trace (render $ ppL loc $ "unlock non-record "++show v0)-} v -- hmm + -- _ -> bugloc loc $ "unlock non-record "++show v0 + where + lock = [(lockLabel c,VRec [])] +-} + +-- suspicious, but backwards compatible +plusVRec rs1 rs2 = VRec ([(l,v)|(l,v)<-rs1,l `notElem` ls2] ++ rs2) + where ls2 = map fst rs2 + +extR t vv = + case vv of + (VFV vs,v2) -> vfv [extR t (v1,v2)|v1<-vs] + (v1,VFV vs) -> vfv [extR t (v1,v2)|v2<-vs] + (VRecType rs1, VRecType rs2) -> + case intersect (map fst rs1) (map fst rs2) of + [] -> VRecType (rs1 ++ rs2) + ls -> error $ "clash"<+>show ls + (VRec rs1, VRec rs2) -> plusVRec rs1 rs2 + (v1 , VRec [(l,_)]) | isLockLabel l -> v1 -- hmm + (VS (VV t pvs vs) s,v2) -> VS (VV t pvs [extR t (v1,v2)|v1<-vs]) s +-- (v1,v2) -> ok2 VExtR v1 v2 -- hmm + (v1,v2) -> error $ "not records" $$ show v1 $$ show v2 + where + error explain = ppbug $ "The term" <+> t + <+> "is not reducible" $$ explain + +glue env (v1,v2) = glu v1 v2 + where + glu v1 v2 = + case (v1,v2) of + (VFV vs,v2) -> vfv [glu v1 v2|v1<-vs] + (v1,VFV vs) -> vfv [glu v1 v2|v2<-vs] + (VString s1,VString s2) -> VString (s1++s2) + (v1,VAlts d vs) -> VAlts (glx d) [(glx v,c) | (v,c) <- vs] + where glx v2 = glu v1 v2 + (v1@(VAlts {}),v2) -> + --err (const (ok2 VGlue v1 v2)) id $ + err bug id $ + do y' <- strsFromValue v2 + x' <- strsFromValue v1 + return $ vfv [foldr1 VC (map VString (str2strings (glueStr v u))) | v <- x', u <- y'] + (VC va vb,v2) -> VC va (glu vb v2) + (v1,VC va vb) -> VC (glu v1 va) vb + (VS (VV ty pvs vs) vb,v2) -> VS (VV ty pvs [glu v v2|v<-vs]) vb + (v1,VS (VV ty pvs vs) vb) -> VS (VV ty pvs [glu v1 v|v<-vs]) vb + (v1@(VApp NonExist _),_) -> v1 + (_,v2@(VApp NonExist _)) -> v2 +-- (v1,v2) -> ok2 VGlue v1 v2 + (v1,v2) -> if flag optPlusAsBind (opts env) + then VC v1 (VC (VApp BIND []) v2) + else let loc = gloc env + vt v = case value2term loc (local env) v of + Left i -> Error ('#':show i) + Right t -> t + originalMsg = render $ ppL loc (hang "unsupported token gluing" 4 + (Glue (vt v1) (vt v2))) + term = render $ pp $ Glue (vt v1) (vt v2) + in error $ unlines + [originalMsg + ,"" + ,"There was a problem in the expression `"++term++"`, either:" + ,"1) You are trying to use + on runtime arguments, possibly via an oper." + ,"2) One of the arguments in `"++term++"` is a bound variable from pattern matching a string, but the cases are non-exhaustive." + ,"For more help see https://github.com/GrammaticalFramework/gf-core/tree/master/doc/errors/gluing.md" + ] + + +-- | to get a string from a value that represents a sequence of terminals +strsFromValue :: Value -> Err [Str] +strsFromValue t = case t of + VString s -> return [str s] + VC s t -> do + s' <- strsFromValue s + t' <- strsFromValue t + return [plusStr x y | x <- s', y <- t'] +{- + VGlue s t -> do + s' <- strsFromValue s + t' <- strsFromValue t + return [glueStr x y | x <- s', y <- t'] +-} + VAlts d vs -> do + d0 <- strsFromValue d + v0 <- mapM (strsFromValue . fst) vs + c0 <- mapM (strsFromValue . snd) vs + --let vs' = zip v0 c0 + return [strTok (str2strings def) vars | + def <- d0, + vars <- [[(str2strings v, map sstr c) | (v,c) <- zip vv c0] | + vv <- sequence v0] + ] + VFV ts -> concat # mapM strsFromValue ts + VStrs ts -> concat # mapM strsFromValue ts + + _ -> fail ("cannot get Str from value " ++ show t) + +vfv vs = case nub vs of + [v] -> v + vs -> VFV vs + +select env vv = + case vv of + (v1,VFV vs) -> vfv [select env (v1,v2)|v2<-vs] + (VFV vs,v2) -> vfv [select env (v1,v2)|v1<-vs] + (v1@(VV pty vs rs),v2) -> + err (const (VS v1 v2)) id $ + do --ats <- allParamValues (srcgr env) pty + --let vs = map (value0 env) ats + i <- maybeErr "no match" $ findIndex (==v2) vs + return (ix (gloc env) "select" rs i) + (VT _ _ [(PW,Bind b)],_) -> {-trace "eliminate wild card table" $-} b [] + (v1@(VT _ _ cs),v2) -> + err (\_->ok2 VS v1 v2) (err bug id . valueMatch env) $ + match (gloc env) cs v2 + (VS (VV pty pvs rs) v12,v2) -> VS (VV pty pvs [select env (v11,v2)|v11<-rs]) v12 + (v1,v2) -> ok2 VS v1 v2 + +match loc cs v = + case value2term loc [] v of + Left i -> bad ("variable #"++show i++" is out of scope") + Right t -> err bad return (matchPattern cs t) + where + bad = fail . ("In pattern matching: "++) + +valueMatch :: CompleteEnv -> (Bind Env,Substitution) -> Err Value +valueMatch env (Bind f,env') = f # mapPairsM (value0 env) env' + +valueTable :: CompleteEnv -> TInfo -> [Case] -> Err OpenValue +valueTable env i cs = + case i of + TComp ty -> do pvs <- paramValues env ty + ((VV ty pvs .) # sequence) # mapM (value env.snd) cs + _ -> do ty <- getTableType i + cs' <- mapM valueCase cs + err (dynamic cs' ty) return (convert cs' ty) + where + dynamic cs' ty _ = cases cs' # value env ty + + cases cs' vty vs = err keep ($vs) (convertv cs' (vty vs)) + where + keep msg = --trace (msg++"\n"++render (ppTerm Unqualified 0 (T i cs))) $ + VT wild (vty vs) (mapSnd ($vs) cs') + + wild = case i of TWild _ -> True; _ -> False + + convertv cs' vty = + case value2term (gloc env) [] vty of + 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' ((pty,vs),pvs) = + do sts <- mapM (matchPattern cs') vs + return $ \ vs -> VV pty pvs $ map (err bug id . valueMatch env) + (mapFst ($vs) sts) + + valueCase (p,t) = do p' <- measurePatt # inlinePattMacro p + pvs <- linPattVars p' + vt <- value (extend pvs env) t + return (p',\vs-> Bind $ \bs-> vt (push' p' bs pvs vs)) + + inlinePattMacro p = + case p of + PM qc -> do r <- resource env qc + case r of + VPatt p' -> inlinePattMacro p' + _ -> ppbug $ hang "Expected pattern macro:" 4 + (show r) + _ -> composPattOp inlinePattMacro p + + +paramValues env ty = snd # paramValues' env ty + +paramValues' env ty = paramValues'' env =<< nfx (global env) ty + +paramValues'' env pty = do ats <- allParamValues (srcgr env) pty + pvs <- mapM (eval (global env) []) ats + return ((pty,ats),pvs) + +push' p bs xs = if length bs/=length xs + then bug $ "push "++show (p,bs,xs) + else push bs xs + +push :: Env -> LocalScope -> Stack -> Stack +push bs [] vs = vs +push bs (x:xs) vs = maybe err id (lookup x bs):push bs xs vs + where err = bug $ "Unbound pattern variable "++showIdent x + +apply' :: CompleteEnv -> Term -> [OpenValue] -> Err OpenValue +apply' env t [] = value env t +apply' env t vs = + case t of + QC x -> return $ \ svs -> VCApp x (map ($svs) vs) +{- + Q x@(m,f) | m==cPredef -> return $ + let constr = --trace ("predef "++show x) . + VApp x + in \ svs -> maybe constr id (Map.lookup f predefs) + $ map ($svs) vs + | otherwise -> do r <- resource env x + return $ \ svs -> vapply (gloc env) r (map ($svs) vs) +-} + App t1 t2 -> apply' env t1 . (:vs) =<< value env t2 + _ -> do fv <- value env t + return $ \ svs -> vapply (gloc env) (fv svs) (map ($svs) vs) + +vapply :: GLocation -> Value -> [Value] -> Value +vapply loc v [] = v +vapply loc v vs = + case v of + VError {} -> v +-- VClosure env (Abs b x t) -> beta gr env b x t vs + VAbs bt _ (Bind f) -> vbeta loc bt f vs + VApp pre vs1 -> delta' pre (vs1++vs) + where + delta' Trace (v1:v2:vs) = let vr = vapply loc v2 vs + in vtrace loc v1 vr + delta' pre vs = err msg vfv $ mapM (delta pre) (varyList vs) + --msg = const (VApp pre (vs1++vs)) + msg = bug . (("Applying Predef."++showIdent (predefName pre)++": ")++) + VS (VV t pvs fs) s -> VS (VV t pvs [vapply loc f vs|f<-fs]) s + VFV fs -> vfv [vapply loc f vs|f<-fs] + VCApp f vs0 -> VCApp f (vs0++vs) + VMeta i env vs0 -> VMeta i env (vs0++vs) + VGen i vs0 -> VGen i (vs0++vs) + v -> bug $ "vapply "++show v++" "++show vs + +vbeta loc bt f (v:vs) = + case (bt,v) of + (Implicit,VImplArg v) -> ap v + (Explicit, v) -> ap v + where + ap (VFV avs) = vfv [vapply loc (f v) vs|v<-avs] + ap v = vapply loc (f v) vs + +vary (VFV vs) = vs +vary v = [v] +varyList = mapM vary + +{- +beta env b x t (v:vs) = + case (b,v) of + (Implicit,VImplArg v) -> apply' (ext (x,v) env) t vs + (Explicit, v) -> apply' (ext (x,v) env) t vs +-} + +vtrace loc arg res = trace (render (hang (pv arg) 4 ("->"<+>pv res))) res + where + pv v = case v of + VRec (f:as) -> hang (pf f) 4 (fsep (map pa as)) + _ -> ppV v + pf (_,VString n) = pp n + pf (_,v) = ppV v + pa (_,v) = ppV v + ppV v = case value2term' True loc [] v of + Left i -> "variable #" <> pp i <+> "is out of scope" + Right t -> ppTerm Unqualified 10 t + +-- | Convert a value back to a term +value2term :: GLocation -> [Ident] -> Value -> Either Int Term +value2term = value2term' False +value2term' stop loc xs v0 = + case v0 of + VApp pre vs -> liftM (foldl App (Q (cPredef,predefName pre))) (mapM v2t vs) + VCApp f vs -> liftM (foldl App (QC f)) (mapM v2t vs) + VGen j vs -> liftM2 (foldl App) (var j) (mapM v2t vs) + VMeta j env vs -> liftM (foldl App (Meta j)) (mapM v2t vs) + VProd bt v x f -> liftM2 (Prod bt x) (v2t v) (v2t' x f) + VAbs bt x f -> liftM (Abs bt x) (v2t' x f) + VInt n -> return (EInt n) + VFloat f -> return (EFloat f) + VString s -> return (if null s then Empty else K s) + VSort s -> return (Sort s) + VImplArg v -> liftM ImplArg (v2t v) + VTblType p res -> liftM2 Table (v2t p) (v2t res) + VRecType rs -> liftM RecType (mapM (\(l,v) -> fmap ((,) l) (v2t v)) rs) + VRec as -> liftM R (mapM (\(l,v) -> v2t v >>= \t -> return (l,(Nothing,t))) as) + VV t _ vs -> liftM (V t) (mapM v2t vs) + VT wild v cs -> v2t v >>= \t -> liftM (T ((if wild then TWild else TTyped) t)) (mapM nfcase cs) + VFV vs -> liftM FV (mapM v2t vs) + VC v1 v2 -> liftM2 C (v2t v1) (v2t v2) + VS v1 v2 -> liftM2 S (v2t v1) (v2t v2) + VP v l -> v2t v >>= \t -> return (P t l) + VPatt p -> return (EPatt p) + VPattType v -> v2t v >>= return . EPattType + VAlts v vvs -> liftM2 Alts (v2t v) (mapM (\(x,y) -> liftM2 (,) (v2t x) (v2t y)) vvs) + VStrs vs -> liftM Strs (mapM v2t vs) +-- VGlue v1 v2 -> Glue (v2t v1) (v2t v2) +-- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2) + VError err -> return (Error err) + + where + v2t = v2txs xs + v2txs = value2term' stop loc + v2t' x f = v2txs (x:xs) (bind f (gen xs)) + + var j + | j [i] + PAs i p -> i:allPattVars p + _ -> collectPattOp allPattVars p + +--- +ix loc fn xs i = + if i)) -- GHC 8.4.1 clash with Text.PrettyPrint - -import GF.Grammar hiding (Env, VGen, VApp, VRecType) -import GF.Grammar.Lookup(lookupResDefLoc,allParamValues) -import GF.Grammar.Predef(cPredef,cErrorType,cTok,cStr,cTrace,cPBool) -import GF.Grammar.PatternMatch(matchPattern,measurePatt) -import GF.Grammar.Lockfield(isLockLabel,lockRecType) --unlockRecord,lockLabel -import GF.Compile.Compute.Value hiding (Error) -import GF.Compile.Compute.Predef(predef,predefName,delta) -import GF.Data.Str(Str,glueStr,str2strings,str,sstr,plusStr,strTok) -import GF.Data.Operations(Err,err,errIn,maybeErr,mapPairsM) -import GF.Data.Utilities(mapFst,mapSnd) -import GF.Infra.Option -import Control.Monad(ap,liftM,liftM2) -- ,unless,mplus -import Data.List (findIndex,intersect,nub,elemIndex,(\\)) --,isInfixOf ---import Data.Char (isUpper,toUpper,toLower) -import GF.Text.Pretty -import qualified Data.Map as Map -import Debug.Trace(trace) - --- * Main entry points - -normalForm :: GlobalEnv -> L Ident -> Term -> Term -normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc) - -nfx env@(GE _ _ _ loc) t = do - v <- eval env [] t - case value2term loc [] v of - Left i -> fail ("variable #"++show i++" is out of scope") - Right t -> return t - -eval :: GlobalEnv -> Env -> Term -> Err Value -eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t - where - cenv = CE gr rvs opts loc (map fst env) - ---apply env = apply' env - --------------------------------------------------------------------------------- - --- * Environments - -type ResourceValues = Map.Map ModuleName (Map.Map Ident (Err Value)) - -data GlobalEnv = GE Grammar ResourceValues Options GLocation -data CompleteEnv = CE {srcgr::Grammar,rvs::ResourceValues, - opts::Options, - gloc::GLocation,local::LocalScope} -type GLocation = L Ident -type LocalScope = [Ident] -type Stack = [Value] -type OpenValue = Stack->Value - -geLoc (GE _ _ _ loc) = loc -geGrammar (GE gr _ _ _) = gr - -ext b env = env{local=b:local env} -extend bs env = env{local=bs++local env} -global env = GE (srcgr env) (rvs env) (opts env) (gloc env) - -var :: CompleteEnv -> Ident -> Err OpenValue -var env x = maybe unbound pick' (elemIndex x (local env)) - where - unbound = fail ("Unknown variable: "++showIdent x) - pick' i = return $ \ vs -> maybe (err i vs) ok (pick i vs) - err i vs = bug $ "Stack problem: "++showIdent x++": " - ++unwords (map showIdent (local env)) - ++" => "++show (i,length vs) - ok v = --trace ("var "++show x++" = "++show v) $ - v - -pick :: Int -> Stack -> Maybe Value -pick 0 (v:_) = Just v -pick i (_:vs) = pick (i-1) vs -pick i vs = Nothing -- bug $ "pick "++show (i,vs) - -resource env (m,c) = --- err bug id $ - if isPredefCat c - then value0 env =<< lockRecType c defLinType -- hmm - else maybe e id $ Map.lookup c =<< Map.lookup m (rvs env) - where e = fail $ "Not found: "++render m++"."++showIdent c - --- | Convert operators once, not every time they are looked up -resourceValues :: Options -> SourceGrammar -> GlobalEnv -resourceValues opts gr = env - where - env = GE gr rvs opts (L NoLoc identW) - rvs = Map.mapWithKey moduleResources (moduleMap gr) - moduleResources m = Map.mapWithKey (moduleResource m) . jments - moduleResource m c _info = do L l t <- lookupResDefLoc gr (m,c) - let loc = L l c - qloc = L l (Q (m,c)) - eval (GE gr rvs opts loc) [] (traceRes qloc t) - - traceRes = if flag optTrace opts - then traceResource - else const id - --- * Tracing - --- | Insert a call to the trace function under the top-level lambdas -traceResource (L l q) t = - case termFormCnc t of - (abs,body) -> mkAbs abs (mkApp traceQ [args,body]) - where - args = R $ tuple2record (K lstr:[Vr x|(bt,x)<-abs,bt==Explicit]) - lstr = render (l<>":"<>ppTerm Qualified 0 q) - traceQ = Q (cPredef,cTrace) - --- * Computing values - --- | Computing the value of a top-level term -value0 :: CompleteEnv -> Term -> Err Value -value0 env = eval (global env) [] - --- | Computing the value of a term -value :: CompleteEnv -> Term -> Err OpenValue -value env t0 = - -- Each terms is traversed only once by this function, using only statically - -- available information. Notably, the values of lambda bound variables - -- will be unknown during the term traversal phase. - -- The result is an OpenValue, which is a function that may be applied many - -- times to different dynamic values, but without the term traversal overhead - -- and without recomputing other statically known information. - -- For this to work, there should be no recursive calls under lambdas here. - -- Whenever we need to construct the OpenValue function with an explicit - -- lambda, we have to lift the recursive calls outside the lambda. - -- (See e.g. the rules for Let, Prod and Abs) -{- - trace (render $ text "value"<+>sep [ppL (gloc env)<>text ":", - brackets (fsep (map ppIdent (local env))), - ppTerm Unqualified 10 t0]) $ ---} - errIn (render t0) $ - case t0 of - Vr x -> var env x - Q x@(m,f) - | m == cPredef -> if f==cErrorType -- to be removed - then let p = identS "P" - in const # value0 env (mkProd [(Implicit,p,typeType)] (Vr p) []) - else if f==cPBool - then const # resource env x - else const . flip VApp [] # predef f - | otherwise -> const # resource env x --valueResDef (fst env) x - QC x -> return $ const (VCApp x []) - App e1 e2 -> apply' env e1 . (:[]) =<< value env e2 - Let (x,(oty,t)) body -> do vb <- value (ext x env) body - vt <- value env t - return $ \ vs -> vb (vt vs:vs) - Meta i -> return $ \ vs -> VMeta i (zip (local env) vs) [] - Prod bt x t1 t2 -> - do vt1 <- value env t1 - vt2 <- value (ext x env) t2 - return $ \ vs -> VProd bt (vt1 vs) x $ Bind $ \ vx -> vt2 (vx:vs) - Abs bt x t -> do vt <- value (ext x env) t - return $ VAbs bt x . Bind . \ vs vx -> vt (vx:vs) - EInt n -> return $ const (VInt n) - EFloat f -> return $ const (VFloat f) - K s -> return $ const (VString s) - Empty -> return $ const (VString "") - Sort s | s == cTok -> return $ const (VSort cStr) -- to be removed - | otherwise -> return $ const (VSort s) - ImplArg t -> (VImplArg.) # value env t - Table p res -> liftM2 VTblType # value env p <# value env res - RecType rs -> do lovs <- mapPairsM (value env) rs - return $ \vs->VRecType $ mapSnd ($vs) lovs - t@(ExtR t1 t2) -> ((extR t.)# both id) # both (value env) (t1,t2) - FV ts -> ((vfv .) # sequence) # mapM (value env) ts - R as -> do lovs <- mapPairsM (value env.snd) as - return $ \ vs->VRec $ mapSnd ($vs) lovs - T i cs -> valueTable env i cs - V ty ts -> do pvs <- paramValues env ty - ((VV ty pvs .) . sequence) # mapM (value env) ts - C t1 t2 -> ((ok2p vconcat.) # both id) # both (value env) (t1,t2) - S t1 t2 -> ((select env.) # both id) # both (value env) (t1,t2) - P t l -> --maybe (bug $ "project "++show l++" from "++show v) id $ - do ov <- value env t - return $ \ vs -> let v = ov vs - in maybe (VP v l) id (proj l v) - Alts t tts -> (\v vts -> VAlts # v <# mapM (both id) vts) # value env t <# mapM (both (value env)) tts - Strs ts -> ((VStrs.) # sequence) # mapM (value env) ts - Glue t1 t2 -> ((ok2p (glue env).) # both id) # both (value env) (t1,t2) - ELin c r -> (unlockVRec (gloc env) c.) # value env r - EPatt p -> return $ const (VPatt p) -- hmm - EPattType ty -> do vt <- value env ty - return (VPattType . vt) - Typed t ty -> value env t - t -> fail.render $ "value"<+>ppTerm Unqualified 10 t $$ show t - -vconcat vv@(v1,v2) = - case vv of - (VString "",_) -> v2 - (_,VString "") -> v1 - (VApp NonExist _,_) -> v1 - (_,VApp NonExist _) -> v2 - _ -> VC v1 v2 - -proj l v | isLockLabel l = return (VRec []) - ---- a workaround 18/2/2005: take this away and find the reason - ---- why earlier compilation destroys the lock field -proj l v = - case v of - VFV vs -> liftM vfv (mapM (proj l) vs) - VRec rs -> lookup l rs --- VExtR v1 v2 -> proj l v2 `mplus` proj l v1 -- hmm - VS (VV pty pvs rs) v2 -> flip VS v2 . VV pty pvs # mapM (proj l) rs - _ -> return (ok1 VP v l) - -ok1 f v1@(VError {}) _ = v1 -ok1 f v1 v2 = f v1 v2 - -ok2 f v1@(VError {}) _ = v1 -ok2 f _ v2@(VError {}) = v2 -ok2 f v1 v2 = f v1 v2 - -ok2p f (v1@VError {},_) = v1 -ok2p f (_,v2@VError {}) = v2 -ok2p f vv = f vv - -unlockVRec loc c0 v0 = v0 -{- -unlockVRec loc c0 v0 = unlockVRec' c0 v0 - where - unlockVRec' ::Ident -> Value -> Value - unlockVRec' c v = - case v of - -- VClosure env t -> err bug (VClosure env) (unlockRecord c t) - VAbs bt x (Bind f) -> VAbs bt x (Bind $ \ v -> unlockVRec' c (f v)) - VRec rs -> plusVRec rs lock - -- _ -> VExtR v (VRec lock) -- hmm - _ -> {-trace (render $ ppL loc $ "unlock non-record "++show v0)-} v -- hmm - -- _ -> bugloc loc $ "unlock non-record "++show v0 - where - lock = [(lockLabel c,VRec [])] --} - --- suspicious, but backwards compatible -plusVRec rs1 rs2 = VRec ([(l,v)|(l,v)<-rs1,l `notElem` ls2] ++ rs2) - where ls2 = map fst rs2 - -extR t vv = - case vv of - (VFV vs,v2) -> vfv [extR t (v1,v2)|v1<-vs] - (v1,VFV vs) -> vfv [extR t (v1,v2)|v2<-vs] - (VRecType rs1, VRecType rs2) -> - case intersect (map fst rs1) (map fst rs2) of - [] -> VRecType (rs1 ++ rs2) - ls -> error $ "clash"<+>show ls - (VRec rs1, VRec rs2) -> plusVRec rs1 rs2 - (v1 , VRec [(l,_)]) | isLockLabel l -> v1 -- hmm - (VS (VV t pvs vs) s,v2) -> VS (VV t pvs [extR t (v1,v2)|v1<-vs]) s --- (v1,v2) -> ok2 VExtR v1 v2 -- hmm - (v1,v2) -> error $ "not records" $$ show v1 $$ show v2 - where - error explain = ppbug $ "The term" <+> t - <+> "is not reducible" $$ explain - -glue env (v1,v2) = glu v1 v2 - where - glu v1 v2 = - case (v1,v2) of - (VFV vs,v2) -> vfv [glu v1 v2|v1<-vs] - (v1,VFV vs) -> vfv [glu v1 v2|v2<-vs] - (VString s1,VString s2) -> VString (s1++s2) - (v1,VAlts d vs) -> VAlts (glx d) [(glx v,c) | (v,c) <- vs] - where glx v2 = glu v1 v2 - (v1@(VAlts {}),v2) -> - --err (const (ok2 VGlue v1 v2)) id $ - err bug id $ - do y' <- strsFromValue v2 - x' <- strsFromValue v1 - return $ vfv [foldr1 VC (map VString (str2strings (glueStr v u))) | v <- x', u <- y'] - (VC va vb,v2) -> VC va (glu vb v2) - (v1,VC va vb) -> VC (glu v1 va) vb - (VS (VV ty pvs vs) vb,v2) -> VS (VV ty pvs [glu v v2|v<-vs]) vb - (v1,VS (VV ty pvs vs) vb) -> VS (VV ty pvs [glu v1 v|v<-vs]) vb - (v1@(VApp NonExist _),_) -> v1 - (_,v2@(VApp NonExist _)) -> v2 --- (v1,v2) -> ok2 VGlue v1 v2 - (v1,v2) -> if flag optPlusAsBind (opts env) - then VC v1 (VC (VApp BIND []) v2) - else let loc = gloc env - vt v = case value2term loc (local env) v of - Left i -> Error ('#':show i) - Right t -> t - originalMsg = render $ ppL loc (hang "unsupported token gluing" 4 - (Glue (vt v1) (vt v2))) - term = render $ pp $ Glue (vt v1) (vt v2) - in error $ unlines - [originalMsg - ,"" - ,"There was a problem in the expression `"++term++"`, either:" - ,"1) You are trying to use + on runtime arguments, possibly via an oper." - ,"2) One of the arguments in `"++term++"` is a bound variable from pattern matching a string, but the cases are non-exhaustive." - ,"For more help see https://github.com/GrammaticalFramework/gf-core/tree/master/doc/errors/gluing.md" - ] - - --- | to get a string from a value that represents a sequence of terminals -strsFromValue :: Value -> Err [Str] -strsFromValue t = case t of - VString s -> return [str s] - VC s t -> do - s' <- strsFromValue s - t' <- strsFromValue t - return [plusStr x y | x <- s', y <- t'] -{- - VGlue s t -> do - s' <- strsFromValue s - t' <- strsFromValue t - return [glueStr x y | x <- s', y <- t'] --} - VAlts d vs -> do - d0 <- strsFromValue d - v0 <- mapM (strsFromValue . fst) vs - c0 <- mapM (strsFromValue . snd) vs - --let vs' = zip v0 c0 - return [strTok (str2strings def) vars | - def <- d0, - vars <- [[(str2strings v, map sstr c) | (v,c) <- zip vv c0] | - vv <- sequence v0] - ] - VFV ts -> concat # mapM strsFromValue ts - VStrs ts -> concat # mapM strsFromValue ts - - _ -> fail ("cannot get Str from value " ++ show t) - -vfv vs = case nub vs of - [v] -> v - vs -> VFV vs - -select env vv = - case vv of - (v1,VFV vs) -> vfv [select env (v1,v2)|v2<-vs] - (VFV vs,v2) -> vfv [select env (v1,v2)|v1<-vs] - (v1@(VV pty vs rs),v2) -> - err (const (VS v1 v2)) id $ - do --ats <- allParamValues (srcgr env) pty - --let vs = map (value0 env) ats - i <- maybeErr "no match" $ findIndex (==v2) vs - return (ix (gloc env) "select" rs i) - (VT _ _ [(PW,Bind b)],_) -> {-trace "eliminate wild card table" $-} b [] - (v1@(VT _ _ cs),v2) -> - err (\_->ok2 VS v1 v2) (err bug id . valueMatch env) $ - match (gloc env) cs v2 - (VS (VV pty pvs rs) v12,v2) -> VS (VV pty pvs [select env (v11,v2)|v11<-rs]) v12 - (v1,v2) -> ok2 VS v1 v2 - -match loc cs v = - case value2term loc [] v of - Left i -> bad ("variable #"++show i++" is out of scope") - Right t -> err bad return (matchPattern cs t) - where - bad = fail . ("In pattern matching: "++) - -valueMatch :: CompleteEnv -> (Bind Env,Substitution) -> Err Value -valueMatch env (Bind f,env') = f # mapPairsM (value0 env) env' - -valueTable :: CompleteEnv -> TInfo -> [Case] -> Err OpenValue -valueTable env i cs = - case i of - TComp ty -> do pvs <- paramValues env ty - ((VV ty pvs .) # sequence) # mapM (value env.snd) cs - _ -> do ty <- getTableType i - cs' <- mapM valueCase cs - err (dynamic cs' ty) return (convert cs' ty) - where - dynamic cs' ty _ = cases cs' # value env ty - - cases cs' vty vs = err keep ($vs) (convertv cs' (vty vs)) - where - keep msg = --trace (msg++"\n"++render (ppTerm Unqualified 0 (T i cs))) $ - VT wild (vty vs) (mapSnd ($vs) cs') - - wild = case i of TWild _ -> True; _ -> False - - convertv cs' vty = - case value2term (gloc env) [] vty of - 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' ((pty,vs),pvs) = - do sts <- mapM (matchPattern cs') vs - return $ \ vs -> VV pty pvs $ map (err bug id . valueMatch env) - (mapFst ($vs) sts) - - valueCase (p,t) = do p' <- measurePatt # inlinePattMacro p - pvs <- linPattVars p' - vt <- value (extend pvs env) t - return (p',\vs-> Bind $ \bs-> vt (push' p' bs pvs vs)) - - inlinePattMacro p = - case p of - PM qc -> do r <- resource env qc - case r of - VPatt p' -> inlinePattMacro p' - _ -> ppbug $ hang "Expected pattern macro:" 4 - (show r) - _ -> composPattOp inlinePattMacro p - - -paramValues env ty = snd # paramValues' env ty - -paramValues' env ty = paramValues'' env =<< nfx (global env) ty - -paramValues'' env pty = do ats <- allParamValues (srcgr env) pty - pvs <- mapM (eval (global env) []) ats - return ((pty,ats),pvs) - -push' p bs xs = if length bs/=length xs - then bug $ "push "++show (p,bs,xs) - else push bs xs - -push :: Env -> LocalScope -> Stack -> Stack -push bs [] vs = vs -push bs (x:xs) vs = maybe err id (lookup x bs):push bs xs vs - where err = bug $ "Unbound pattern variable "++showIdent x - -apply' :: CompleteEnv -> Term -> [OpenValue] -> Err OpenValue -apply' env t [] = value env t -apply' env t vs = - case t of - QC x -> return $ \ svs -> VCApp x (map ($svs) vs) -{- - Q x@(m,f) | m==cPredef -> return $ - let constr = --trace ("predef "++show x) . - VApp x - in \ svs -> maybe constr id (Map.lookup f predefs) - $ map ($svs) vs - | otherwise -> do r <- resource env x - return $ \ svs -> vapply (gloc env) r (map ($svs) vs) --} - App t1 t2 -> apply' env t1 . (:vs) =<< value env t2 - _ -> do fv <- value env t - return $ \ svs -> vapply (gloc env) (fv svs) (map ($svs) vs) - -vapply :: GLocation -> Value -> [Value] -> Value -vapply loc v [] = v -vapply loc v vs = - case v of - VError {} -> v --- VClosure env (Abs b x t) -> beta gr env b x t vs - VAbs bt _ (Bind f) -> vbeta loc bt f vs - VApp pre vs1 -> delta' pre (vs1++vs) - where - delta' Trace (v1:v2:vs) = let vr = vapply loc v2 vs - in vtrace loc v1 vr - delta' pre vs = err msg vfv $ mapM (delta pre) (varyList vs) - --msg = const (VApp pre (vs1++vs)) - msg = bug . (("Applying Predef."++showIdent (predefName pre)++": ")++) - VS (VV t pvs fs) s -> VS (VV t pvs [vapply loc f vs|f<-fs]) s - VFV fs -> vfv [vapply loc f vs|f<-fs] - VCApp f vs0 -> VCApp f (vs0++vs) - VMeta i env vs0 -> VMeta i env (vs0++vs) - VGen i vs0 -> VGen i (vs0++vs) - v -> bug $ "vapply "++show v++" "++show vs - -vbeta loc bt f (v:vs) = - case (bt,v) of - (Implicit,VImplArg v) -> ap v - (Explicit, v) -> ap v - where - ap (VFV avs) = vfv [vapply loc (f v) vs|v<-avs] - ap v = vapply loc (f v) vs - -vary (VFV vs) = vs -vary v = [v] -varyList = mapM vary - -{- -beta env b x t (v:vs) = - case (b,v) of - (Implicit,VImplArg v) -> apply' (ext (x,v) env) t vs - (Explicit, v) -> apply' (ext (x,v) env) t vs --} - -vtrace loc arg res = trace (render (hang (pv arg) 4 ("->"<+>pv res))) res - where - pv v = case v of - VRec (f:as) -> hang (pf f) 4 (fsep (map pa as)) - _ -> ppV v - pf (_,VString n) = pp n - pf (_,v) = ppV v - pa (_,v) = ppV v - ppV v = case value2term' True loc [] v of - Left i -> "variable #" <> pp i <+> "is out of scope" - Right t -> ppTerm Unqualified 10 t - --- | Convert a value back to a term -value2term :: GLocation -> [Ident] -> Value -> Either Int Term -value2term = value2term' False -value2term' stop loc xs v0 = - case v0 of - VApp pre vs -> liftM (foldl App (Q (cPredef,predefName pre))) (mapM v2t vs) - VCApp f vs -> liftM (foldl App (QC f)) (mapM v2t vs) - VGen j vs -> liftM2 (foldl App) (var j) (mapM v2t vs) - VMeta j env vs -> liftM (foldl App (Meta j)) (mapM v2t vs) - VProd bt v x f -> liftM2 (Prod bt x) (v2t v) (v2t' x f) - VAbs bt x f -> liftM (Abs bt x) (v2t' x f) - VInt n -> return (EInt n) - VFloat f -> return (EFloat f) - VString s -> return (if null s then Empty else K s) - VSort s -> return (Sort s) - VImplArg v -> liftM ImplArg (v2t v) - VTblType p res -> liftM2 Table (v2t p) (v2t res) - VRecType rs -> liftM RecType (mapM (\(l,v) -> fmap ((,) l) (v2t v)) rs) - VRec as -> liftM R (mapM (\(l,v) -> v2t v >>= \t -> return (l,(Nothing,t))) as) - VV t _ vs -> liftM (V t) (mapM v2t vs) - VT wild v cs -> v2t v >>= \t -> liftM (T ((if wild then TWild else TTyped) t)) (mapM nfcase cs) - VFV vs -> liftM FV (mapM v2t vs) - VC v1 v2 -> liftM2 C (v2t v1) (v2t v2) - VS v1 v2 -> liftM2 S (v2t v1) (v2t v2) - VP v l -> v2t v >>= \t -> return (P t l) - VPatt p -> return (EPatt p) - VPattType v -> v2t v >>= return . EPattType - VAlts v vvs -> liftM2 Alts (v2t v) (mapM (\(x,y) -> liftM2 (,) (v2t x) (v2t y)) vvs) - VStrs vs -> liftM Strs (mapM v2t vs) --- VGlue v1 v2 -> Glue (v2t v1) (v2t v2) --- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2) - VError err -> return (Error err) - - where - v2t = v2txs xs - v2txs = value2term' stop loc - v2t' x f = v2txs (x:xs) (bind f (gen xs)) - - var j - | j [i] - PAs i p -> i:allPattVars p - _ -> collectPattOp allPattVars p - ---- -ix loc fn xs i = - if i Type -> Int -> CncCat pgfCncCat gr lincat index = let ((_,size),schema) = computeCatRange gr lincat in PGF.CncCat index (index+size-1) - (mkArray (map (renderStyle style{mode=OneLineMode} . ppPath) + (mkArray (map (renderStyle style{mode=OneLineMode} . ppPath) (getStrPaths schema))) where getStrPaths :: Schema Identity s c -> [Path] @@ -243,7 +243,7 @@ choices nr path = do (args,_) <- get | (value,index) <- values]) descend schema path rpath = bug $ "descend "++show (schema,path,rpath) - updateEnv path value gr c (args,seq) = + updateEnv path value gr c (args,seq) = case updateNthM (restrictProtoFCat path value) nr args of Just args -> c value (args,seq) Nothing -> bug "conflict in updateEnv" @@ -606,7 +606,7 @@ restrictProtoFCat path v (PFCat cat f schema) = do Just index -> return (CPar (m,[(v,index)])) Nothing -> mzero addConstraint CNil v (CStr _) = bug "restrictProtoFCat: string path" - + update k0 f [] = return [] update k0 f (x@(k,Identity v):xs) | k0 == k = do v <- f v diff --git a/src/compiler/GF/Compile/GrammarToCanonical.hs b/src/compiler/GF/Compile/GrammarToCanonical.hs index 33f35ad08..d43256177 100644 --- a/src/compiler/GF/Compile/GrammarToCanonical.hs +++ b/src/compiler/GF/Compile/GrammarToCanonical.hs @@ -19,7 +19,7 @@ import GF.Compile.Compute.Value(Predefined(..)) import GF.Infra.Ident(ModuleName(..),Ident,prefixIdent,showIdent,isWildIdent) import GF.Infra.Option(optionsPGF) import PGF.Internal(Literal(..)) -import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues) +import GF.Compile.Compute.Concrete(normalForm,resourceValues) import GF.Grammar.Canonical as C import Debug.Trace @@ -72,7 +72,7 @@ concrete2canonical gr cenv absname cnc modinfo = [lincat|(_,Left lincat)<-defs] [lin|(_,Right lin)<-defs] where - defs = concatMap (toCanonical gr absname cenv) . + defs = concatMap (toCanonical gr absname cenv) . M.toList $ jments modinfo @@ -189,7 +189,7 @@ convert' gr vs = ppT _ -> VarValue (gQId cPredef n) -- hmm where p = PredefValue . PredefId - + ppP p = case p of PC c ps -> ParamPattern (Param (gId c) (map ppP ps)) diff --git a/src/compiler/GF/Compile/Optimize.hs b/src/compiler/GF/Compile/Optimize.hs index 393deb020..ac3fa357c 100644 --- a/src/compiler/GF/Compile/Optimize.hs +++ b/src/compiler/GF/Compile/Optimize.hs @@ -6,7 +6,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/09/16 13:56:13 $ +-- > CVS $Date: 2005/09/16 13:56:13 $ -- > CVS $Author: aarne $ -- > CVS $Revision: 1.18 $ -- @@ -21,7 +21,7 @@ import GF.Grammar.Printer import GF.Grammar.Macros import GF.Grammar.Lookup import GF.Grammar.Predef -import GF.Compile.Compute.ConcreteNew(GlobalEnv,normalForm,resourceValues) +import GF.Compile.Compute.Concrete(GlobalEnv,normalForm,resourceValues) import GF.Data.Operations import GF.Infra.Option @@ -90,7 +90,7 @@ evalInfo opts resenv sgr m c info = do let ppr' = fmap (evalPrintname resenv c) ppr return $ CncFun mt pde' ppr' mpmcfg -- only cat in type actually needed {- - ResOper pty pde + ResOper pty pde | not new && OptExpand `Set.member` optim -> do pde' <- case pde of Just (L loc de) -> do de <- computeConcrete gr de @@ -171,13 +171,13 @@ mkLinDefault gr typ = liftM (Abs Explicit varStr) $ mkDefField typ _ -> Bad (render ("linearization type field cannot be" <+> typ)) mkLinReference :: SourceGrammar -> Type -> Err Term -mkLinReference gr typ = - liftM (Abs Explicit varStr) $ +mkLinReference gr typ = + liftM (Abs Explicit varStr) $ case mkDefField typ (Vr varStr) of Bad "no string" -> return Empty x -> x where - mkDefField ty trm = + mkDefField ty trm = case ty of Table pty ty -> do ps <- allParamValues gr pty case ps of @@ -203,7 +203,7 @@ factor param c i t = T (TComp ty) cs -> factors ty [(p, factor param c (i+1) v) | (p, v) <- cs] _ -> composSafeOp (factor param c i) t where - factors ty pvs0 + factors ty pvs0 | not param = V ty (map snd pvs0) factors ty [] = V ty [] factors ty pvs0@[(p,v)] = V ty [v] @@ -224,7 +224,7 @@ factor param c i t = replace :: Term -> Term -> Term -> Term replace old new trm = case trm of - -- these are the important cases, since they can correspond to patterns + -- these are the important cases, since they can correspond to patterns QC _ | trm == old -> new App _ _ | trm == old -> new R _ | trm == old -> new diff --git a/src/compiler/GF/Compile/TypeCheck/ConcreteNew.hs b/src/compiler/GF/Compile/TypeCheck/ConcreteNew.hs index b35aaf9ed..c32afa7a5 100644 --- a/src/compiler/GF/Compile/TypeCheck/ConcreteNew.hs +++ b/src/compiler/GF/Compile/TypeCheck/ConcreteNew.hs @@ -10,7 +10,7 @@ import GF.Grammar hiding (Env, VGen, VApp, VRecType) import GF.Grammar.Lookup import GF.Grammar.Predef import GF.Grammar.Lockfield -import GF.Compile.Compute.ConcreteNew +import GF.Compile.Compute.Concrete import GF.Compile.Compute.Predef(predef,predefName) import GF.Infra.CheckM import GF.Data.Operations @@ -133,7 +133,7 @@ tcRho ge scope t@(RecType rs) (Just ty) = do [] -> unifyVar ge scope i env vs vtypePType _ -> return () ty -> do ty <- zonkTerm =<< tc_value2term (geLoc ge) (scopeVars scope) ty - tcError ("The record type" <+> ppTerm Unqualified 0 t $$ + tcError ("The record type" <+> ppTerm Unqualified 0 t $$ "cannot be of type" <+> ppTerm Unqualified 0 ty) (rs,mb_ty) <- tcRecTypeFields ge scope rs (Just ty') return (f (RecType rs),ty) @@ -187,7 +187,7 @@ tcRho ge scope (R rs) (Just ty) = do case ty' of (VRecType ltys) -> do lttys <- checkRecFields ge scope rs ltys rs <- mapM (\(l,t,ty) -> tc_value2term (geLoc ge) (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys - return ((f . R) rs, + return ((f . R) rs, VRecType [(l, ty) | (l,t,ty) <- lttys] ) ty -> do lttys <- inferRecFields ge scope rs @@ -277,11 +277,11 @@ tcApp ge scope (App fun arg) = -- APP2 varg <- liftErr (eval ge (scopeEnv scope) arg) return (App fun arg, res_ty varg) tcApp ge scope (Q id) = -- VAR (global) - mkTcA (lookupOverloadTypes (geGrammar ge) id) `bindTcA` \(t,ty) -> + mkTcA (lookupOverloadTypes (geGrammar ge) id) `bindTcA` \(t,ty) -> do ty <- liftErr (eval ge [] ty) return (t,ty) tcApp ge scope (QC id) = -- VAR (global) - mkTcA (lookupOverloadTypes (geGrammar ge) id) `bindTcA` \(t,ty) -> + mkTcA (lookupOverloadTypes (geGrammar ge) id) `bindTcA` \(t,ty) -> do ty <- liftErr (eval ge [] ty) return (t,ty) tcApp ge scope t = @@ -350,7 +350,7 @@ tcPatt ge scope (PM q) ty0 = do Bad err -> tcError (pp err) tcPatt ge scope p ty = unimplemented ("tcPatt "++show p) -inferRecFields ge scope rs = +inferRecFields ge scope rs = mapM (\(l,r) -> tcRecField ge scope l r Nothing) rs checkRecFields ge scope [] ltys @@ -368,7 +368,7 @@ checkRecFields ge scope ((l,t):lts) ltys = where takeIt l1 [] = (Nothing, []) takeIt l1 (lty@(l2,ty):ltys) - | l1 == l2 = (Just ty,ltys) + | l1 == l2 = (Just ty,ltys) | otherwise = let (mb_ty,ltys') = takeIt l1 ltys in (mb_ty,lty:ltys') @@ -390,7 +390,7 @@ tcRecTypeFields ge scope ((l,ty):rs) mb_ty = do | s == cPType -> return mb_ty VMeta _ _ _ -> return mb_ty _ -> do sort <- zonkTerm =<< tc_value2term (geLoc ge) (scopeVars scope) sort - tcError ("The record type field" <+> l <+> ':' <+> ppTerm Unqualified 0 ty $$ + tcError ("The record type field" <+> l <+> ':' <+> ppTerm Unqualified 0 ty $$ "cannot be of type" <+> ppTerm Unqualified 0 sort) (rs,mb_ty) <- tcRecTypeFields ge scope rs mb_ty return ((l,ty):rs,mb_ty) @@ -444,11 +444,11 @@ subsCheckRho ge scope t (VApp p1 _) (VApp p2 _) -- Rule | predefName p1 == cInts && predefName p2 == cInt = return t subsCheckRho ge scope t (VApp p1 [VInt i]) (VApp p2 [VInt j]) -- Rule INT2 | predefName p1 == cInts && predefName p2 == cInts = - if i <= j + if i <= j then return t else tcError ("Ints" <+> i <+> "is not a subtype of" <+> "Ints" <+> j) subsCheckRho ge scope t ty1@(VRecType rs1) ty2@(VRecType rs2) = do -- Rule REC - let mkAccess scope t = + let mkAccess scope t = case t of ExtR t1 t2 -> do (scope,mkProj1,mkWrap1) <- mkAccess scope t1 (scope,mkProj2,mkWrap2) <- mkAccess scope t2 @@ -557,7 +557,7 @@ unify ge scope v (VMeta i env vs) = unifyVar ge scope i env vs v unify ge scope v1 v2 = do t1 <- zonkTerm =<< tc_value2term (geLoc ge) (scopeVars scope) v1 t2 <- zonkTerm =<< tc_value2term (geLoc ge) (scopeVars scope) v2 - tcError ("Cannot unify terms:" <+> (ppTerm Unqualified 0 t1 $$ + tcError ("Cannot unify terms:" <+> (ppTerm Unqualified 0 t1 $$ ppTerm Unqualified 0 t2)) -- | Invariant: tv1 is a flexible type variable @@ -609,7 +609,7 @@ quantify ge scope t tvs ty0 = do ty <- tc_value2term (geLoc ge) (scopeVars scope) ty0 let used_bndrs = nub (bndrs ty) -- Avoid quantified type variables in use new_bndrs = take (length tvs) (allBinders \\ used_bndrs) - mapM_ bind (tvs `zip` new_bndrs) -- 'bind' is just a cunning way + mapM_ bind (tvs `zip` new_bndrs) -- 'bind' is just a cunning way ty <- zonkTerm ty -- of doing the substitution vty <- liftErr (eval ge [] (foldr (\v ty -> Prod Implicit v typeType ty) ty new_bndrs)) return (foldr (Abs Implicit) t new_bndrs,vty) @@ -619,7 +619,7 @@ quantify ge scope t tvs ty0 = do bndrs (Prod _ x t1 t2) = [x] ++ bndrs t1 ++ bndrs t2 bndrs _ = [] -allBinders :: [Ident] -- a,b,..z, a1, b1,... z1, a2, b2,... +allBinders :: [Ident] -- a,b,..z, a1, b1,... z1, a2, b2,... allBinders = [ identS [x] | x <- ['a'..'z'] ] ++ [ identS (x : show i) | i <- [1 :: Integer ..], x <- ['a'..'z']] @@ -688,12 +688,12 @@ runTcM f = case unTcM f IntMap.empty [] of TcFail (msg:msgs) -> do checkWarnings msgs; checkError msg newMeta :: Scope -> Sigma -> TcM MetaId -newMeta scope ty = TcM (\ms msgs -> +newMeta scope ty = TcM (\ms msgs -> let i = IntMap.size ms in TcOk i (IntMap.insert i (Unbound scope ty) ms) msgs) getMeta :: MetaId -> TcM MetaValue -getMeta i = TcM (\ms msgs -> +getMeta i = TcM (\ms msgs -> case IntMap.lookup i ms of Just mv -> TcOk mv ms msgs Nothing -> TcFail (("Unknown metavariable" <+> ppMeta i) : msgs)) @@ -702,7 +702,7 @@ setMeta :: MetaId -> MetaValue -> TcM () setMeta i mv = TcM (\ms msgs -> TcOk () (IntMap.insert i mv ms) msgs) newVar :: Scope -> Ident -newVar scope = head [x | i <- [1..], +newVar scope = head [x | i <- [1..], let x = identS ('v':show i), isFree scope x] where @@ -721,7 +721,7 @@ getMetaVars loc sc_tys = do return (foldr go [] tys) where -- Get the MetaIds from a term; no duplicates in result - go (Vr tv) acc = acc + go (Vr tv) acc = acc go (App x y) acc = go x (go y acc) go (Meta i) acc | i `elem` acc = acc @@ -741,7 +741,7 @@ getFreeVars loc sc_tys = do tys <- mapM (\(scope,ty) -> zonkTerm =<< tc_value2term loc (scopeVars scope) ty) sc_tys return (foldr (go []) [] tys) where - go bound (Vr tv) acc + go bound (Vr tv) acc | tv `elem` bound = acc | tv `elem` acc = acc | otherwise = tv : acc @@ -771,7 +771,7 @@ tc_value2term loc xs v = -data TcA x a +data TcA x a = TcSingle (MetaStore -> [Message] -> TcResult a) | TcMany [x] (MetaStore -> [Message] -> [(a,MetaStore,[Message])]) From 376b1234a2cb510aab62fefb59821557595c6ecb Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 14:27:11 +0200 Subject: [PATCH 61/75] Rename GF.Compile.TypeCheck.RConcrete to GF.Compile.TypeCheck.Concrete --- gf.cabal | 1 - src/compiler/GF/Command/SourceCommands.hs | 2 +- src/compiler/GF/Compile/CheckGrammar.hs | 2 +- src/compiler/GF/Compile/TypeCheck/Concrete.hs | 364 ++++---- .../GF/Compile/TypeCheck/RConcrete.hs | 801 ------------------ 5 files changed, 224 insertions(+), 946 deletions(-) delete mode 100644 src/compiler/GF/Compile/TypeCheck/RConcrete.hs diff --git a/gf.cabal b/gf.cabal index 854f8cfbf..fe9fb05b3 100644 --- a/gf.cabal +++ b/gf.cabal @@ -207,7 +207,6 @@ library GF.Compile.TypeCheck.Concrete GF.Compile.TypeCheck.ConcreteNew GF.Compile.TypeCheck.Primitives - GF.Compile.TypeCheck.RConcrete GF.Compile.TypeCheck.TC GF.Compile.Update GF.Data.BacktrackM diff --git a/src/compiler/GF/Command/SourceCommands.hs b/src/compiler/GF/Command/SourceCommands.hs index daf3f7f1e..91ada899d 100644 --- a/src/compiler/GF/Command/SourceCommands.hs +++ b/src/compiler/GF/Command/SourceCommands.hs @@ -19,7 +19,7 @@ import GF.Grammar.ShowTerm import GF.Grammar.Lookup (allOpers,allOpersTo) import GF.Compile.Rename(renameSourceTerm) import GF.Compile.Compute.Concrete(normalForm,resourceValues) -import GF.Compile.TypeCheck.RConcrete as TC(inferLType,ppType) +import GF.Compile.TypeCheck.Concrete as TC(inferLType,ppType) import GF.Infra.Dependencies(depGraph) import GF.Infra.CheckM(runCheck) diff --git a/src/compiler/GF/Compile/CheckGrammar.hs b/src/compiler/GF/Compile/CheckGrammar.hs index e7839da34..a657fd020 100644 --- a/src/compiler/GF/Compile/CheckGrammar.hs +++ b/src/compiler/GF/Compile/CheckGrammar.hs @@ -27,7 +27,7 @@ import GF.Infra.Ident import GF.Infra.Option import GF.Compile.TypeCheck.Abstract -import GF.Compile.TypeCheck.RConcrete +import GF.Compile.TypeCheck.Concrete import qualified GF.Compile.TypeCheck.ConcreteNew as CN import qualified GF.Compile.Compute.Concrete as CN diff --git a/src/compiler/GF/Compile/TypeCheck/Concrete.hs b/src/compiler/GF/Compile/TypeCheck/Concrete.hs index 2afff7c6a..380970405 100644 --- a/src/compiler/GF/Compile/TypeCheck/Concrete.hs +++ b/src/compiler/GF/Compile/TypeCheck/Concrete.hs @@ -1,6 +1,7 @@ {-# LANGUAGE PatternGuards #-} -module GF.Compile.TypeCheck.Concrete( {-checkLType, inferLType, computeLType, ppType-} ) where -{- +module GF.Compile.TypeCheck.Concrete( checkLType, inferLType, computeLType, ppType ) where +import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint + import GF.Infra.CheckM import GF.Data.Operations @@ -22,10 +23,16 @@ computeLType gr g0 t = comp (reverse [(b,x, Vr x) | (b,x,_) <- g0] ++ g0) t _ | Just _ <- isTypeInts ty -> return ty ---- shouldn't be needed | isPredefConstant ty -> return ty ---- shouldn't be needed - Q (m,ident) -> checkIn (text "module" <+> ppIdent m) $ do + Q (m,ident) -> checkIn ("module" <+> m) $ do ty' <- lookupResDef gr (m,ident) if ty' == ty then return ty else comp g ty' --- is this necessary to test? + AdHocOverload ts -> do + over <- getOverload gr g (Just typeType) t + case over of + Just (tr,_) -> return tr + _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 t) + Vr ident -> checkLookup ident g -- never needed to compute! App f a -> do @@ -73,26 +80,26 @@ inferLType gr g trm = case trm of Q (m,ident) | isPredef m -> termWith trm $ case typPredefined ident of Just ty -> return ty - Nothing -> checkError (text "unknown in Predef:" <+> ppIdent ident) + Nothing -> checkError ("unknown in Predef:" <+> ident) Q ident -> checks [ termWith trm $ lookupResType gr ident >>= computeLType gr g , lookupResDef gr ident >>= inferLType gr g , - checkError (text "cannot infer type of constant" <+> ppTerm Unqualified 0 trm) + checkError ("cannot infer type of constant" <+> ppTerm Unqualified 0 trm) ] QC (m,ident) | isPredef m -> termWith trm $ case typPredefined ident of Just ty -> return ty - Nothing -> checkError (text "unknown in Predef:" <+> ppIdent ident) + Nothing -> checkError ("unknown in Predef:" <+> ident) QC ident -> checks [ termWith trm $ lookupResType gr ident >>= computeLType gr g , lookupResDef gr ident >>= inferLType gr g , - checkError (text "cannot infer type of canonical constant" <+> ppTerm Unqualified 0 trm) + checkError ("cannot infer type of canonical constant" <+> ppTerm Unqualified 0 trm) ] Vr ident -> termWith trm $ checkLookup ident g @@ -100,7 +107,12 @@ inferLType gr g trm = case trm of Typed e t -> do t' <- computeLType gr g t checkLType gr g e t' - return (e,t') + + AdHocOverload ts -> do + over <- getOverload gr g Nothing trm + case over of + Just trty -> return trty + _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm) App f a -> do over <- getOverload gr g Nothing trm @@ -110,13 +122,17 @@ inferLType gr g trm = case trm of (f',fty) <- inferLType gr g f fty' <- computeLType gr g fty case fty' of - Prod bt z arg val -> do + Prod bt z arg val -> do a' <- justCheck g a arg - ty <- if isWildIdent z + ty <- if isWildIdent z then return val else substituteLType [(bt,z,a')] val - return (App f' a',ty) - _ -> checkError (text "A function type is expected for" <+> ppTerm Unqualified 0 f <+> text "instead of type" <+> ppType fty) + return (App f' a',ty) + _ -> + let term = ppTerm Unqualified 0 f + funName = pp . head . words .render $ term + in checkError ("A function type is expected for" <+> term <+> "instead of type" <+> ppType fty $$ + "\n ** Maybe you gave too many arguments to" <+> funName <+> "\n") S f x -> do (f', fty) <- inferLType gr g f @@ -124,7 +140,7 @@ inferLType gr g trm = case trm of Table arg val -> do x'<- justCheck g x arg return (S f' x', val) - _ -> checkError (text "table lintype expected for the table in" $$ nest 2 (ppTerm Unqualified 0 trm)) + _ -> checkError ("table lintype expected for the table in" $$ nest 2 (ppTerm Unqualified 0 trm)) P t i -> do (t',ty) <- inferLType gr g t --- ?? @@ -132,16 +148,16 @@ inferLType gr g trm = case trm of let tr2 = P t' i termWith tr2 $ case ty' of RecType ts -> case lookup i ts of - Nothing -> checkError (text "unknown label" <+> ppLabel i <+> text "in" $$ nest 2 (ppTerm Unqualified 0 ty')) + Nothing -> checkError ("unknown label" <+> i <+> "in" $$ nest 2 (ppTerm Unqualified 0 ty')) Just x -> return x - _ -> checkError (text "record type expected for:" <+> ppTerm Unqualified 0 t $$ - text " instead of the inferred:" <+> ppTerm Unqualified 0 ty') + _ -> checkError ("record type expected for:" <+> ppTerm Unqualified 0 t $$ + " instead of the inferred:" <+> ppTerm Unqualified 0 ty') R r -> do let (ls,fs) = unzip r fsts <- mapM inferM fs let ts = [ty | (Just ty,_) <- fsts] - checkCond (text "cannot infer type of record" $$ nest 2 (ppTerm Unqualified 0 trm)) (length ts == length fsts) + checkCond ("cannot infer type of record" $$ nest 2 (ppTerm Unqualified 0 trm)) (length ts == length fsts) return $ (R (zip ls fsts), RecType (zip ls ts)) T (TTyped arg) pts -> do @@ -152,10 +168,10 @@ inferLType gr g trm = case trm of checkLType gr g trm (Table arg val) T ti pts -> do -- tries to guess: good in oper type inference let pts' = [pt | pt@(p,_) <- pts, isConstPatt p] - case pts' of - [] -> checkError (text "cannot infer table type of" <+> ppTerm Unqualified 0 trm) ----- PInt k : _ -> return $ Ints $ max [i | PInt i <- pts'] - _ -> do + case pts' of + [] -> checkError ("cannot infer table type of" <+> ppTerm Unqualified 0 trm) +---- PInt k : _ -> return $ Ints $ max [i | PInt i <- pts'] + _ -> do (arg,val) <- checks $ map (inferCase Nothing) pts' checkLType gr g trm (Table arg val) V arg pts -> do @@ -166,9 +182,9 @@ inferLType gr g trm = case trm of K s -> do if elem ' ' s then do - let ss = foldr C Empty (map K (words s)) + let ss = foldr C Empty (map K (words s)) ----- removed irritating warning AR 24/5/2008 - ----- checkWarn ("token \"" ++ s ++ + ----- checkWarn ("token \"" ++ s ++ ----- "\" converted to token list" ++ prt ss) return (ss, typeStr) else return (trm, typeStr) @@ -179,50 +195,56 @@ inferLType gr g trm = case trm of Empty -> return (trm, typeStr) - C s1 s2 -> + C s1 s2 -> check2 (flip (justCheck g) typeStr) C s1 s2 typeStr - Glue s1 s2 -> + Glue s1 s2 -> check2 (flip (justCheck g) typeStr) Glue s1 s2 typeStr ---- typeTok ---- hack from Rename.identRenameTerm, to live with files with naming conflicts 18/6/2007 Strs (Cn c : ts) | c == cConflict -> do - checkWarn (text "unresolved constant, could be any of" <+> hcat (map (ppTerm Unqualified 0) ts)) + checkWarn ("unresolved constant, could be any of" <+> hcat (map (ppTerm Unqualified 0) ts)) inferLType gr g (head ts) Strs ts -> do - ts' <- mapM (\t -> justCheck g t typeStr) ts + ts' <- mapM (\t -> justCheck g t typeStr) ts return (Strs ts', typeStrs) Alts t aa -> do t' <- justCheck g t typeStr aa' <- flip mapM aa (\ (c,v) -> do - c' <- justCheck g c typeStr + c' <- justCheck g c typeStr v' <- checks $ map (justCheck g v) [typeStrs, EPattType typeStr] return (c',v')) return (Alts t' aa', typeStr) RecType r -> do let (ls,ts) = unzip r - ts' <- mapM (flip (justCheck g) typeType) ts + ts' <- mapM (flip (justCheck g) typeType) ts return (RecType (zip ls ts'), typeType) ExtR r s -> do - (r',rT) <- inferLType gr g r + +--- over <- getOverload gr g Nothing r +--- let r1 = maybe r fst over + let r1 = r --- + + (r',rT) <- inferLType gr g r1 rT' <- computeLType gr g rT + (s',sT) <- inferLType gr g s sT' <- computeLType gr g sT let trm' = ExtR r' s' - ---- trm' <- plusRecord r' s' case (rT', sT') of (RecType rs, RecType ss) -> do - rt <- plusRecType rT' sT' + let rt = RecType ([field | field@(l,_) <- rs, notElem l (map fst ss)] ++ ss) -- select types of later fields checkLType gr g trm' rt ---- return (trm', rt) - _ | rT' == typeType && sT' == typeType -> return (trm', typeType) - _ -> checkError (text "records or record types expected in" <+> ppTerm Unqualified 0 trm) + _ | rT' == typeType && sT' == typeType -> do + return (trm', typeType) + _ -> checkError ("records or record types expected in" <+> ppTerm Unqualified 0 trm) - Sort _ -> + Sort _ -> termWith trm $ return typeType Prod bt x a b -> do @@ -231,7 +253,7 @@ inferLType gr g trm = case trm of return (Prod bt x a' b', typeType) Table p t -> do - p' <- justCheck g p typeType --- check p partype! + p' <- justCheck g p typeType --- check p partype! t' <- justCheck g t typeType return $ (Table p' t', typeType) @@ -250,9 +272,9 @@ inferLType gr g trm = case trm of ELin c trm -> do (trm',ty) <- inferLType gr g trm ty' <- lockRecType c ty ---- lookup c; remove lock AR 20/6/2009 - return $ (ELin c trm', ty') + return $ (ELin c trm', ty') - _ -> checkError (text "cannot infer lintype of" <+> ppTerm Unqualified 0 trm) + _ -> checkError ("cannot infer lintype of" <+> ppTerm Unqualified 0 trm) where isPredef m = elem m [cPredef,cPredefAbs] @@ -299,7 +321,6 @@ inferLType gr g trm = case trm of PChars _ -> return $ typeStr _ -> inferLType gr g (patt2term p) >>= return . snd - -- type inference: Nothing, type checking: Just t -- the latter permits matching with value type getOverload :: SourceGrammar -> Context -> Maybe Type -> Term -> Check (Maybe (Term,Type)) @@ -310,15 +331,28 @@ getOverload gr g mt ot = case appForm ot of v <- matchOverload f typs ttys return $ Just v _ -> return Nothing + (AdHocOverload cs@(f:_), ts) -> do --- the function name f is only used in error messages + let typs = concatMap collectOverloads cs + ttys <- mapM (inferLType gr g) ts + v <- matchOverload f typs ttys + return $ Just v _ -> return Nothing + where + collectOverloads tr@(Q c) = case lookupOverload gr c of + Ok typs -> typs + _ -> case lookupResType gr c of + Ok ty -> let (args,val) = typeFormCnc ty in [(map (\(b,x,t) -> t) args,(val,tr))] + _ -> [] + collectOverloads _ = [] --- constructors QC + matchOverload f typs ttys = do let (tts,tys) = unzip ttys let vfs = lookupOverloadInstance tys typs let matches = [vf | vf@((_,v,_),_) <- vfs, matchVal mt v] let showTypes ty = hsep (map ppType ty) - + let (stys,styps) = (showTypes tys, [showTypes ty | (ty,_) <- typs]) -- to avoid strange error msg e.g. in case of unmatch record extension, show whole types if needed AR 28/1/2013 @@ -329,50 +363,57 @@ getOverload gr g mt ot = case appForm ot of case ([vf | (vf,True) <- matches],[vf | (vf,False) <- matches]) of ([(_,val,fun)],_) -> return (mkApp fun tts, val) ([],[(pre,val,fun)]) -> do - checkWarn $ text "ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot $$ - text "for" $$ + checkWarn $ "ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot $$ + "for" $$ nest 2 (showTypes tys) $$ - text "using" $$ + "using" $$ nest 2 (showTypes pre) return (mkApp fun tts, val) ([],[]) -> do - checkError $ text "no overload instance of" <+> ppTerm Unqualified 0 f $$ - text "for" $$ + checkError $ "no overload instance of" <+> ppTerm Qualified 0 f $$ + maybe empty (\x -> "with value type" <+> ppType x) mt $$ + "for argument list" $$ nest 2 stysError $$ - text "among" $$ - nest 2 (vcat stypsError) $$ - maybe empty (\x -> text "with value type" <+> ppType x) mt + "among alternatives" $$ + nest 2 (vcat stypsError) + (vfs1,vfs2) -> case (noProds vfs1,noProds vfs2) of ([(val,fun)],_) -> do return (mkApp fun tts, val) ([],[(val,fun)]) -> do - checkWarn (text "ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot) + checkWarn ("ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot) return (mkApp fun tts, val) ----- unsafely exclude irritating warning AR 24/5/2008 ------ checkWarn $ "overloading of" +++ prt f +++ +----- checkWarn $ "overloading of" +++ prt f +++ ----- "resolved by excluding partial applications:" ++++ ----- unlines [prtType env ty | (ty,_) <- vfs', not (noProd ty)] - - _ -> checkError $ text "ambiguous overloading of" <+> ppTerm Unqualified 0 f <+> - text "for" <+> hsep (map ppType tys) $$ - text "with alternatives" $$ - nest 2 (vcat [ppType ty | (_,ty,_) <- if null vfs1 then vfs2 else vfs2]) +--- now forgiving ambiguity with a warning AR 1/2/2014 +-- This gives ad hoc overloading the same behaviour as the choice of the first match in renaming did before. +-- But it also gives a chance to ambiguous overloadings that were banned before. + (nps1,nps2) -> do + checkWarn $ "ambiguous overloading of" <+> ppTerm Unqualified 0 f <+> + ---- "with argument types" <+> hsep (map (ppTerm Qualified 0) tys) $$ + "resolved by selecting the first of the alternatives" $$ + nest 2 (vcat [ppTerm Qualified 0 fun | (_,ty,fun) <- vfs1 ++ if null vfs1 then vfs2 else []]) + case [(mkApp fun tts,val) | (val,fun) <- nps1 ++ nps2] of + [] -> checkError $ "no alternatives left when resolving" <+> ppTerm Unqualified 0 f + h:_ -> return h matchVal mt v = elem mt [Nothing,Just v,Just (unlocked v)] unlocked v = case v of - RecType fs -> RecType $ filter (not . isLockLabel . fst) fs + RecType fs -> RecType $ filter (not . isLockLabel . fst) (sortRec fs) _ -> v ---- TODO: accept subtypes ---- TODO: use a trie - lookupOverloadInstance tys typs = - [((pre,mkFunType rest val, t),isExact) | + lookupOverloadInstance tys typs = + [((pre,mkFunType rest val, t),isExact) | let lt = length tys, (ty,(val,t)) <- typs, length ty >= lt, - let (pre,rest) = splitAt lt ty, + let (pre,rest) = splitAt lt ty, let isExact = pre == tys, isExact || map unlocked pre == map unlocked tys ] @@ -385,20 +426,21 @@ getOverload gr g mt ot = case appForm ot of checkLType :: SourceGrammar -> Context -> Term -> Type -> Check (Term, Type) checkLType gr g trm typ0 = do - typ <- computeLType gr g typ0 case trm of Abs bt x c -> do case typ of - Prod bt' z a b -> do + Prod bt' z a b -> do (c',b') <- if isWildIdent z then checkLType gr ((bt,x,a):g) c b - else do b' <- checkIn (text "abs") $ substituteLType [(bt',z,Vr x)] b + else do b' <- checkIn (pp "abs") $ substituteLType [(bt',z,Vr x)] b checkLType gr ((bt,x,a):g) c b' - return $ (Abs bt x c', Prod bt' x a b') - _ -> checkError $ text "function type expected instead of" <+> ppType typ + return $ (Abs bt x c', Prod bt' z a b') + _ -> checkError $ "function type expected instead of" <+> ppType typ $$ + "\n ** Double-check that the type signature of the operation" $$ + "matches the number of arguments given to it.\n" App f a -> do over <- getOverload gr g (Just typ) trm @@ -408,6 +450,12 @@ checkLType gr g trm typ0 = do (trm',ty') <- inferLType gr g trm termWith trm' $ checkEqLType gr g typ ty' trm' + AdHocOverload ts -> do + over <- getOverload gr g Nothing trm + case over of + Just trty -> return trty + _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm) + Q _ -> do over <- getOverload gr g (Just typ) trm case over of @@ -417,21 +465,21 @@ checkLType gr g trm typ0 = do termWith trm' $ checkEqLType gr g typ ty' trm' T _ [] -> - checkError (text "found empty table in type" <+> ppTerm Unqualified 0 typ) - T _ cs -> case typ of - Table arg val -> do + checkError ("found empty table in type" <+> ppTerm Unqualified 0 typ) + T _ cs -> case typ of + Table arg val -> do case allParamValues gr arg of Ok vs -> do let ps0 = map fst cs ps <- testOvershadow ps0 vs - if null ps - then return () - else checkWarn (text "patterns never reached:" $$ + if null ps + then return () + else checkWarn ("patterns never reached:" $$ nest 2 (vcat (map (ppPatt Unqualified 0) ps))) _ -> return () -- happens with variable types cs' <- mapM (checkCase arg val) cs return (T (TTyped arg) cs', typ) - _ -> checkError $ text "table type expected for table instead of" $$ nest 2 (ppType typ) + _ -> checkError $ "table type expected for table instead of" $$ nest 2 (ppType typ) V arg0 vs -> case typ of Table arg1 val -> @@ -439,51 +487,54 @@ checkLType gr g trm typ0 = do vs1 <- allParamValues gr arg1 if length vs1 == length vs then return () - else checkError $ text "wrong number of values in table" <+> ppTerm Unqualified 0 trm + else checkError $ "wrong number of values in table" <+> ppTerm Unqualified 0 trm vs' <- map fst `fmap` sequence [checkLType gr g v val|v<-vs] return (V arg' vs',typ) R r -> case typ of --- why needed? because inference may be too difficult RecType rr -> do - let (ls,_) = unzip rr -- labels of expected type + --let (ls,_) = unzip rr -- labels of expected type fsts <- mapM (checkM r) rr -- check that they are found in the record return $ (R fsts, typ) -- normalize record - _ -> checkError (text "record type expected in type checking instead of" $$ nest 2 (ppTerm Unqualified 0 typ)) + _ -> checkError ("record type expected in type checking instead of" $$ nest 2 (ppTerm Unqualified 0 typ)) ExtR r s -> case typ of _ | typ == typeType -> do trm' <- computeLType gr g trm case trm' of - RecType _ -> termWith trm $ return typeType - ExtR (Vr _) (RecType _) -> termWith trm $ return typeType + RecType _ -> termWith trm' $ return typeType + ExtR (Vr _) (RecType _) -> termWith trm' $ return typeType -- ext t = t ** ... - _ -> checkError (text "invalid record type extension" <+> nest 2 (ppTerm Unqualified 0 trm)) + _ -> checkError ("invalid record type extension" <+> nest 2 (ppTerm Unqualified 0 trm)) RecType rr -> do - (r',ty,s') <- checks [ - do (r',ty) <- inferLType gr g r - return (r',ty,s) - , - do (s',ty) <- inferLType gr g s - return (s',ty,r) - ] - case ty of - RecType rr1 -> do - let (rr0,rr2) = recParts rr rr1 - r2 <- justCheck g r' rr0 - s2 <- justCheck g s' rr2 - return $ (ExtR r2 s2, typ) - _ -> checkError (text "record type expected in extension of" <+> ppTerm Unqualified 0 r $$ - text "but found" <+> ppTerm Unqualified 0 ty) + ll2 <- case s of + R ss -> return $ map fst ss + _ -> do + (s',typ2) <- inferLType gr g s + case typ2 of + RecType ss -> return $ map fst ss + _ -> checkError ("cannot get labels from" $$ nest 2 (ppTerm Unqualified 0 typ2)) + let ll1 = [l | (l,_) <- rr, notElem l ll2] + +--- over <- getOverload gr g Nothing r --- this would solve #66 but fail ParadigmsAra. AR 6/7/2020 +--- let r1 = maybe r fst over + let r1 = r --- + + (r',_) <- checkLType gr g r1 (RecType [field | field@(l,_) <- rr, elem l ll1]) + (s',_) <- checkLType gr g s (RecType [field | field@(l,_) <- rr, elem l ll2]) + + let rec = R ([(l,(Nothing,P r' l)) | l <- ll1] ++ [(l,(Nothing,P s' l)) | l <- ll2]) + return (rec, typ) ExtR ty ex -> do r' <- justCheck g r ty s' <- justCheck g s ex return $ (ExtR r' s', typ) --- is this all? it assumes the same division in trm and typ - _ -> checkError (text "record extension not meaningful for" <+> ppTerm Unqualified 0 typ) + _ -> checkError ("record extension not meaningful for" <+> ppTerm Unqualified 0 typ) FV vs -> do ttys <- mapM (flip (checkLType gr g) typ) vs @@ -498,7 +549,7 @@ checkLType gr g trm typ0 = do (arg',val) <- checkLType gr g arg p checkEqLType gr g typ t trm return (S tab' arg', t) - _ -> checkError (text "table type expected for applied table instead of" <+> ppType ty') + _ -> checkError ("table type expected for applied table instead of" <+> ppType ty') , do (arg',ty) <- inferLType gr g arg ty' <- computeLType gr g ty @@ -507,7 +558,8 @@ checkLType gr g trm typ0 = do ] Let (x,(mty,def)) body -> case mty of Just ty -> do - (def',ty') <- checkLType gr g def ty + (ty0,_) <- checkLType gr g ty typeType + (def',ty') <- checkLType gr g def ty0 body' <- justCheck ((Explicit,x,ty'):g) body typ return (Let (x,(Just ty',def')) body', typ) _ -> do @@ -523,10 +575,10 @@ checkLType gr g trm typ0 = do termWith trm' $ checkEqLType gr g typ ty' trm' where justCheck g ty te = checkLType gr g ty te >>= return . fst - - recParts rr t = (RecType rr1,RecType rr2) where - (rr1,rr2) = partition (flip elem (map fst t) . fst) rr - +{- + recParts rr t = (RecType rr1,RecType rr2) where + (rr1,rr2) = partition (flip elem (map fst t) . fst) rr +-} checkM rms (l,ty) = case lookup l rms of Just (Just ty0,t) -> do checkEqLType gr g ty ty0 t @@ -535,12 +587,12 @@ checkLType gr g trm typ0 = do Just (_,t) -> do (t',ty') <- checkLType gr g t ty return (l,(Just ty',t')) - _ -> checkError $ - if isLockLabel l + _ -> checkError $ + if isLockLabel l then let cat = drop 5 (showIdent (label2ident l)) - in ppTerm Unqualified 0 (R rms) <+> text "is not in the lincat of" <+> text cat <> - text "; try wrapping it with lin" <+> text cat - else text "cannot find value for label" <+> ppLabel l <+> text "in" <+> ppTerm Unqualified 0 (R rms) + in ppTerm Unqualified 0 (R rms) <+> "is not in the lincat of" <+> cat <> + "; try wrapping it with lin" <+> cat + else "cannot find value for label" <+> l <+> "in" <+> ppTerm Unqualified 0 (R rms) checkCase arg val (p,t) = do cont <- pattContext gr g arg p @@ -553,7 +605,7 @@ pattContext env g typ p = case p of PP (q,c) ps | q /= cPredef -> do ---- why this /=? AR 6/1/2006 t <- lookupResType env (q,c) let (cont,v) = typeFormCnc t - checkCond (text "wrong number of arguments for constructor in" <+> ppPatt Unqualified 0 p) + checkCond ("wrong number of arguments for constructor in" <+> ppPatt Unqualified 0 p) (length cont == length ps) checkEqLType env g typ v (patt2term p) mapM (\((_,_,ty),p) -> pattContext env g ty p) (zip cont ps) >>= return . concat @@ -564,7 +616,7 @@ pattContext env g typ p = case p of let pts = [(ty,tr) | (l,tr) <- r, Just ty <- [lookup l t]] ----- checkWarn $ prt p ++++ show pts ----- debug mapM (uncurry (pattContext env g)) pts >>= return . concat - _ -> checkError (text "record type expected for pattern instead of" <+> ppTerm Unqualified 0 typ') + _ -> checkError ("record type expected for pattern instead of" <+> ppTerm Unqualified 0 typ') PT t p' -> do checkEqLType env g typ t (patt2term p') pattContext env g typ p' @@ -577,10 +629,10 @@ pattContext env g typ p = case p of g1 <- pattContext env g typ p' g2 <- pattContext env g typ q let pts = nub ([x | pt@(_,x,_) <- g1, notElem pt g2] ++ [x | pt@(_,x,_) <- g2, notElem pt g1]) - checkCond - (text "incompatible bindings of" <+> - fsep (map ppIdent pts) <+> - text "in pattern alterantives" <+> ppPatt Unqualified 0 p) (null pts) + checkCond + ("incompatible bindings of" <+> + fsep pts <+> + "in pattern alterantives" <+> ppPatt Unqualified 0 p) (null pts) return g1 -- must be g1 == g2 PSeq p q -> do g1 <- pattContext env g typ p @@ -590,11 +642,11 @@ pattContext env g typ p = case p of PNeg p' -> noBind typ p' _ -> return [] ---- check types! - where + where noBind typ p' = do co <- pattContext env g typ p' if not (null co) - then checkWarn (text "no variable bound inside pattern" <+> ppPatt Unqualified 0 p) + then checkWarn ("no variable bound inside pattern" <+> ppPatt Unqualified 0 p) >> return [] else return [] @@ -603,9 +655,31 @@ checkEqLType gr g t u trm = do (b,t',u',s) <- checkIfEqLType gr g t u trm case b of True -> return t' - False -> checkError $ text s <+> text "type of" <+> ppTerm Unqualified 0 trm $$ - text "expected:" <+> ppType t $$ - text "inferred:" <+> ppType u + False -> + let inferredType = ppTerm Qualified 0 u + expectedType = ppTerm Qualified 0 t + term = ppTerm Unqualified 0 trm + funName = pp . head . words .render $ term + helpfulMsg = + case (arrows inferredType, arrows expectedType) of + (0,0) -> pp "" -- None of the types is a function + _ -> "\n **" <+> + if expectedType `isLessApplied` inferredType + then "Maybe you gave too few arguments to" <+> funName + else pp "Double-check that type signature and number of arguments match." + in checkError $ s <+> "type of" <+> term $$ + "expected:" <+> expectedType $$ -- ppqType t u $$ + "inferred:" <+> inferredType $$ -- ppqType u t + helpfulMsg + where + -- count the number of arrows in the prettyprinted term + arrows :: Doc -> Int + arrows = length . filter (=="->") . words . render + + -- If prettyprinted type t has fewer arrows then prettyprinted type u, + -- then t is "less applied", and we can print out more helpful error msg. + isLessApplied :: Doc -> Doc -> Bool + isLessApplied t u = arrows t < arrows u checkIfEqLType :: SourceGrammar -> Context -> Type -> Type -> Term -> Check (Bool,Type,Type,String) checkIfEqLType gr g t u trm = do @@ -617,60 +691,62 @@ checkIfEqLType gr g t u trm = do --- better: use a flag to forgive? (AR 31/1/2006) _ -> case missingLock [] t' u' of Ok lo -> do - checkWarn $ text "missing lock field" <+> fsep (map ppLabel lo) + checkWarn $ "missing lock field" <+> fsep lo return (True,t',u',[]) Bad s -> return (False,t',u',s) where - -- t is a subtype of u + -- check that u is a subtype of t --- quick hack version of TC.eqVal - alpha g t u = case (t,u) of + alpha g t u = case (t,u) of -- error (the empty type!) is subtype of any other type (_,u) | u == typeError -> True -- contravariance - (Prod _ x a b, Prod _ y c d) -> alpha g c a && alpha ((x,y):g) b d - + (Prod _ x a b, Prod _ y c d) -> alpha g c a && alpha ((x,y):g) b d + -- record subtyping - (RecType rs, RecType ts) -> all (\ (l,a) -> - any (\ (k,b) -> alpha g a b && l == k) ts) rs + (RecType rs, RecType ts) -> all (\ (l,a) -> + any (\ (k,b) -> l == k && alpha g a b) ts) rs (ExtR r s, ExtR r' s') -> alpha g r r' && alpha g s s' (ExtR r s, t) -> alpha g r t || alpha g s t -- the following say that Ints n is a subset of Int and of Ints m >= n - (t,u) | Just m <- isTypeInts t, Just n <- isTypeInts t -> m >= n + -- But why does it also allow Int as a subtype of Ints m? /TH 2014-04-04 + (t,u) | Just m <- isTypeInts t, Just n <- isTypeInts u -> m >= n | Just _ <- isTypeInts t, u == typeInt -> True ---- check size! | t == typeInt, Just _ <- isTypeInts u -> True ---- why this ???? AR 11/12/2005 ---- this should be made in Rename - (Q (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) + (Q (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) || elem n (allExtendsPlus gr m) || m == n --- for Predef - (QC (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) + (QC (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) || elem n (allExtendsPlus gr m) - (QC (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) + (QC (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) || elem n (allExtendsPlus gr m) - (Q (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) + (Q (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) || elem n (allExtendsPlus gr m) - (Table a b, Table c d) -> alpha g a c && alpha g b d + -- contravariance + (Table a b, Table c d) -> alpha g c a && alpha g b d (Vr x, Vr y) -> x == y || elem (x,y) g || elem (y,x) g - _ -> t == u + _ -> t == u --- the following should be one-way coercions only. AR 4/1/2001 || elem t sTypes && elem u sTypes - || (t == typeType && u == typePType) - || (u == typeType && t == typePType) + || (t == typeType && u == typePType) + || (u == typeType && t == typePType) - missingLock g t u = case (t,u) of - (RecType rs, RecType ts) -> - let - ls = [l | (l,a) <- rs, + missingLock g t u = case (t,u) of + (RecType rs, RecType ts) -> + let + ls = [l | (l,a) <- rs, not (any (\ (k,b) -> alpha g a b && l == k) ts)] (locks,others) = partition isLockLabel ls in case others of - _:_ -> Bad $ render (text "missing record fields:" <+> fsep (punctuate comma (map ppLabel others))) + _:_ -> Bad $ render ("missing record fields:" <+> fsep (punctuate ',' (others))) _ -> return locks -- contravariance (Prod _ x a b, Prod _ y c d) -> do @@ -696,7 +772,7 @@ termWith t ct = do return (t,ty) -- | compositional check\/infer of binary operations -check2 :: (Term -> Check Term) -> (Term -> Term -> Term) -> +check2 :: (Term -> Check Term) -> (Term -> Term -> Term) -> Term -> Term -> Type -> Check (Term,Type) check2 chk con a b t = do a' <- chk a @@ -708,14 +784,18 @@ ppType :: Type -> Doc ppType ty = case ty of RecType fs -> case filter isLockLabel $ map fst fs of - [lock] -> text (drop 5 (showIdent (label2ident lock))) + [lock] -> pp (drop 5 (showIdent (label2ident lock))) _ -> ppTerm Unqualified 0 ty - Prod _ x a b -> ppType a <+> text "->" <+> ppType b + Prod _ x a b -> ppType a <+> "->" <+> ppType b _ -> ppTerm Unqualified 0 ty - +{- +ppqType :: Type -> Type -> Doc +ppqType t u = case (ppType t, ppType u) of + (pt,pu) | render pt == render pu -> ppTerm Qualified 0 t + (pt,_) -> pt +-} checkLookup :: Ident -> Context -> Check Type checkLookup x g = case [ty | (b,y,ty) <- g, x == y] of - [] -> checkError (text "unknown variable" <+> ppIdent x) + [] -> checkError ("unknown variable" <+> x) (ty:_) -> return ty --} diff --git a/src/compiler/GF/Compile/TypeCheck/RConcrete.hs b/src/compiler/GF/Compile/TypeCheck/RConcrete.hs deleted file mode 100644 index aa13d5406..000000000 --- a/src/compiler/GF/Compile/TypeCheck/RConcrete.hs +++ /dev/null @@ -1,801 +0,0 @@ -{-# LANGUAGE PatternGuards #-} -module GF.Compile.TypeCheck.RConcrete( checkLType, inferLType, computeLType, ppType ) where -import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint - -import GF.Infra.CheckM -import GF.Data.Operations - -import GF.Grammar -import GF.Grammar.Lookup -import GF.Grammar.Predef -import GF.Grammar.PatternMatch -import GF.Grammar.Lockfield (isLockLabel, lockRecType, unlockRecord) -import GF.Compile.TypeCheck.Primitives - -import Data.List -import Control.Monad -import GF.Text.Pretty - -computeLType :: SourceGrammar -> Context -> Type -> Check Type -computeLType gr g0 t = comp (reverse [(b,x, Vr x) | (b,x,_) <- g0] ++ g0) t - where - comp g ty = case ty of - _ | Just _ <- isTypeInts ty -> return ty ---- shouldn't be needed - | isPredefConstant ty -> return ty ---- shouldn't be needed - - Q (m,ident) -> checkIn ("module" <+> m) $ do - ty' <- lookupResDef gr (m,ident) - if ty' == ty then return ty else comp g ty' --- is this necessary to test? - - AdHocOverload ts -> do - over <- getOverload gr g (Just typeType) t - case over of - Just (tr,_) -> return tr - _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 t) - - Vr ident -> checkLookup ident g -- never needed to compute! - - App f a -> do - f' <- comp g f - a' <- comp g a - case f' of - Abs b x t -> comp ((b,x,a'):g) t - _ -> return $ App f' a' - - Prod bt x a b -> do - a' <- comp g a - b' <- comp ((bt,x,Vr x) : g) b - return $ Prod bt x a' b' - - Abs bt x b -> do - b' <- comp ((bt,x,Vr x):g) b - return $ Abs bt x b' - - Let (x,(_,a)) b -> comp ((Explicit,x,a):g) b - - ExtR r s -> do - r' <- comp g r - s' <- comp g s - case (r',s') of - (RecType rs, RecType ss) -> plusRecType r' s' >>= comp g - _ -> return $ ExtR r' s' - - RecType fs -> do - let fs' = sortRec fs - liftM RecType $ mapPairsM (comp g) fs' - - ELincat c t -> do - t' <- comp g t - lockRecType c t' ---- locking to be removed AR 20/6/2009 - - _ | ty == typeTok -> return typeStr - _ | isPredefConstant ty -> return ty - - _ -> composOp (comp g) ty - --- the underlying algorithms - -inferLType :: SourceGrammar -> Context -> Term -> Check (Term, Type) -inferLType gr g trm = case trm of - - Q (m,ident) | isPredef m -> termWith trm $ case typPredefined ident of - Just ty -> return ty - Nothing -> checkError ("unknown in Predef:" <+> ident) - - Q ident -> checks [ - termWith trm $ lookupResType gr ident >>= computeLType gr g - , - lookupResDef gr ident >>= inferLType gr g - , - checkError ("cannot infer type of constant" <+> ppTerm Unqualified 0 trm) - ] - - QC (m,ident) | isPredef m -> termWith trm $ case typPredefined ident of - Just ty -> return ty - Nothing -> checkError ("unknown in Predef:" <+> ident) - - QC ident -> checks [ - termWith trm $ lookupResType gr ident >>= computeLType gr g - , - lookupResDef gr ident >>= inferLType gr g - , - checkError ("cannot infer type of canonical constant" <+> ppTerm Unqualified 0 trm) - ] - - Vr ident -> termWith trm $ checkLookup ident g - - Typed e t -> do - t' <- computeLType gr g t - checkLType gr g e t' - - AdHocOverload ts -> do - over <- getOverload gr g Nothing trm - case over of - Just trty -> return trty - _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm) - - App f a -> do - over <- getOverload gr g Nothing trm - case over of - Just trty -> return trty - _ -> do - (f',fty) <- inferLType gr g f - fty' <- computeLType gr g fty - case fty' of - Prod bt z arg val -> do - a' <- justCheck g a arg - ty <- if isWildIdent z - then return val - else substituteLType [(bt,z,a')] val - return (App f' a',ty) - _ -> - let term = ppTerm Unqualified 0 f - funName = pp . head . words .render $ term - in checkError ("A function type is expected for" <+> term <+> "instead of type" <+> ppType fty $$ - "\n ** Maybe you gave too many arguments to" <+> funName <+> "\n") - - S f x -> do - (f', fty) <- inferLType gr g f - case fty of - Table arg val -> do - x'<- justCheck g x arg - return (S f' x', val) - _ -> checkError ("table lintype expected for the table in" $$ nest 2 (ppTerm Unqualified 0 trm)) - - P t i -> do - (t',ty) <- inferLType gr g t --- ?? - ty' <- computeLType gr g ty - let tr2 = P t' i - termWith tr2 $ case ty' of - RecType ts -> case lookup i ts of - Nothing -> checkError ("unknown label" <+> i <+> "in" $$ nest 2 (ppTerm Unqualified 0 ty')) - Just x -> return x - _ -> checkError ("record type expected for:" <+> ppTerm Unqualified 0 t $$ - " instead of the inferred:" <+> ppTerm Unqualified 0 ty') - - R r -> do - let (ls,fs) = unzip r - fsts <- mapM inferM fs - let ts = [ty | (Just ty,_) <- fsts] - checkCond ("cannot infer type of record" $$ nest 2 (ppTerm Unqualified 0 trm)) (length ts == length fsts) - return $ (R (zip ls fsts), RecType (zip ls ts)) - - T (TTyped arg) pts -> do - (_,val) <- checks $ map (inferCase (Just arg)) pts - checkLType gr g trm (Table arg val) - T (TComp arg) pts -> do - (_,val) <- checks $ map (inferCase (Just arg)) pts - checkLType gr g trm (Table arg val) - T ti pts -> do -- tries to guess: good in oper type inference - let pts' = [pt | pt@(p,_) <- pts, isConstPatt p] - case pts' of - [] -> checkError ("cannot infer table type of" <+> ppTerm Unqualified 0 trm) ----- PInt k : _ -> return $ Ints $ max [i | PInt i <- pts'] - _ -> do - (arg,val) <- checks $ map (inferCase Nothing) pts' - checkLType gr g trm (Table arg val) - V arg pts -> do - (_,val) <- checks $ map (inferLType gr g) pts --- return (trm, Table arg val) -- old, caused issue 68 - checkLType gr g trm (Table arg val) - - K s -> do - if elem ' ' s - then do - let ss = foldr C Empty (map K (words s)) - ----- removed irritating warning AR 24/5/2008 - ----- checkWarn ("token \"" ++ s ++ - ----- "\" converted to token list" ++ prt ss) - return (ss, typeStr) - else return (trm, typeStr) - - EInt i -> return (trm, typeInt) - - EFloat i -> return (trm, typeFloat) - - Empty -> return (trm, typeStr) - - C s1 s2 -> - check2 (flip (justCheck g) typeStr) C s1 s2 typeStr - - Glue s1 s2 -> - check2 (flip (justCheck g) typeStr) Glue s1 s2 typeStr ---- typeTok - ----- hack from Rename.identRenameTerm, to live with files with naming conflicts 18/6/2007 - Strs (Cn c : ts) | c == cConflict -> do - checkWarn ("unresolved constant, could be any of" <+> hcat (map (ppTerm Unqualified 0) ts)) - inferLType gr g (head ts) - - Strs ts -> do - ts' <- mapM (\t -> justCheck g t typeStr) ts - return (Strs ts', typeStrs) - - Alts t aa -> do - t' <- justCheck g t typeStr - aa' <- flip mapM aa (\ (c,v) -> do - c' <- justCheck g c typeStr - v' <- checks $ map (justCheck g v) [typeStrs, EPattType typeStr] - return (c',v')) - return (Alts t' aa', typeStr) - - RecType r -> do - let (ls,ts) = unzip r - ts' <- mapM (flip (justCheck g) typeType) ts - return (RecType (zip ls ts'), typeType) - - ExtR r s -> do - ---- over <- getOverload gr g Nothing r ---- let r1 = maybe r fst over - let r1 = r --- - - (r',rT) <- inferLType gr g r1 - rT' <- computeLType gr g rT - - (s',sT) <- inferLType gr g s - sT' <- computeLType gr g sT - - let trm' = ExtR r' s' - case (rT', sT') of - (RecType rs, RecType ss) -> do - let rt = RecType ([field | field@(l,_) <- rs, notElem l (map fst ss)] ++ ss) -- select types of later fields - checkLType gr g trm' rt ---- return (trm', rt) - _ | rT' == typeType && sT' == typeType -> do - return (trm', typeType) - _ -> checkError ("records or record types expected in" <+> ppTerm Unqualified 0 trm) - - Sort _ -> - termWith trm $ return typeType - - Prod bt x a b -> do - a' <- justCheck g a typeType - b' <- justCheck ((bt,x,a'):g) b typeType - return (Prod bt x a' b', typeType) - - Table p t -> do - p' <- justCheck g p typeType --- check p partype! - t' <- justCheck g t typeType - return $ (Table p' t', typeType) - - FV vs -> do - (_,ty) <- checks $ map (inferLType gr g) vs ---- checkIfComplexVariantType trm ty - checkLType gr g trm ty - - EPattType ty -> do - ty' <- justCheck g ty typeType - return (EPattType ty',typeType) - EPatt p -> do - ty <- inferPatt p - return (trm, EPattType ty) - - ELin c trm -> do - (trm',ty) <- inferLType gr g trm - ty' <- lockRecType c ty ---- lookup c; remove lock AR 20/6/2009 - return $ (ELin c trm', ty') - - _ -> checkError ("cannot infer lintype of" <+> ppTerm Unqualified 0 trm) - - where - isPredef m = elem m [cPredef,cPredefAbs] - - justCheck g ty te = checkLType gr g ty te >>= return . fst - - -- for record fields, which may be typed - inferM (mty, t) = do - (t', ty') <- case mty of - Just ty -> checkLType gr g t ty - _ -> inferLType gr g t - return (Just ty',t') - - inferCase mty (patt,term) = do - arg <- maybe (inferPatt patt) return mty - cont <- pattContext gr g arg patt - (_,val) <- inferLType gr (reverse cont ++ g) term - return (arg,val) - isConstPatt p = case p of - PC _ ps -> True --- all isConstPatt ps - PP _ ps -> True --- all isConstPatt ps - PR ps -> all (isConstPatt . snd) ps - PT _ p -> isConstPatt p - PString _ -> True - PInt _ -> True - PFloat _ -> True - PChar -> True - PChars _ -> True - PSeq p q -> isConstPatt p && isConstPatt q - PAlt p q -> isConstPatt p && isConstPatt q - PRep p -> isConstPatt p - PNeg p -> isConstPatt p - PAs _ p -> isConstPatt p - _ -> False - - inferPatt p = case p of - PP (q,c) ps | q /= cPredef -> liftM valTypeCnc (lookupResType gr (q,c)) - PAs _ p -> inferPatt p - PNeg p -> inferPatt p - PAlt p q -> checks [inferPatt p, inferPatt q] - PSeq _ _ -> return $ typeStr - PRep _ -> return $ typeStr - PChar -> return $ typeStr - PChars _ -> return $ typeStr - _ -> inferLType gr g (patt2term p) >>= return . snd - --- type inference: Nothing, type checking: Just t --- the latter permits matching with value type -getOverload :: SourceGrammar -> Context -> Maybe Type -> Term -> Check (Maybe (Term,Type)) -getOverload gr g mt ot = case appForm ot of - (f@(Q c), ts) -> case lookupOverload gr c of - Ok typs -> do - ttys <- mapM (inferLType gr g) ts - v <- matchOverload f typs ttys - return $ Just v - _ -> return Nothing - (AdHocOverload cs@(f:_), ts) -> do --- the function name f is only used in error messages - let typs = concatMap collectOverloads cs - ttys <- mapM (inferLType gr g) ts - v <- matchOverload f typs ttys - return $ Just v - _ -> return Nothing - - where - collectOverloads tr@(Q c) = case lookupOverload gr c of - Ok typs -> typs - _ -> case lookupResType gr c of - Ok ty -> let (args,val) = typeFormCnc ty in [(map (\(b,x,t) -> t) args,(val,tr))] - _ -> [] - collectOverloads _ = [] --- constructors QC - - matchOverload f typs ttys = do - let (tts,tys) = unzip ttys - let vfs = lookupOverloadInstance tys typs - let matches = [vf | vf@((_,v,_),_) <- vfs, matchVal mt v] - let showTypes ty = hsep (map ppType ty) - - - let (stys,styps) = (showTypes tys, [showTypes ty | (ty,_) <- typs]) - - -- to avoid strange error msg e.g. in case of unmatch record extension, show whole types if needed AR 28/1/2013 - let (stysError,stypsError) = if elem (render stys) (map render styps) - then (hsep (map (ppTerm Unqualified 0) tys), [hsep (map (ppTerm Unqualified 0) ty) | (ty,_) <- typs]) - else (stys,styps) - - case ([vf | (vf,True) <- matches],[vf | (vf,False) <- matches]) of - ([(_,val,fun)],_) -> return (mkApp fun tts, val) - ([],[(pre,val,fun)]) -> do - checkWarn $ "ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot $$ - "for" $$ - nest 2 (showTypes tys) $$ - "using" $$ - nest 2 (showTypes pre) - return (mkApp fun tts, val) - ([],[]) -> do - checkError $ "no overload instance of" <+> ppTerm Qualified 0 f $$ - maybe empty (\x -> "with value type" <+> ppType x) mt $$ - "for argument list" $$ - nest 2 stysError $$ - "among alternatives" $$ - nest 2 (vcat stypsError) - - - (vfs1,vfs2) -> case (noProds vfs1,noProds vfs2) of - ([(val,fun)],_) -> do - return (mkApp fun tts, val) - ([],[(val,fun)]) -> do - checkWarn ("ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot) - return (mkApp fun tts, val) - ------ unsafely exclude irritating warning AR 24/5/2008 ------ checkWarn $ "overloading of" +++ prt f +++ ------ "resolved by excluding partial applications:" ++++ ------ unlines [prtType env ty | (ty,_) <- vfs', not (noProd ty)] - ---- now forgiving ambiguity with a warning AR 1/2/2014 --- This gives ad hoc overloading the same behaviour as the choice of the first match in renaming did before. --- But it also gives a chance to ambiguous overloadings that were banned before. - (nps1,nps2) -> do - checkWarn $ "ambiguous overloading of" <+> ppTerm Unqualified 0 f <+> - ---- "with argument types" <+> hsep (map (ppTerm Qualified 0) tys) $$ - "resolved by selecting the first of the alternatives" $$ - nest 2 (vcat [ppTerm Qualified 0 fun | (_,ty,fun) <- vfs1 ++ if null vfs1 then vfs2 else []]) - case [(mkApp fun tts,val) | (val,fun) <- nps1 ++ nps2] of - [] -> checkError $ "no alternatives left when resolving" <+> ppTerm Unqualified 0 f - h:_ -> return h - - matchVal mt v = elem mt [Nothing,Just v,Just (unlocked v)] - - unlocked v = case v of - RecType fs -> RecType $ filter (not . isLockLabel . fst) (sortRec fs) - _ -> v - ---- TODO: accept subtypes - ---- TODO: use a trie - lookupOverloadInstance tys typs = - [((pre,mkFunType rest val, t),isExact) | - let lt = length tys, - (ty,(val,t)) <- typs, length ty >= lt, - let (pre,rest) = splitAt lt ty, - let isExact = pre == tys, - isExact || map unlocked pre == map unlocked tys - ] - - noProds vfs = [(v,f) | (_,v,f) <- vfs, noProd v] - - noProd ty = case ty of - Prod _ _ _ _ -> False - _ -> True - -checkLType :: SourceGrammar -> Context -> Term -> Type -> Check (Term, Type) -checkLType gr g trm typ0 = do - typ <- computeLType gr g typ0 - - case trm of - - Abs bt x c -> do - case typ of - Prod bt' z a b -> do - (c',b') <- if isWildIdent z - then checkLType gr ((bt,x,a):g) c b - else do b' <- checkIn (pp "abs") $ substituteLType [(bt',z,Vr x)] b - checkLType gr ((bt,x,a):g) c b' - return $ (Abs bt x c', Prod bt' z a b') - _ -> checkError $ "function type expected instead of" <+> ppType typ $$ - "\n ** Double-check that the type signature of the operation" $$ - "matches the number of arguments given to it.\n" - - App f a -> do - over <- getOverload gr g (Just typ) trm - case over of - Just trty -> return trty - _ -> do - (trm',ty') <- inferLType gr g trm - termWith trm' $ checkEqLType gr g typ ty' trm' - - AdHocOverload ts -> do - over <- getOverload gr g Nothing trm - case over of - Just trty -> return trty - _ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm) - - Q _ -> do - over <- getOverload gr g (Just typ) trm - case over of - Just trty -> return trty - _ -> do - (trm',ty') <- inferLType gr g trm - termWith trm' $ checkEqLType gr g typ ty' trm' - - T _ [] -> - checkError ("found empty table in type" <+> ppTerm Unqualified 0 typ) - T _ cs -> case typ of - Table arg val -> do - case allParamValues gr arg of - Ok vs -> do - let ps0 = map fst cs - ps <- testOvershadow ps0 vs - if null ps - then return () - else checkWarn ("patterns never reached:" $$ - nest 2 (vcat (map (ppPatt Unqualified 0) ps))) - _ -> return () -- happens with variable types - cs' <- mapM (checkCase arg val) cs - return (T (TTyped arg) cs', typ) - _ -> checkError $ "table type expected for table instead of" $$ nest 2 (ppType typ) - V arg0 vs -> - case typ of - Table arg1 val -> - do arg' <- checkEqLType gr g arg0 arg1 trm - vs1 <- allParamValues gr arg1 - if length vs1 == length vs - then return () - else checkError $ "wrong number of values in table" <+> ppTerm Unqualified 0 trm - vs' <- map fst `fmap` sequence [checkLType gr g v val|v<-vs] - return (V arg' vs',typ) - - R r -> case typ of --- why needed? because inference may be too difficult - RecType rr -> do - --let (ls,_) = unzip rr -- labels of expected type - fsts <- mapM (checkM r) rr -- check that they are found in the record - return $ (R fsts, typ) -- normalize record - - _ -> checkError ("record type expected in type checking instead of" $$ nest 2 (ppTerm Unqualified 0 typ)) - - ExtR r s -> case typ of - _ | typ == typeType -> do - trm' <- computeLType gr g trm - case trm' of - RecType _ -> termWith trm' $ return typeType - ExtR (Vr _) (RecType _) -> termWith trm' $ return typeType - -- ext t = t ** ... - _ -> checkError ("invalid record type extension" <+> nest 2 (ppTerm Unqualified 0 trm)) - - RecType rr -> do - - ll2 <- case s of - R ss -> return $ map fst ss - _ -> do - (s',typ2) <- inferLType gr g s - case typ2 of - RecType ss -> return $ map fst ss - _ -> checkError ("cannot get labels from" $$ nest 2 (ppTerm Unqualified 0 typ2)) - let ll1 = [l | (l,_) <- rr, notElem l ll2] - ---- over <- getOverload gr g Nothing r --- this would solve #66 but fail ParadigmsAra. AR 6/7/2020 ---- let r1 = maybe r fst over - let r1 = r --- - - (r',_) <- checkLType gr g r1 (RecType [field | field@(l,_) <- rr, elem l ll1]) - (s',_) <- checkLType gr g s (RecType [field | field@(l,_) <- rr, elem l ll2]) - - let rec = R ([(l,(Nothing,P r' l)) | l <- ll1] ++ [(l,(Nothing,P s' l)) | l <- ll2]) - return (rec, typ) - - ExtR ty ex -> do - r' <- justCheck g r ty - s' <- justCheck g s ex - return $ (ExtR r' s', typ) --- is this all? it assumes the same division in trm and typ - - _ -> checkError ("record extension not meaningful for" <+> ppTerm Unqualified 0 typ) - - FV vs -> do - ttys <- mapM (flip (checkLType gr g) typ) vs ---- checkIfComplexVariantType trm typ - return (FV (map fst ttys), typ) --- typ' ? - - S tab arg -> checks [ do - (tab',ty) <- inferLType gr g tab - ty' <- computeLType gr g ty - case ty' of - Table p t -> do - (arg',val) <- checkLType gr g arg p - checkEqLType gr g typ t trm - return (S tab' arg', t) - _ -> checkError ("table type expected for applied table instead of" <+> ppType ty') - , do - (arg',ty) <- inferLType gr g arg - ty' <- computeLType gr g ty - (tab',_) <- checkLType gr g tab (Table ty' typ) - return (S tab' arg', typ) - ] - Let (x,(mty,def)) body -> case mty of - Just ty -> do - (ty0,_) <- checkLType gr g ty typeType - (def',ty') <- checkLType gr g def ty0 - body' <- justCheck ((Explicit,x,ty'):g) body typ - return (Let (x,(Just ty',def')) body', typ) - _ -> do - (def',ty) <- inferLType gr g def -- tries to infer type of local constant - checkLType gr g (Let (x,(Just ty,def')) body) typ - - ELin c tr -> do - tr1 <- unlockRecord c tr - checkLType gr g tr1 typ - - _ -> do - (trm',ty') <- inferLType gr g trm - termWith trm' $ checkEqLType gr g typ ty' trm' - where - justCheck g ty te = checkLType gr g ty te >>= return . fst -{- - recParts rr t = (RecType rr1,RecType rr2) where - (rr1,rr2) = partition (flip elem (map fst t) . fst) rr --} - checkM rms (l,ty) = case lookup l rms of - Just (Just ty0,t) -> do - checkEqLType gr g ty ty0 t - (t',ty') <- checkLType gr g t ty - return (l,(Just ty',t')) - Just (_,t) -> do - (t',ty') <- checkLType gr g t ty - return (l,(Just ty',t')) - _ -> checkError $ - if isLockLabel l - then let cat = drop 5 (showIdent (label2ident l)) - in ppTerm Unqualified 0 (R rms) <+> "is not in the lincat of" <+> cat <> - "; try wrapping it with lin" <+> cat - else "cannot find value for label" <+> l <+> "in" <+> ppTerm Unqualified 0 (R rms) - - checkCase arg val (p,t) = do - cont <- pattContext gr g arg p - t' <- justCheck (reverse cont ++ g) t val - return (p,t') - -pattContext :: SourceGrammar -> Context -> Type -> Patt -> Check Context -pattContext env g typ p = case p of - PV x -> return [(Explicit,x,typ)] - PP (q,c) ps | q /= cPredef -> do ---- why this /=? AR 6/1/2006 - t <- lookupResType env (q,c) - let (cont,v) = typeFormCnc t - checkCond ("wrong number of arguments for constructor in" <+> ppPatt Unqualified 0 p) - (length cont == length ps) - checkEqLType env g typ v (patt2term p) - mapM (\((_,_,ty),p) -> pattContext env g ty p) (zip cont ps) >>= return . concat - PR r -> do - typ' <- computeLType env g typ - case typ' of - RecType t -> do - let pts = [(ty,tr) | (l,tr) <- r, Just ty <- [lookup l t]] - ----- checkWarn $ prt p ++++ show pts ----- debug - mapM (uncurry (pattContext env g)) pts >>= return . concat - _ -> checkError ("record type expected for pattern instead of" <+> ppTerm Unqualified 0 typ') - PT t p' -> do - checkEqLType env g typ t (patt2term p') - pattContext env g typ p' - - PAs x p -> do - g' <- pattContext env g typ p - return ((Explicit,x,typ):g') - - PAlt p' q -> do - g1 <- pattContext env g typ p' - g2 <- pattContext env g typ q - let pts = nub ([x | pt@(_,x,_) <- g1, notElem pt g2] ++ [x | pt@(_,x,_) <- g2, notElem pt g1]) - checkCond - ("incompatible bindings of" <+> - fsep pts <+> - "in pattern alterantives" <+> ppPatt Unqualified 0 p) (null pts) - return g1 -- must be g1 == g2 - PSeq p q -> do - g1 <- pattContext env g typ p - g2 <- pattContext env g typ q - return $ g1 ++ g2 - PRep p' -> noBind typeStr p' - PNeg p' -> noBind typ p' - - _ -> return [] ---- check types! - where - noBind typ p' = do - co <- pattContext env g typ p' - if not (null co) - then checkWarn ("no variable bound inside pattern" <+> ppPatt Unqualified 0 p) - >> return [] - else return [] - -checkEqLType :: SourceGrammar -> Context -> Type -> Type -> Term -> Check Type -checkEqLType gr g t u trm = do - (b,t',u',s) <- checkIfEqLType gr g t u trm - case b of - True -> return t' - False -> - let inferredType = ppTerm Qualified 0 u - expectedType = ppTerm Qualified 0 t - term = ppTerm Unqualified 0 trm - funName = pp . head . words .render $ term - helpfulMsg = - case (arrows inferredType, arrows expectedType) of - (0,0) -> pp "" -- None of the types is a function - _ -> "\n **" <+> - if expectedType `isLessApplied` inferredType - then "Maybe you gave too few arguments to" <+> funName - else pp "Double-check that type signature and number of arguments match." - in checkError $ s <+> "type of" <+> term $$ - "expected:" <+> expectedType $$ -- ppqType t u $$ - "inferred:" <+> inferredType $$ -- ppqType u t - helpfulMsg - where - -- count the number of arrows in the prettyprinted term - arrows :: Doc -> Int - arrows = length . filter (=="->") . words . render - - -- If prettyprinted type t has fewer arrows then prettyprinted type u, - -- then t is "less applied", and we can print out more helpful error msg. - isLessApplied :: Doc -> Doc -> Bool - isLessApplied t u = arrows t < arrows u - -checkIfEqLType :: SourceGrammar -> Context -> Type -> Type -> Term -> Check (Bool,Type,Type,String) -checkIfEqLType gr g t u trm = do - t' <- computeLType gr g t - u' <- computeLType gr g u - case t' == u' || alpha [] t' u' of - True -> return (True,t',u',[]) - -- forgive missing lock fields by only generating a warning. - --- better: use a flag to forgive? (AR 31/1/2006) - _ -> case missingLock [] t' u' of - Ok lo -> do - checkWarn $ "missing lock field" <+> fsep lo - return (True,t',u',[]) - Bad s -> return (False,t',u',s) - - where - - -- check that u is a subtype of t - --- quick hack version of TC.eqVal - alpha g t u = case (t,u) of - - -- error (the empty type!) is subtype of any other type - (_,u) | u == typeError -> True - - -- contravariance - (Prod _ x a b, Prod _ y c d) -> alpha g c a && alpha ((x,y):g) b d - - -- record subtyping - (RecType rs, RecType ts) -> all (\ (l,a) -> - any (\ (k,b) -> l == k && alpha g a b) ts) rs - (ExtR r s, ExtR r' s') -> alpha g r r' && alpha g s s' - (ExtR r s, t) -> alpha g r t || alpha g s t - - -- the following say that Ints n is a subset of Int and of Ints m >= n - -- But why does it also allow Int as a subtype of Ints m? /TH 2014-04-04 - (t,u) | Just m <- isTypeInts t, Just n <- isTypeInts u -> m >= n - | Just _ <- isTypeInts t, u == typeInt -> True ---- check size! - | t == typeInt, Just _ <- isTypeInts u -> True ---- why this ???? AR 11/12/2005 - - ---- this should be made in Rename - (Q (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) - || elem n (allExtendsPlus gr m) - || m == n --- for Predef - (QC (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) - || elem n (allExtendsPlus gr m) - (QC (m,a), Q (n,b)) | a == b -> elem m (allExtendsPlus gr n) - || elem n (allExtendsPlus gr m) - (Q (m,a), QC (n,b)) | a == b -> elem m (allExtendsPlus gr n) - || elem n (allExtendsPlus gr m) - - -- contravariance - (Table a b, Table c d) -> alpha g c a && alpha g b d - (Vr x, Vr y) -> x == y || elem (x,y) g || elem (y,x) g - _ -> t == u - --- the following should be one-way coercions only. AR 4/1/2001 - || elem t sTypes && elem u sTypes - || (t == typeType && u == typePType) - || (u == typeType && t == typePType) - - missingLock g t u = case (t,u) of - (RecType rs, RecType ts) -> - let - ls = [l | (l,a) <- rs, - not (any (\ (k,b) -> alpha g a b && l == k) ts)] - (locks,others) = partition isLockLabel ls - in case others of - _:_ -> Bad $ render ("missing record fields:" <+> fsep (punctuate ',' (others))) - _ -> return locks - -- contravariance - (Prod _ x a b, Prod _ y c d) -> do - ls1 <- missingLock g c a - ls2 <- missingLock g b d - return $ ls1 ++ ls2 - - _ -> Bad "" - - sTypes = [typeStr, typeTok, typeString] - --- auxiliaries - --- | light-weight substitution for dep. types -substituteLType :: Context -> Type -> Check Type -substituteLType g t = case t of - Vr x -> return $ maybe t id $ lookup x [(x,t) | (_,x,t) <- g] - _ -> composOp (substituteLType g) t - -termWith :: Term -> Check Type -> Check (Term, Type) -termWith t ct = do - ty <- ct - return (t,ty) - --- | compositional check\/infer of binary operations -check2 :: (Term -> Check Term) -> (Term -> Term -> Term) -> - Term -> Term -> Type -> Check (Term,Type) -check2 chk con a b t = do - a' <- chk a - b' <- chk b - return (con a' b', t) - --- printing a type with a lock field lock_C as C -ppType :: Type -> Doc -ppType ty = - case ty of - RecType fs -> case filter isLockLabel $ map fst fs of - [lock] -> pp (drop 5 (showIdent (label2ident lock))) - _ -> ppTerm Unqualified 0 ty - Prod _ x a b -> ppType a <+> "->" <+> ppType b - _ -> ppTerm Unqualified 0 ty -{- -ppqType :: Type -> Type -> Doc -ppqType t u = case (ppType t, ppType u) of - (pt,pu) | render pt == render pu -> ppTerm Qualified 0 t - (pt,_) -> pt --} -checkLookup :: Ident -> Context -> Check Type -checkLookup x g = - case [ty | (b,y,ty) <- g, x == y] of - [] -> checkError ("unknown variable" <+> x) - (ty:_) -> return ty From 5d7c687cb77ba10fd8a0ae70a605bb02f1ba59cf Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 14:32:39 +0200 Subject: [PATCH 62/75] Make imports in CheckGrammar a little more explicit --- src/compiler/GF/Compile/CheckGrammar.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/GF/Compile/CheckGrammar.hs b/src/compiler/GF/Compile/CheckGrammar.hs index a657fd020..71bce96c4 100644 --- a/src/compiler/GF/Compile/CheckGrammar.hs +++ b/src/compiler/GF/Compile/CheckGrammar.hs @@ -27,9 +27,9 @@ import GF.Infra.Ident import GF.Infra.Option import GF.Compile.TypeCheck.Abstract -import GF.Compile.TypeCheck.Concrete -import qualified GF.Compile.TypeCheck.ConcreteNew as CN -import qualified GF.Compile.Compute.Concrete as CN +import GF.Compile.TypeCheck.Concrete(computeLType,checkLType,inferLType,ppType) +import qualified GF.Compile.TypeCheck.ConcreteNew as CN(checkLType,inferLType) +import qualified GF.Compile.Compute.Concrete as CN(normalForm,resourceValues) import GF.Grammar import GF.Grammar.Lexer From b090e9b0ff9c442396358090f0afa276e5531de5 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 15:31:00 +0200 Subject: [PATCH 63/75] Add --haskell=pgf2 flag --- src/compiler/GF/Compile/PGFtoHaskell.hs | 120 +++++++++++++----------- src/compiler/GF/Infra/Option.hs | 104 ++++++++++---------- 2 files changed, 120 insertions(+), 104 deletions(-) diff --git a/src/compiler/GF/Compile/PGFtoHaskell.hs b/src/compiler/GF/Compile/PGFtoHaskell.hs index 6356c9f6d..bc8e59f57 100644 --- a/src/compiler/GF/Compile/PGFtoHaskell.hs +++ b/src/compiler/GF/Compile/PGFtoHaskell.hs @@ -5,7 +5,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/06/17 12:39:07 $ +-- > CVS $Date: 2005/06/17 12:39:07 $ -- > CVS $Author: bringert $ -- > CVS $Revision: 1.8 $ -- @@ -22,7 +22,7 @@ import PGF.Internal import GF.Data.Operations import GF.Infra.Option -import Data.List --(isPrefixOf, find, intersperse) +import Data.List(isPrefixOf,find,intercalate,intersperse,groupBy,sortBy) import qualified Data.Map as Map type Prefix = String -> String @@ -34,11 +34,12 @@ grammar2haskell :: Options -> PGF -> String grammar2haskell opts name gr = foldr (++++) [] $ - pragmas ++ haskPreamble gadt name derivingClause extraImports ++ + pragmas ++ haskPreamble gadt name derivingClause (extraImports ++ pgfImports) ++ [types, gfinstances gId lexical gr'] ++ compos where gr' = hSkeleton gr gadt = haskellOption opts HaskellGADT dataExt = haskellOption opts HaskellData + pgf2 = haskellOption opts HaskellPGF2 lexical cat = haskellOption opts HaskellLexical && isLexicalCat opts cat gId | haskellOption opts HaskellNoPrefix = rmForbiddenChars | otherwise = ("G"++) . rmForbiddenChars @@ -50,21 +51,23 @@ grammar2haskell opts name gr = foldr (++++) [] $ derivingClause | dataExt = "deriving (Show,Data)" | otherwise = "deriving Show" - extraImports | gadt = ["import Control.Monad.Identity", - "import Data.Monoid"] + extraImports | gadt = ["import Control.Monad.Identity", "import Data.Monoid"] | dataExt = ["import Data.Data"] | otherwise = [] + pgfImports | pgf2 = ["import PGF2 hiding (Tree)", "", "showCId :: CId -> String", "showCId = id"] + | otherwise = ["import PGF hiding (Tree)"] types | gadt = datatypesGADT gId lexical gr' | otherwise = datatypes gId derivingClause lexical gr' compos | gadt = prCompos gId lexical gr' ++ composClass | otherwise = [] -haskPreamble gadt name derivingClause extraImports = +haskPreamble :: Bool -> String -> String -> [String] -> [String] +haskPreamble gadt name derivingClause imports = [ "module " ++ name ++ " where", "" - ] ++ extraImports ++ [ - "import PGF hiding (Tree)", + ] ++ imports ++ [ + "", "----------------------------------------------------", "-- automatic translation from GF to Haskell", "----------------------------------------------------", @@ -85,10 +88,11 @@ haskPreamble gadt name derivingClause extraImports = "" ] +predefInst :: Bool -> String -> String -> String -> String -> String -> String predefInst gadt derivingClause gtyp typ destr consr = (if gadt then [] - else ("newtype" +++ gtyp +++ "=" +++ gtyp +++ typ +++ derivingClause ++ "\n\n") + else "newtype" +++ gtyp +++ "=" +++ gtyp +++ typ +++ derivingClause ++ "\n\n" ) ++ "instance Gf" +++ gtyp +++ "where" ++++ @@ -103,10 +107,10 @@ type OIdent = String type HSkeleton = [(OIdent, [(OIdent, [OIdent])])] datatypes :: Prefix -> DerivingClause -> (OIdent -> Bool) -> (String,HSkeleton) -> String -datatypes gId derivingClause lexical = (foldr (+++++) "") . (filter (/="")) . (map (hDatatype gId derivingClause lexical)) . snd +datatypes gId derivingClause lexical = foldr (+++++) "" . filter (/="") . map (hDatatype gId derivingClause lexical) . snd gfinstances :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> String -gfinstances gId lexical (m,g) = (foldr (+++++) "") $ (filter (/="")) $ (map (gfInstance gId lexical m)) g +gfinstances gId lexical (m,g) = foldr (+++++) "" $ filter (/="") $ map (gfInstance gId lexical m) g hDatatype :: Prefix -> DerivingClause -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> String @@ -131,16 +135,17 @@ nonLexicalRules True rules = [r | r@(f,t) <- rules, not (null t)] lexicalConstructor :: OIdent -> String lexicalConstructor cat = "Lex" ++ cat +predefTypeSkel :: HSkeleton predefTypeSkel = [(c,[]) | c <- ["String", "Int", "Float"]] -- GADT version of data types datatypesGADT :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> String -datatypesGADT gId lexical (_,skel) = unlines $ +datatypesGADT gId lexical (_,skel) = unlines $ concatMap (hCatTypeGADT gId) (skel ++ predefTypeSkel) ++ - [ - "", + [ + "", "data Tree :: * -> * where" - ] ++ + ] ++ concatMap (map (" "++) . hDatatypeGADT gId lexical) skel ++ [ " GString :: String -> Tree GString_", @@ -164,23 +169,23 @@ hCatTypeGADT gId (cat,rules) "data"+++gId cat++"_"] hDatatypeGADT :: Prefix -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> [String] -hDatatypeGADT gId lexical (cat, rules) +hDatatypeGADT gId lexical (cat, rules) | isListCat (cat,rules) = [gId cat+++"::"+++"["++gId (elemCat cat)++"]" +++ "->" +++ t] | otherwise = - [ gId f +++ "::" +++ concatMap (\a -> gId a +++ "-> ") args ++ t + [ gId f +++ "::" +++ concatMap (\a -> gId a +++ "-> ") args ++ t | (f,args) <- nonLexicalRules (lexical cat) rules ] ++ if lexical cat then [lexicalConstructor cat +++ ":: String ->"+++ t] else [] where t = "Tree" +++ gId cat ++ "_" hEqGADT :: Prefix -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> [String] hEqGADT gId lexical (cat, rules) - | isListCat (cat,rules) = let r = listr cat in ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ listeqs] + | isListCat (cat,rules) = let r = listr cat in ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ listeqs] | otherwise = ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ eqs r | r <- nonLexicalRules (lexical cat) rules] ++ if lexical cat then ["(" ++ lexicalConstructor cat +++ "x" ++ "," ++ lexicalConstructor cat +++ "y" ++ ") -> x == y"] else [] where patt s (f,xs) = unwords (gId f : mkSVars s (length xs)) - eqs (_,xs) = unwords ("and" : "[" : intersperse "," [x ++ " == " ++ y | + eqs (_,xs) = unwords ("and" : "[" : intersperse "," [x ++ " == " ++ y | (x,y) <- zip (mkSVars "x" (length xs)) (mkSVars "y" (length xs)) ] ++ ["]"]) listr c = (c,["foo"]) -- foo just for length = 1 listeqs = "and [x == y | (x,y) <- zip x1 y1]" @@ -189,25 +194,26 @@ prCompos :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> [String] prCompos gId lexical (_,catrules) = ["instance Compos Tree where", " compos r a f t = case t of"] - ++ + ++ [" " ++ prComposCons (gId f) xs | (c,rs) <- catrules, not (isListCat (c,rs)), - (f,xs) <- rs, not (null xs)] - ++ + (f,xs) <- rs, not (null xs)] + ++ [" " ++ prComposCons (gId c) ["x1"] | (c,rs) <- catrules, isListCat (c,rs)] - ++ + ++ [" _ -> r t"] where - prComposCons f xs = let vs = mkVars (length xs) in + prComposCons f xs = let vs = mkVars (length xs) in f +++ unwords vs +++ "->" +++ rhs f (zip vs xs) rhs f vcs = "r" +++ f +++ unwords (map (prRec f) vcs) - prRec f (v,c) + prRec f (v,c) | isList f = "`a` foldr (a . a (r (:)) . f) (r [])" +++ v | otherwise = "`a`" +++ "f" +++ v - isList f = (gId "List") `isPrefixOf` f + isList f = gId "List" `isPrefixOf` f gfInstance :: Prefix -> (OIdent -> Bool) -> String -> (OIdent, [(OIdent, [OIdent])]) -> String gfInstance gId lexical m crs = hInstance gId lexical m crs ++++ fInstance gId lexical m crs +hInstance :: (String -> String) -> (String -> Bool) -> String -> (String, [(OIdent, [OIdent])]) -> String ----hInstance m ("Cn",_) = "" --- seems to belong to an old applic. AR 18/5/2004 hInstance gId _ m (cat,[]) = unlines [ "instance Show" +++ gId cat, @@ -216,15 +222,15 @@ hInstance gId _ m (cat,[]) = unlines [ " gf _ = undefined", " fg _ = undefined" ] -hInstance gId lexical m (cat,rules) +hInstance gId lexical m (cat,rules) | isListCat (cat,rules) = "instance Gf" +++ gId cat +++ "where" ++++ - " gf (" ++ gId cat +++ "[" ++ concat (intersperse "," baseVars) ++ "])" + " gf (" ++ gId cat +++ "[" ++ intercalate "," baseVars ++ "])" +++ "=" +++ mkRHS ("Base"++ec) baseVars ++++ - " gf (" ++ gId cat +++ "(x:xs)) = " - ++ mkRHS ("Cons"++ec) ["x",prParenth (gId cat+++"xs")] + " gf (" ++ gId cat +++ "(x:xs)) = " + ++ mkRHS ("Cons"++ec) ["x",prParenth (gId cat+++"xs")] -- no show for GADTs --- ++++ " gf (" ++ gId cat +++ "xs) = error (\"Bad " ++ cat ++ " value: \" ++ show xs)" +-- ++++ " gf (" ++ gId cat +++ "xs) = error (\"Bad " ++ cat ++ " value: \" ++ show xs)" | otherwise = "instance Gf" +++ gId cat +++ "where\n" ++ unlines ([mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] @@ -233,19 +239,22 @@ hInstance gId lexical m (cat,rules) ec = elemCat cat baseVars = mkVars (baseSize (cat,rules)) mkInst f xx = let xx' = mkVars (length xx) in " gf " ++ - (if length xx == 0 then gId f else prParenth (gId f +++ foldr1 (+++) xx')) +++ + (if null xx then gId f else prParenth (gId f +++ foldr1 (+++) xx')) +++ "=" +++ mkRHS f xx' - mkRHS f vars = "mkApp (mkCId \"" ++ f ++ "\")" +++ - "[" ++ prTList ", " ["gf" +++ x | x <- vars] ++ "]" + mkRHS f vars = "mkApp (mkCId \"" ++ f ++ "\")" +++ + "[" ++ prTList ", " ["gf" +++ x | x <- vars] ++ "]" +mkVars :: Int -> [String] mkVars = mkSVars "x" + +mkSVars :: String -> Int -> [String] mkSVars s n = [s ++ show i | i <- [1..n]] ----fInstance m ("Cn",_) = "" --- fInstance _ _ m (cat,[]) = "" fInstance gId lexical m (cat,rules) = " fg t =" ++++ - (if isList + (if isList then " " ++ gId cat ++ " (fgs t) where\n fgs t = case unApp t of" else " case unApp t of") ++++ unlines [mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] ++++ @@ -257,27 +266,28 @@ fInstance gId lexical m (cat,rules) = " Just (i," ++ "[" ++ prTList "," xx' ++ "])" +++ "| i == mkCId \"" ++ f ++ "\" ->" +++ mkRHS f xx' - where xx' = ["x" ++ show i | (_,i) <- zip xx [1..]] - mkRHS f vars - | isList = - if "Base" `isPrefixOf` f - then "[" ++ prTList ", " [ "fg" +++ x | x <- vars ] ++ "]" - else "fg" +++ (vars !! 0) +++ ":" +++ "fgs" +++ (vars !! 1) - | otherwise = - gId f +++ - prTList " " [prParenth ("fg" +++ x) | x <- vars] + where + xx' = ["x" ++ show i | (_,i) <- zip xx [1..]] + mkRHS f vars + | isList = + if "Base" `isPrefixOf` f + then "[" ++ prTList ", " [ "fg" +++ x | x <- vars ] ++ "]" + else "fg" +++ (vars !! 0) +++ ":" +++ "fgs" +++ (vars !! 1) + | otherwise = + gId f +++ + prTList " " [prParenth ("fg" +++ x) | x <- vars] --type HSkeleton = [(OIdent, [(OIdent, [OIdent])])] hSkeleton :: PGF -> (String,HSkeleton) -hSkeleton gr = - (showCId (absname gr), - let fs = - [(showCId c, [(showCId f, map showCId cs) | (f, (cs,_)) <- fs]) | +hSkeleton gr = + (showCId (absname gr), + let fs = + [(showCId c, [(showCId f, map showCId cs) | (f, (cs,_)) <- fs]) | fs@((_, (_,c)):_) <- fns] - in fs ++ [(sc, []) | c <- cts, let sc = showCId c, notElem sc (["Int", "Float", "String"] ++ map fst fs)] + in fs ++ [(sc, []) | c <- cts, let sc = showCId c, sc `notElem` (["Int", "Float", "String"] ++ map fst fs)] ) where - cts = Map.keys (cats (abstract gr)) + cts = Map.keys (cats (abstract gr)) fns = groupBy valtypg (sortBy valtyps (map jty (Map.assocs (funs (abstract gr))))) valtyps (_, (_,x)) (_, (_,y)) = compare x y valtypg (_, (_,x)) (_, (_,y)) = x == y @@ -291,9 +301,10 @@ updateSkeleton cat skel rule = -} isListCat :: (OIdent, [(OIdent, [OIdent])]) -> Bool isListCat (cat,rules) = "List" `isPrefixOf` cat && length rules == 2 - && ("Base"++c) `elem` fs && ("Cons"++c) `elem` fs - where c = elemCat cat - fs = map fst rules + && ("Base"++c) `elem` fs && ("Cons"++c) `elem` fs + where + c = elemCat cat + fs = map fst rules -- | Gets the element category of a list category. elemCat :: OIdent -> OIdent @@ -310,7 +321,7 @@ baseSize (_,rules) = length bs where Just (_,bs) = find (("Base" `isPrefixOf`) . fst) rules composClass :: [String] -composClass = +composClass = [ "", "class Compos t where", @@ -337,4 +348,3 @@ composClass = "", "newtype C b a = C { unC :: b }" ] - diff --git a/src/compiler/GF/Infra/Option.hs b/src/compiler/GF/Infra/Option.hs index 6b7ff0cad..2a2ffd176 100644 --- a/src/compiler/GF/Infra/Option.hs +++ b/src/compiler/GF/Infra/Option.hs @@ -2,13 +2,13 @@ module GF.Infra.Option ( -- ** Command line options -- *** Option types - Options, - Flags(..), - Mode(..), Phase(..), Verbosity(..), - OutputFormat(..), + Options, + Flags(..), + Mode(..), Phase(..), Verbosity(..), + OutputFormat(..), SISRFormat(..), Optimization(..), CFGTransform(..), HaskellOption(..), Dump(..), Pass(..), Recomp(..), - outputFormatsExpl, + outputFormatsExpl, -- *** Option parsing parseOptions, parseModuleOptions, fixRelativeLibPaths, -- *** Option pretty-printing @@ -47,7 +47,7 @@ import PGF.Internal(Literal(..)) import qualified Control.Monad.Fail as Fail usageHeader :: String -usageHeader = unlines +usageHeader = unlines ["Usage: gf [OPTIONS] [FILE [...]]", "", "How each FILE is handled depends on the file name suffix:", @@ -90,10 +90,10 @@ data Phase = Preproc | Convert | Compile | Link data OutputFormat = FmtPGFPretty | FmtCanonicalGF | FmtCanonicalJson - | FmtJavaScript + | FmtJavaScript | FmtJSON - | FmtPython - | FmtHaskell + | FmtPython + | FmtHaskell | FmtJava | FmtProlog | FmtBNF @@ -102,37 +102,42 @@ data OutputFormat = FmtPGFPretty | FmtNoLR | FmtSRGS_XML | FmtSRGS_XML_NonRec - | FmtSRGS_ABNF + | FmtSRGS_ABNF | FmtSRGS_ABNF_NonRec - | FmtJSGF - | FmtGSL + | FmtJSGF + | FmtGSL | FmtVoiceXML | FmtSLF | FmtRegExp | FmtFA deriving (Eq,Ord) -data SISRFormat = +data SISRFormat = -- | SISR Working draft 1 April 2003 -- - SISR_WD20030401 + SISR_WD20030401 | SISR_1_0 deriving (Show,Eq,Ord) data Optimization = OptStem | OptCSE | OptExpand | OptParametrize deriving (Show,Eq,Ord) -data CFGTransform = CFGNoLR +data CFGTransform = CFGNoLR | CFGRegular - | CFGTopDownFilter - | CFGBottomUpFilter + | CFGTopDownFilter + | CFGBottomUpFilter | CFGStartCatOnly | CFGMergeIdentical | CFGRemoveCycles deriving (Show,Eq,Ord) -data HaskellOption = HaskellNoPrefix | HaskellGADT | HaskellLexical - | HaskellConcrete | HaskellVariants | HaskellData +data HaskellOption = HaskellNoPrefix + | HaskellGADT + | HaskellLexical + | HaskellConcrete + | HaskellVariants + | HaskellData + | HaskellPGF2 deriving (Show,Eq,Ord) data Warning = WarnMissingLincat @@ -196,7 +201,7 @@ instance Show Options where parseOptions :: ErrorMonad err => [String] -- ^ list of string arguments -> err (Options, [FilePath]) -parseOptions args +parseOptions args | not (null errs) = errors errs | otherwise = do opts <- concatOptions `fmap` liftErr (sequence optss) return (opts, files) @@ -208,7 +213,7 @@ parseModuleOptions :: ErrorMonad err => -> err Options parseModuleOptions args = do (opts,nonopts) <- parseOptions args - if null nonopts + if null nonopts then return opts else errors $ map ("Non-option among module options: " ++) nonopts @@ -281,7 +286,7 @@ defaultFlags = Flags { optOptimizations = Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize], optOptimizePGF = False, optSplitPGF = False, - optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter, + optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter, CFGTopDownFilter, CFGMergeIdentical], optLibraryPath = [], optStartCat = Nothing, @@ -301,7 +306,7 @@ defaultFlags = Flags { -- | Option descriptions {-# NOINLINE optDescr #-} optDescr :: [OptDescr (Err Options)] -optDescr = +optDescr = [ Option ['?','h'] ["help"] (NoArg (mode ModeHelp)) "Show help message.", Option ['V'] ["version"] (NoArg (mode ModeVersion)) "Display GF version number.", @@ -327,44 +332,44 @@ optDescr = -- Option ['t'] ["trace"] (NoArg (trace True)) "Trace computations", -- Option [] ["no-trace"] (NoArg (trace False)) "Don't trace computations", Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').", - Option ['f'] ["output-format"] (ReqArg outFmt "FMT") + Option ['f'] ["output-format"] (ReqArg outFmt "FMT") (unlines ["Output format. FMT can be one of:", "Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)", "Multiple concrete: pgf (default), json, js, pgf_pretty, prolog, python, ...", -- gar, "Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf, "Abstract only: haskell, ..."]), -- prolog_abs, - Option [] ["sisr"] (ReqArg sisrFmt "FMT") + Option [] ["sisr"] (ReqArg sisrFmt "FMT") (unlines ["Include SISR tags in generated speech recognition grammars.", "FMT can be one of: old, 1.0"]), - Option [] ["haskell"] (ReqArg hsOption "OPTION") - ("Turn on an optional feature when generating Haskell data types. OPTION = " + Option [] ["haskell"] (ReqArg hsOption "OPTION") + ("Turn on an optional feature when generating Haskell data types. OPTION = " ++ concat (intersperse " | " (map fst haskellOptionNames))), - Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]") + Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]") "Treat CAT as a lexical category.", - Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]") + Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]") "Treat CAT as a literal category.", - Option ['D'] ["output-dir"] (ReqArg outDir "DIR") + Option ['D'] ["output-dir"] (ReqArg outDir "DIR") "Save output files (other than .gfo files) in DIR.", - Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR") + Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR") "Overrides the value of GF_LIB_PATH.", - Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp)) + Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp)) "Always recompile from source.", - Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer)) + Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer)) "(default) Recompile from source if the source is newer than the .gfo file.", - Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp)) + Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp)) "Never recompile from source, if there is already .gfo file.", Option [] ["retain"] (NoArg (set $ \o -> o { optRetainResource = True })) "Retain opers.", Option [] ["probs"] (ReqArg probsFile "file.probs") "Read probabilities from file.", - Option ['n'] ["name"] (ReqArg name "NAME") + Option ['n'] ["name"] (ReqArg name "NAME") (unlines ["Use NAME as the name of the output. This is used in the output file names, ", "with suffixes depending on the formats, and, when relevant, ", "internally in the output."]), Option ['i'] [] (ReqArg addLibDir "DIR") "Add DIR to the library search path.", Option [] ["path"] (ReqArg setLibPath "DIR:DIR:...") "Set the library search path.", - Option [] ["preproc"] (ReqArg preproc "CMD") + Option [] ["preproc"] (ReqArg preproc "CMD") (unlines ["Use CMD to preprocess input files.", "Multiple preprocessors can be used by giving this option multiple times."]), - Option [] ["coding"] (ReqArg coding "ENCODING") + Option [] ["coding"] (ReqArg coding "ENCODING") ("Character encoding of the source grammar, ENCODING = utf8, latin1, cp1251, ..."), Option [] ["startcat"] (ReqArg startcat "CAT") "Grammar start category.", Option [] ["language"] (ReqArg language "LANG") "Set the speech language flag to LANG in the generated grammar.", @@ -372,7 +377,7 @@ optDescr = Option [] ["unlexer"] (ReqArg unlexer "UNLEXER") "Use unlexer UNLEXER.", Option [] ["pmcfg"] (NoArg (pmcfg True)) "Generate PMCFG (default).", Option [] ["no-pmcfg"] (NoArg (pmcfg False)) "Don't generate PMCFG (useful for libraries).", - Option [] ["optimize"] (ReqArg optimize "OPT") + Option [] ["optimize"] (ReqArg optimize "OPT") "Select an optimization package. OPT = all | values | parametrize | none", Option [] ["optimize-pgf"] (NoArg (optimize_pgf True)) "Enable or disable global grammar optimization. This could significantly reduce the size of the final PGF file", @@ -447,7 +452,7 @@ optDescr = optimize x = case lookup x optimizationPackages of Just p -> set $ \o -> o { optOptimizations = p } Nothing -> fail $ "Unknown optimization package: " ++ x - + optimize_pgf x = set $ \o -> o { optOptimizePGF = x } splitPGF x = set $ \o -> o { optSplitPGF = x } @@ -471,7 +476,7 @@ outputFormats :: [(String,OutputFormat)] outputFormats = map fst outputFormatsExpl outputFormatsExpl :: [((String,OutputFormat),String)] -outputFormatsExpl = +outputFormatsExpl = [(("pgf_pretty", FmtPGFPretty),"human-readable pgf"), (("canonical_gf", FmtCanonicalGF),"Canonical GF source files"), (("canonical_json", FmtCanonicalJson),"Canonical JSON source files"), @@ -504,11 +509,11 @@ instance Read OutputFormat where readsPrec = lookupReadsPrec outputFormats optimizationPackages :: [(String, Set Optimization)] -optimizationPackages = +optimizationPackages = [("all", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), ("values", Set.fromList [OptStem,OptCSE,OptExpand]), ("noexpand", Set.fromList [OptStem,OptCSE]), - + -- deprecated ("all_subs", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), ("parametrize", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), @@ -516,7 +521,7 @@ optimizationPackages = ] cfgTransformNames :: [(String, CFGTransform)] -cfgTransformNames = +cfgTransformNames = [("nolr", CFGNoLR), ("regular", CFGRegular), ("topdown", CFGTopDownFilter), @@ -532,7 +537,8 @@ haskellOptionNames = ("lexical", HaskellLexical), ("concrete", HaskellConcrete), ("variants", HaskellVariants), - ("data", HaskellData)] + ("data", HaskellData), + ("pgf2", HaskellPGF2)] -- | This is for bacward compatibility. Since GHC 6.12 we -- started using the native Unicode support in GHC but it @@ -558,7 +564,7 @@ onOff f def = OptArg g "[on,off]" _ -> fail $ "Expected [on,off], got: " ++ show x readOutputFormat :: Fail.MonadFail m => String -> m OutputFormat -readOutputFormat s = +readOutputFormat s = maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats -- FIXME: this is a copy of the function in GF.Devel.UseIO. @@ -570,7 +576,7 @@ splitInModuleSearchPath s = case break isPathSep s of isPathSep :: Char -> Bool isPathSep c = c == ':' || c == ';' --- +-- -- * Convenience functions for checking options -- @@ -592,7 +598,7 @@ isLiteralCat opts c = Set.member c (flag optLiteralCats opts) isLexicalCat :: Options -> String -> Bool isLexicalCat opts c = Set.member c (flag optLexicalCats opts) --- +-- -- * Convenience functions for setting options -- @@ -623,8 +629,8 @@ readMaybe s = case reads s of toEnumBounded :: (Bounded a, Enum a, Ord a) => Int -> Maybe a toEnumBounded i = let mi = minBound - ma = maxBound `asTypeOf` mi - in if i >= fromEnum mi && i <= fromEnum ma + ma = maxBound `asTypeOf` mi + in if i >= fromEnum mi && i <= fromEnum ma then Just (toEnum i `asTypeOf` mi) else Nothing From d53e1713c7860de8a5c256ffe0eed81d5388ae41 Mon Sep 17 00:00:00 2001 From: Meowyam Date: Fri, 2 Jul 2021 16:08:34 +0800 Subject: [PATCH 64/75] resolves GrammaticalFramework/gf-core/#97 --- src/compiler/GF/Command/CommonCommands.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/GF/Command/CommonCommands.hs b/src/compiler/GF/Command/CommonCommands.hs index 0b698e79c..578331e65 100644 --- a/src/compiler/GF/Command/CommonCommands.hs +++ b/src/compiler/GF/Command/CommonCommands.hs @@ -170,10 +170,13 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [ restrictedSystem $ syst ++ " <" ++ tmpi ++ " >" ++ tmpo fmap fromString $ restricted $ readFile tmpo, -} - fmap fromString . restricted . readShellProcess syst $ toString arg, + fmap (fromStrings . lines) . restricted . readShellProcess syst . unlines $ toStrings arg, flags = [ ("command","the system command applied to the argument") ], + options = [ + ("lines","preserve input lines, and return output as a list of lines") + ], examples = [ mkEx "gt | l | ? wc -- generate trees, linearize, and count words" ] From 12c564f97c13d644590b86c8e26b80d962bd1773 Mon Sep 17 00:00:00 2001 From: 2jacobtan Date: Tue, 6 Jul 2021 05:00:18 +0800 Subject: [PATCH 65/75] specify version bounds in gf.cabal --- gf.cabal | 58 +++++++++++++++++++++++++------------------- stack-ghc8.10.4.yaml | 14 +++++++++++ stack.yaml | 15 +----------- 3 files changed, 48 insertions(+), 39 deletions(-) create mode 100644 stack-ghc8.10.4.yaml diff --git a/gf.cabal b/gf.cabal index 9a9e3903e..0eba0ead3 100644 --- a/gf.cabal +++ b/gf.cabal @@ -1,7 +1,7 @@ name: gf -version: 3.10.4-git +version: 3.11.0-git -cabal-version: >= 1.22 +cabal-version: 1.22 build-type: Custom license: OtherLicense license-file: LICENSE @@ -11,7 +11,7 @@ description: GF, Grammatical Framework, is a programming language for multilingu homepage: http://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues maintainer: Thomas Hallgren -tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3 +tested-with: GHC==8.0.2, GHC==8.10.4 data-dir: src extra-source-files: WebSetup.hs @@ -74,20 +74,22 @@ flag c-runtime library default-language: Haskell2010 - build-depends: base >= 4.6 && <5, - array, - containers, - bytestring, - utf8-string, - random, - pretty, - mtl, - 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 + build-depends: + -- | GHC 8.0.2 to GHC 8.10.4 + base >= 4.9.1 && <4.15, + array >= 0.5.1 && < 0.6, + containers >= 0.5.7 && < 0.7, + bytestring >= 0.10.8 && < 0.11, + utf8-string >= 1.0.1.1 && < 1.1, + random >= 1.1 && < 1.3, + pretty >= 1.1.3 && < 1.2, + mtl >= 2.2.1 && < 2.3, + exceptions >= 0.8.3 && < 0.11, + fail >= 4.9.0 && < 4.10, + -- 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 >= 0.5.1.4 && < 0.7, + ghc-prim >= 0.5.0 && < 0.7 hs-source-dirs: src/runtime/haskell other-modules: @@ -146,8 +148,14 @@ library ---- GF compiler as a library: - build-depends: filepath, directory>=1.2, time, - process, haskeline, parallel>=3, json + build-depends: + filepath >= 1.4.1 && < 1.5, + directory >= 1.3.0 && < 1.4, + time >= 1.6.0 && < 1.10, + process >= 1.4.3 && < 1.7, + haskeline >= 0.7.3 && < 0.9, + parallel >= 3.2.1.1 && < 3.3, + json >= 0.9.1 && < 0.11 hs-source-dirs: src/compiler exposed-modules: @@ -274,12 +282,12 @@ library cpp-options: -DC_RUNTIME if flag(server) - build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7, - cgi>=3001.2.2.0 + build-depends: httpd-shed >= 0.4.0 && < 0.5, network>=2.3 && <2.7, + cgi >= 3001.3.0.2 && < 3001.6 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 && <2.7 else - build-depends: network<2.6 + build-depends: network >= 2.5 && <2.6 cpp-options: -DSERVER_MODE other-modules: @@ -313,9 +321,9 @@ library ghc-options: -fno-warn-tabs if os(windows) - build-depends: Win32 + build-depends: Win32 >= 2.3.1.1 && < 2.7 else - build-depends: unix, terminfo>=0.4 + build-depends: unix >= 2.7.2 && < 2.8, terminfo >=0.4.0 && < 0.5 if impl(ghc>=8.2) ghc-options: -fhide-source-paths diff --git a/stack-ghc8.10.4.yaml b/stack-ghc8.10.4.yaml new file mode 100644 index 000000000..b10f66e4f --- /dev/null +++ b/stack-ghc8.10.4.yaml @@ -0,0 +1,14 @@ +resolver: lts-18.0 # ghc 8.10.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 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib diff --git a/stack.yaml b/stack.yaml index 69b8c8790..cfb0330a0 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,16 +1,3 @@ -# This default stack file is a copy of stack-ghc8.6.5.yaml -# But committing a symlink can be problematic on Windows, so it's a real copy. -# See: https://github.com/GrammaticalFramework/gf-core/pull/106 -resolver: lts-14.27 # ghc 8.6.5 +resolver: lts-9.21 # ghc 8.0.2 -extra-deps: -- network-2.6.3.6 -- httpd-shed-0.4.0.3 -- cgi-3001.5.0.0 - -# flags: -# gf: -# c-runtime: true -# extra-lib-dirs: -# - /usr/local/lib From be231584f61a1c6134b6163b1198be556fafc0fb Mon Sep 17 00:00:00 2001 From: 2jacobtan Date: Tue, 6 Jul 2021 05:20:09 +0800 Subject: [PATCH 66/75] set stack.yaml to lts-18.0 --- stack.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/stack.yaml b/stack.yaml index cfb0330a0..3a79afdf0 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,3 +1,18 @@ +# This default stack file is a copy of stack-ghc8.10.4.yaml +# But committing a symlink can be problematic on Windows, so it's a real copy. +# See: https://github.com/GrammaticalFramework/gf-core/pull/106 -resolver: lts-9.21 # ghc 8.0.2 +resolver: lts-18.0 # ghc 8.10.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 + +# flags: +# gf: +# c-runtime: true +# extra-lib-dirs: +# - /usr/local/lib From e1a40640cd55b6047f2aa36bf3394017d8867fd6 Mon Sep 17 00:00:00 2001 From: 2jacobtan Date: Tue, 6 Jul 2021 05:42:34 +0800 Subject: [PATCH 67/75] specify version bounds in pgf.cabal and pgf2.cabal --- src/runtime/haskell-bind/pgf2.cabal | 6 +++--- src/runtime/haskell/pgf.cabal | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/runtime/haskell-bind/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal index c8d5d8c6c..fcd854d72 100644 --- a/src/runtime/haskell-bind/pgf2.cabal +++ b/src/runtime/haskell-bind/pgf2.cabal @@ -23,9 +23,9 @@ library PGF2.Expr, PGF2.Type build-depends: - base >=4.3 && <5, - containers, - pretty + base >= 4.9.1 && <4.15, + containers >= 0.5.7 && < 0.7, + pretty >= 1.1.3 && < 1.2 default-language: Haskell2010 build-tools: hsc2hs extra-libraries: pgf gu diff --git a/src/runtime/haskell/pgf.cabal b/src/runtime/haskell/pgf.cabal index f829a6e35..9a59502c4 100644 --- a/src/runtime/haskell/pgf.cabal +++ b/src/runtime/haskell/pgf.cabal @@ -14,16 +14,16 @@ tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC==8.4.4 library default-language: Haskell2010 build-depends: - array, - base >= 4.6 && <5, - bytestring, - containers, + base >= 4.9.1 && <4.15, + array >= 0.5.1 && < 0.6, + containers >= 0.5.7 && < 0.7, + bytestring >= 0.10.8 && < 0.11, + utf8-string >= 1.0.1.1 && < 1.1, + random >= 1.1 && < 1.3, + pretty >= 1.1.3 && < 1.2, + mtl >= 2.2.1 && < 2.3, + ghc-prim >= 0.5.0 && < 0.7 -- exceptions, - ghc-prim, - mtl, - pretty, - random, - utf8-string other-modules: -- not really part of GF but I have changed the original binary library From dff1193f7b7a9f186835de80ca96471034abf182 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Thu, 1 Jul 2021 15:31:00 +0200 Subject: [PATCH 68/75] Add --haskell=pgf2 flag --- src/compiler/GF/Compile/PGFtoHaskell.hs | 120 +++++++++++++----------- src/compiler/GF/Infra/Option.hs | 104 ++++++++++---------- 2 files changed, 120 insertions(+), 104 deletions(-) diff --git a/src/compiler/GF/Compile/PGFtoHaskell.hs b/src/compiler/GF/Compile/PGFtoHaskell.hs index 6356c9f6d..bc8e59f57 100644 --- a/src/compiler/GF/Compile/PGFtoHaskell.hs +++ b/src/compiler/GF/Compile/PGFtoHaskell.hs @@ -5,7 +5,7 @@ -- Stability : (stable) -- Portability : (portable) -- --- > CVS $Date: 2005/06/17 12:39:07 $ +-- > CVS $Date: 2005/06/17 12:39:07 $ -- > CVS $Author: bringert $ -- > CVS $Revision: 1.8 $ -- @@ -22,7 +22,7 @@ import PGF.Internal import GF.Data.Operations import GF.Infra.Option -import Data.List --(isPrefixOf, find, intersperse) +import Data.List(isPrefixOf,find,intercalate,intersperse,groupBy,sortBy) import qualified Data.Map as Map type Prefix = String -> String @@ -34,11 +34,12 @@ grammar2haskell :: Options -> PGF -> String grammar2haskell opts name gr = foldr (++++) [] $ - pragmas ++ haskPreamble gadt name derivingClause extraImports ++ + pragmas ++ haskPreamble gadt name derivingClause (extraImports ++ pgfImports) ++ [types, gfinstances gId lexical gr'] ++ compos where gr' = hSkeleton gr gadt = haskellOption opts HaskellGADT dataExt = haskellOption opts HaskellData + pgf2 = haskellOption opts HaskellPGF2 lexical cat = haskellOption opts HaskellLexical && isLexicalCat opts cat gId | haskellOption opts HaskellNoPrefix = rmForbiddenChars | otherwise = ("G"++) . rmForbiddenChars @@ -50,21 +51,23 @@ grammar2haskell opts name gr = foldr (++++) [] $ derivingClause | dataExt = "deriving (Show,Data)" | otherwise = "deriving Show" - extraImports | gadt = ["import Control.Monad.Identity", - "import Data.Monoid"] + extraImports | gadt = ["import Control.Monad.Identity", "import Data.Monoid"] | dataExt = ["import Data.Data"] | otherwise = [] + pgfImports | pgf2 = ["import PGF2 hiding (Tree)", "", "showCId :: CId -> String", "showCId = id"] + | otherwise = ["import PGF hiding (Tree)"] types | gadt = datatypesGADT gId lexical gr' | otherwise = datatypes gId derivingClause lexical gr' compos | gadt = prCompos gId lexical gr' ++ composClass | otherwise = [] -haskPreamble gadt name derivingClause extraImports = +haskPreamble :: Bool -> String -> String -> [String] -> [String] +haskPreamble gadt name derivingClause imports = [ "module " ++ name ++ " where", "" - ] ++ extraImports ++ [ - "import PGF hiding (Tree)", + ] ++ imports ++ [ + "", "----------------------------------------------------", "-- automatic translation from GF to Haskell", "----------------------------------------------------", @@ -85,10 +88,11 @@ haskPreamble gadt name derivingClause extraImports = "" ] +predefInst :: Bool -> String -> String -> String -> String -> String -> String predefInst gadt derivingClause gtyp typ destr consr = (if gadt then [] - else ("newtype" +++ gtyp +++ "=" +++ gtyp +++ typ +++ derivingClause ++ "\n\n") + else "newtype" +++ gtyp +++ "=" +++ gtyp +++ typ +++ derivingClause ++ "\n\n" ) ++ "instance Gf" +++ gtyp +++ "where" ++++ @@ -103,10 +107,10 @@ type OIdent = String type HSkeleton = [(OIdent, [(OIdent, [OIdent])])] datatypes :: Prefix -> DerivingClause -> (OIdent -> Bool) -> (String,HSkeleton) -> String -datatypes gId derivingClause lexical = (foldr (+++++) "") . (filter (/="")) . (map (hDatatype gId derivingClause lexical)) . snd +datatypes gId derivingClause lexical = foldr (+++++) "" . filter (/="") . map (hDatatype gId derivingClause lexical) . snd gfinstances :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> String -gfinstances gId lexical (m,g) = (foldr (+++++) "") $ (filter (/="")) $ (map (gfInstance gId lexical m)) g +gfinstances gId lexical (m,g) = foldr (+++++) "" $ filter (/="") $ map (gfInstance gId lexical m) g hDatatype :: Prefix -> DerivingClause -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> String @@ -131,16 +135,17 @@ nonLexicalRules True rules = [r | r@(f,t) <- rules, not (null t)] lexicalConstructor :: OIdent -> String lexicalConstructor cat = "Lex" ++ cat +predefTypeSkel :: HSkeleton predefTypeSkel = [(c,[]) | c <- ["String", "Int", "Float"]] -- GADT version of data types datatypesGADT :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> String -datatypesGADT gId lexical (_,skel) = unlines $ +datatypesGADT gId lexical (_,skel) = unlines $ concatMap (hCatTypeGADT gId) (skel ++ predefTypeSkel) ++ - [ - "", + [ + "", "data Tree :: * -> * where" - ] ++ + ] ++ concatMap (map (" "++) . hDatatypeGADT gId lexical) skel ++ [ " GString :: String -> Tree GString_", @@ -164,23 +169,23 @@ hCatTypeGADT gId (cat,rules) "data"+++gId cat++"_"] hDatatypeGADT :: Prefix -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> [String] -hDatatypeGADT gId lexical (cat, rules) +hDatatypeGADT gId lexical (cat, rules) | isListCat (cat,rules) = [gId cat+++"::"+++"["++gId (elemCat cat)++"]" +++ "->" +++ t] | otherwise = - [ gId f +++ "::" +++ concatMap (\a -> gId a +++ "-> ") args ++ t + [ gId f +++ "::" +++ concatMap (\a -> gId a +++ "-> ") args ++ t | (f,args) <- nonLexicalRules (lexical cat) rules ] ++ if lexical cat then [lexicalConstructor cat +++ ":: String ->"+++ t] else [] where t = "Tree" +++ gId cat ++ "_" hEqGADT :: Prefix -> (OIdent -> Bool) -> (OIdent, [(OIdent, [OIdent])]) -> [String] hEqGADT gId lexical (cat, rules) - | isListCat (cat,rules) = let r = listr cat in ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ listeqs] + | isListCat (cat,rules) = let r = listr cat in ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ listeqs] | otherwise = ["(" ++ patt "x" r ++ "," ++ patt "y" r ++ ") -> " ++ eqs r | r <- nonLexicalRules (lexical cat) rules] ++ if lexical cat then ["(" ++ lexicalConstructor cat +++ "x" ++ "," ++ lexicalConstructor cat +++ "y" ++ ") -> x == y"] else [] where patt s (f,xs) = unwords (gId f : mkSVars s (length xs)) - eqs (_,xs) = unwords ("and" : "[" : intersperse "," [x ++ " == " ++ y | + eqs (_,xs) = unwords ("and" : "[" : intersperse "," [x ++ " == " ++ y | (x,y) <- zip (mkSVars "x" (length xs)) (mkSVars "y" (length xs)) ] ++ ["]"]) listr c = (c,["foo"]) -- foo just for length = 1 listeqs = "and [x == y | (x,y) <- zip x1 y1]" @@ -189,25 +194,26 @@ prCompos :: Prefix -> (OIdent -> Bool) -> (String,HSkeleton) -> [String] prCompos gId lexical (_,catrules) = ["instance Compos Tree where", " compos r a f t = case t of"] - ++ + ++ [" " ++ prComposCons (gId f) xs | (c,rs) <- catrules, not (isListCat (c,rs)), - (f,xs) <- rs, not (null xs)] - ++ + (f,xs) <- rs, not (null xs)] + ++ [" " ++ prComposCons (gId c) ["x1"] | (c,rs) <- catrules, isListCat (c,rs)] - ++ + ++ [" _ -> r t"] where - prComposCons f xs = let vs = mkVars (length xs) in + prComposCons f xs = let vs = mkVars (length xs) in f +++ unwords vs +++ "->" +++ rhs f (zip vs xs) rhs f vcs = "r" +++ f +++ unwords (map (prRec f) vcs) - prRec f (v,c) + prRec f (v,c) | isList f = "`a` foldr (a . a (r (:)) . f) (r [])" +++ v | otherwise = "`a`" +++ "f" +++ v - isList f = (gId "List") `isPrefixOf` f + isList f = gId "List" `isPrefixOf` f gfInstance :: Prefix -> (OIdent -> Bool) -> String -> (OIdent, [(OIdent, [OIdent])]) -> String gfInstance gId lexical m crs = hInstance gId lexical m crs ++++ fInstance gId lexical m crs +hInstance :: (String -> String) -> (String -> Bool) -> String -> (String, [(OIdent, [OIdent])]) -> String ----hInstance m ("Cn",_) = "" --- seems to belong to an old applic. AR 18/5/2004 hInstance gId _ m (cat,[]) = unlines [ "instance Show" +++ gId cat, @@ -216,15 +222,15 @@ hInstance gId _ m (cat,[]) = unlines [ " gf _ = undefined", " fg _ = undefined" ] -hInstance gId lexical m (cat,rules) +hInstance gId lexical m (cat,rules) | isListCat (cat,rules) = "instance Gf" +++ gId cat +++ "where" ++++ - " gf (" ++ gId cat +++ "[" ++ concat (intersperse "," baseVars) ++ "])" + " gf (" ++ gId cat +++ "[" ++ intercalate "," baseVars ++ "])" +++ "=" +++ mkRHS ("Base"++ec) baseVars ++++ - " gf (" ++ gId cat +++ "(x:xs)) = " - ++ mkRHS ("Cons"++ec) ["x",prParenth (gId cat+++"xs")] + " gf (" ++ gId cat +++ "(x:xs)) = " + ++ mkRHS ("Cons"++ec) ["x",prParenth (gId cat+++"xs")] -- no show for GADTs --- ++++ " gf (" ++ gId cat +++ "xs) = error (\"Bad " ++ cat ++ " value: \" ++ show xs)" +-- ++++ " gf (" ++ gId cat +++ "xs) = error (\"Bad " ++ cat ++ " value: \" ++ show xs)" | otherwise = "instance Gf" +++ gId cat +++ "where\n" ++ unlines ([mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] @@ -233,19 +239,22 @@ hInstance gId lexical m (cat,rules) ec = elemCat cat baseVars = mkVars (baseSize (cat,rules)) mkInst f xx = let xx' = mkVars (length xx) in " gf " ++ - (if length xx == 0 then gId f else prParenth (gId f +++ foldr1 (+++) xx')) +++ + (if null xx then gId f else prParenth (gId f +++ foldr1 (+++) xx')) +++ "=" +++ mkRHS f xx' - mkRHS f vars = "mkApp (mkCId \"" ++ f ++ "\")" +++ - "[" ++ prTList ", " ["gf" +++ x | x <- vars] ++ "]" + mkRHS f vars = "mkApp (mkCId \"" ++ f ++ "\")" +++ + "[" ++ prTList ", " ["gf" +++ x | x <- vars] ++ "]" +mkVars :: Int -> [String] mkVars = mkSVars "x" + +mkSVars :: String -> Int -> [String] mkSVars s n = [s ++ show i | i <- [1..n]] ----fInstance m ("Cn",_) = "" --- fInstance _ _ m (cat,[]) = "" fInstance gId lexical m (cat,rules) = " fg t =" ++++ - (if isList + (if isList then " " ++ gId cat ++ " (fgs t) where\n fgs t = case unApp t of" else " case unApp t of") ++++ unlines [mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] ++++ @@ -257,27 +266,28 @@ fInstance gId lexical m (cat,rules) = " Just (i," ++ "[" ++ prTList "," xx' ++ "])" +++ "| i == mkCId \"" ++ f ++ "\" ->" +++ mkRHS f xx' - where xx' = ["x" ++ show i | (_,i) <- zip xx [1..]] - mkRHS f vars - | isList = - if "Base" `isPrefixOf` f - then "[" ++ prTList ", " [ "fg" +++ x | x <- vars ] ++ "]" - else "fg" +++ (vars !! 0) +++ ":" +++ "fgs" +++ (vars !! 1) - | otherwise = - gId f +++ - prTList " " [prParenth ("fg" +++ x) | x <- vars] + where + xx' = ["x" ++ show i | (_,i) <- zip xx [1..]] + mkRHS f vars + | isList = + if "Base" `isPrefixOf` f + then "[" ++ prTList ", " [ "fg" +++ x | x <- vars ] ++ "]" + else "fg" +++ (vars !! 0) +++ ":" +++ "fgs" +++ (vars !! 1) + | otherwise = + gId f +++ + prTList " " [prParenth ("fg" +++ x) | x <- vars] --type HSkeleton = [(OIdent, [(OIdent, [OIdent])])] hSkeleton :: PGF -> (String,HSkeleton) -hSkeleton gr = - (showCId (absname gr), - let fs = - [(showCId c, [(showCId f, map showCId cs) | (f, (cs,_)) <- fs]) | +hSkeleton gr = + (showCId (absname gr), + let fs = + [(showCId c, [(showCId f, map showCId cs) | (f, (cs,_)) <- fs]) | fs@((_, (_,c)):_) <- fns] - in fs ++ [(sc, []) | c <- cts, let sc = showCId c, notElem sc (["Int", "Float", "String"] ++ map fst fs)] + in fs ++ [(sc, []) | c <- cts, let sc = showCId c, sc `notElem` (["Int", "Float", "String"] ++ map fst fs)] ) where - cts = Map.keys (cats (abstract gr)) + cts = Map.keys (cats (abstract gr)) fns = groupBy valtypg (sortBy valtyps (map jty (Map.assocs (funs (abstract gr))))) valtyps (_, (_,x)) (_, (_,y)) = compare x y valtypg (_, (_,x)) (_, (_,y)) = x == y @@ -291,9 +301,10 @@ updateSkeleton cat skel rule = -} isListCat :: (OIdent, [(OIdent, [OIdent])]) -> Bool isListCat (cat,rules) = "List" `isPrefixOf` cat && length rules == 2 - && ("Base"++c) `elem` fs && ("Cons"++c) `elem` fs - where c = elemCat cat - fs = map fst rules + && ("Base"++c) `elem` fs && ("Cons"++c) `elem` fs + where + c = elemCat cat + fs = map fst rules -- | Gets the element category of a list category. elemCat :: OIdent -> OIdent @@ -310,7 +321,7 @@ baseSize (_,rules) = length bs where Just (_,bs) = find (("Base" `isPrefixOf`) . fst) rules composClass :: [String] -composClass = +composClass = [ "", "class Compos t where", @@ -337,4 +348,3 @@ composClass = "", "newtype C b a = C { unC :: b }" ] - diff --git a/src/compiler/GF/Infra/Option.hs b/src/compiler/GF/Infra/Option.hs index 6b7ff0cad..2a2ffd176 100644 --- a/src/compiler/GF/Infra/Option.hs +++ b/src/compiler/GF/Infra/Option.hs @@ -2,13 +2,13 @@ module GF.Infra.Option ( -- ** Command line options -- *** Option types - Options, - Flags(..), - Mode(..), Phase(..), Verbosity(..), - OutputFormat(..), + Options, + Flags(..), + Mode(..), Phase(..), Verbosity(..), + OutputFormat(..), SISRFormat(..), Optimization(..), CFGTransform(..), HaskellOption(..), Dump(..), Pass(..), Recomp(..), - outputFormatsExpl, + outputFormatsExpl, -- *** Option parsing parseOptions, parseModuleOptions, fixRelativeLibPaths, -- *** Option pretty-printing @@ -47,7 +47,7 @@ import PGF.Internal(Literal(..)) import qualified Control.Monad.Fail as Fail usageHeader :: String -usageHeader = unlines +usageHeader = unlines ["Usage: gf [OPTIONS] [FILE [...]]", "", "How each FILE is handled depends on the file name suffix:", @@ -90,10 +90,10 @@ data Phase = Preproc | Convert | Compile | Link data OutputFormat = FmtPGFPretty | FmtCanonicalGF | FmtCanonicalJson - | FmtJavaScript + | FmtJavaScript | FmtJSON - | FmtPython - | FmtHaskell + | FmtPython + | FmtHaskell | FmtJava | FmtProlog | FmtBNF @@ -102,37 +102,42 @@ data OutputFormat = FmtPGFPretty | FmtNoLR | FmtSRGS_XML | FmtSRGS_XML_NonRec - | FmtSRGS_ABNF + | FmtSRGS_ABNF | FmtSRGS_ABNF_NonRec - | FmtJSGF - | FmtGSL + | FmtJSGF + | FmtGSL | FmtVoiceXML | FmtSLF | FmtRegExp | FmtFA deriving (Eq,Ord) -data SISRFormat = +data SISRFormat = -- | SISR Working draft 1 April 2003 -- - SISR_WD20030401 + SISR_WD20030401 | SISR_1_0 deriving (Show,Eq,Ord) data Optimization = OptStem | OptCSE | OptExpand | OptParametrize deriving (Show,Eq,Ord) -data CFGTransform = CFGNoLR +data CFGTransform = CFGNoLR | CFGRegular - | CFGTopDownFilter - | CFGBottomUpFilter + | CFGTopDownFilter + | CFGBottomUpFilter | CFGStartCatOnly | CFGMergeIdentical | CFGRemoveCycles deriving (Show,Eq,Ord) -data HaskellOption = HaskellNoPrefix | HaskellGADT | HaskellLexical - | HaskellConcrete | HaskellVariants | HaskellData +data HaskellOption = HaskellNoPrefix + | HaskellGADT + | HaskellLexical + | HaskellConcrete + | HaskellVariants + | HaskellData + | HaskellPGF2 deriving (Show,Eq,Ord) data Warning = WarnMissingLincat @@ -196,7 +201,7 @@ instance Show Options where parseOptions :: ErrorMonad err => [String] -- ^ list of string arguments -> err (Options, [FilePath]) -parseOptions args +parseOptions args | not (null errs) = errors errs | otherwise = do opts <- concatOptions `fmap` liftErr (sequence optss) return (opts, files) @@ -208,7 +213,7 @@ parseModuleOptions :: ErrorMonad err => -> err Options parseModuleOptions args = do (opts,nonopts) <- parseOptions args - if null nonopts + if null nonopts then return opts else errors $ map ("Non-option among module options: " ++) nonopts @@ -281,7 +286,7 @@ defaultFlags = Flags { optOptimizations = Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize], optOptimizePGF = False, optSplitPGF = False, - optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter, + optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter, CFGTopDownFilter, CFGMergeIdentical], optLibraryPath = [], optStartCat = Nothing, @@ -301,7 +306,7 @@ defaultFlags = Flags { -- | Option descriptions {-# NOINLINE optDescr #-} optDescr :: [OptDescr (Err Options)] -optDescr = +optDescr = [ Option ['?','h'] ["help"] (NoArg (mode ModeHelp)) "Show help message.", Option ['V'] ["version"] (NoArg (mode ModeVersion)) "Display GF version number.", @@ -327,44 +332,44 @@ optDescr = -- Option ['t'] ["trace"] (NoArg (trace True)) "Trace computations", -- Option [] ["no-trace"] (NoArg (trace False)) "Don't trace computations", Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').", - Option ['f'] ["output-format"] (ReqArg outFmt "FMT") + Option ['f'] ["output-format"] (ReqArg outFmt "FMT") (unlines ["Output format. FMT can be one of:", "Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)", "Multiple concrete: pgf (default), json, js, pgf_pretty, prolog, python, ...", -- gar, "Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf, "Abstract only: haskell, ..."]), -- prolog_abs, - Option [] ["sisr"] (ReqArg sisrFmt "FMT") + Option [] ["sisr"] (ReqArg sisrFmt "FMT") (unlines ["Include SISR tags in generated speech recognition grammars.", "FMT can be one of: old, 1.0"]), - Option [] ["haskell"] (ReqArg hsOption "OPTION") - ("Turn on an optional feature when generating Haskell data types. OPTION = " + Option [] ["haskell"] (ReqArg hsOption "OPTION") + ("Turn on an optional feature when generating Haskell data types. OPTION = " ++ concat (intersperse " | " (map fst haskellOptionNames))), - Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]") + Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]") "Treat CAT as a lexical category.", - Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]") + Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]") "Treat CAT as a literal category.", - Option ['D'] ["output-dir"] (ReqArg outDir "DIR") + Option ['D'] ["output-dir"] (ReqArg outDir "DIR") "Save output files (other than .gfo files) in DIR.", - Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR") + Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR") "Overrides the value of GF_LIB_PATH.", - Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp)) + Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp)) "Always recompile from source.", - Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer)) + Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer)) "(default) Recompile from source if the source is newer than the .gfo file.", - Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp)) + Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp)) "Never recompile from source, if there is already .gfo file.", Option [] ["retain"] (NoArg (set $ \o -> o { optRetainResource = True })) "Retain opers.", Option [] ["probs"] (ReqArg probsFile "file.probs") "Read probabilities from file.", - Option ['n'] ["name"] (ReqArg name "NAME") + Option ['n'] ["name"] (ReqArg name "NAME") (unlines ["Use NAME as the name of the output. This is used in the output file names, ", "with suffixes depending on the formats, and, when relevant, ", "internally in the output."]), Option ['i'] [] (ReqArg addLibDir "DIR") "Add DIR to the library search path.", Option [] ["path"] (ReqArg setLibPath "DIR:DIR:...") "Set the library search path.", - Option [] ["preproc"] (ReqArg preproc "CMD") + Option [] ["preproc"] (ReqArg preproc "CMD") (unlines ["Use CMD to preprocess input files.", "Multiple preprocessors can be used by giving this option multiple times."]), - Option [] ["coding"] (ReqArg coding "ENCODING") + Option [] ["coding"] (ReqArg coding "ENCODING") ("Character encoding of the source grammar, ENCODING = utf8, latin1, cp1251, ..."), Option [] ["startcat"] (ReqArg startcat "CAT") "Grammar start category.", Option [] ["language"] (ReqArg language "LANG") "Set the speech language flag to LANG in the generated grammar.", @@ -372,7 +377,7 @@ optDescr = Option [] ["unlexer"] (ReqArg unlexer "UNLEXER") "Use unlexer UNLEXER.", Option [] ["pmcfg"] (NoArg (pmcfg True)) "Generate PMCFG (default).", Option [] ["no-pmcfg"] (NoArg (pmcfg False)) "Don't generate PMCFG (useful for libraries).", - Option [] ["optimize"] (ReqArg optimize "OPT") + Option [] ["optimize"] (ReqArg optimize "OPT") "Select an optimization package. OPT = all | values | parametrize | none", Option [] ["optimize-pgf"] (NoArg (optimize_pgf True)) "Enable or disable global grammar optimization. This could significantly reduce the size of the final PGF file", @@ -447,7 +452,7 @@ optDescr = optimize x = case lookup x optimizationPackages of Just p -> set $ \o -> o { optOptimizations = p } Nothing -> fail $ "Unknown optimization package: " ++ x - + optimize_pgf x = set $ \o -> o { optOptimizePGF = x } splitPGF x = set $ \o -> o { optSplitPGF = x } @@ -471,7 +476,7 @@ outputFormats :: [(String,OutputFormat)] outputFormats = map fst outputFormatsExpl outputFormatsExpl :: [((String,OutputFormat),String)] -outputFormatsExpl = +outputFormatsExpl = [(("pgf_pretty", FmtPGFPretty),"human-readable pgf"), (("canonical_gf", FmtCanonicalGF),"Canonical GF source files"), (("canonical_json", FmtCanonicalJson),"Canonical JSON source files"), @@ -504,11 +509,11 @@ instance Read OutputFormat where readsPrec = lookupReadsPrec outputFormats optimizationPackages :: [(String, Set Optimization)] -optimizationPackages = +optimizationPackages = [("all", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), ("values", Set.fromList [OptStem,OptCSE,OptExpand]), ("noexpand", Set.fromList [OptStem,OptCSE]), - + -- deprecated ("all_subs", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), ("parametrize", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]), @@ -516,7 +521,7 @@ optimizationPackages = ] cfgTransformNames :: [(String, CFGTransform)] -cfgTransformNames = +cfgTransformNames = [("nolr", CFGNoLR), ("regular", CFGRegular), ("topdown", CFGTopDownFilter), @@ -532,7 +537,8 @@ haskellOptionNames = ("lexical", HaskellLexical), ("concrete", HaskellConcrete), ("variants", HaskellVariants), - ("data", HaskellData)] + ("data", HaskellData), + ("pgf2", HaskellPGF2)] -- | This is for bacward compatibility. Since GHC 6.12 we -- started using the native Unicode support in GHC but it @@ -558,7 +564,7 @@ onOff f def = OptArg g "[on,off]" _ -> fail $ "Expected [on,off], got: " ++ show x readOutputFormat :: Fail.MonadFail m => String -> m OutputFormat -readOutputFormat s = +readOutputFormat s = maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats -- FIXME: this is a copy of the function in GF.Devel.UseIO. @@ -570,7 +576,7 @@ splitInModuleSearchPath s = case break isPathSep s of isPathSep :: Char -> Bool isPathSep c = c == ':' || c == ';' --- +-- -- * Convenience functions for checking options -- @@ -592,7 +598,7 @@ isLiteralCat opts c = Set.member c (flag optLiteralCats opts) isLexicalCat :: Options -> String -> Bool isLexicalCat opts c = Set.member c (flag optLexicalCats opts) --- +-- -- * Convenience functions for setting options -- @@ -623,8 +629,8 @@ readMaybe s = case reads s of toEnumBounded :: (Bounded a, Enum a, Ord a) => Int -> Maybe a toEnumBounded i = let mi = minBound - ma = maxBound `asTypeOf` mi - in if i >= fromEnum mi && i <= fromEnum ma + ma = maxBound `asTypeOf` mi + in if i >= fromEnum mi && i <= fromEnum ma then Just (toEnum i `asTypeOf` mi) else Nothing From 173ab96839212e042c38629d45bcd30cc6e111ca Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Sat, 6 Jun 2020 11:35:05 +0200 Subject: [PATCH 69/75] Hotfix for https://github.com/GrammaticalFramework/gf-core/issues/56 --- src/compiler/GF/Compile/Rename.hs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/compiler/GF/Compile/Rename.hs b/src/compiler/GF/Compile/Rename.hs index aacf24c5b..c7ea56b45 100644 --- a/src/compiler/GF/Compile/Rename.hs +++ b/src/compiler/GF/Compile/Rename.hs @@ -39,6 +39,7 @@ import GF.Data.Operations import Control.Monad import Data.List (nub,(\\)) +import qualified Data.List as L import qualified Data.Map as Map import Data.Maybe(mapMaybe) import GF.Text.Pretty @@ -105,7 +106,26 @@ renameIdentTerm' env@(act,imps) t0 = ts@(t:_) -> do checkWarn ("atomic term" <+> ppTerm Qualified 0 t0 $$ "conflict" <+> hsep (punctuate ',' (map (ppTerm Qualified 0) ts)) $$ "given" <+> fsep (punctuate ',' (map fst qualifs))) - return t + return (bestTerm ts) -- Heuristic for resource grammar. Returns t for all others. + where + -- Hotfix for https://github.com/GrammaticalFramework/gf-core/issues/56 + -- Real bug is probably somewhere deeper in recognising excluded functions. /IL 2020-06-06 + notFromCommonModule :: Term -> Bool + notFromCommonModule term = + let t = render $ ppTerm Qualified 0 term :: String + in not $ any (\moduleName -> moduleName `L.isPrefixOf` t) + ["CommonX", "ConstructX", "ExtendFunctor" + ,"MarkHTMLX", "ParamX", "TenseX", "TextX"] + + -- If one of the terms comes from the common modules, + -- we choose the other one, because that's defined in the grammar. + bestTerm :: [Term] -> Term + bestTerm [] = error "constant not found" -- not reached: bestTerm is only called for case ts@(t:_) + bestTerm ts@(t:_) = + let notCommon = [t | t <- ts, notFromCommonModule t] + in case notCommon of + [] -> t -- All terms are from common modules, return first of original list + (u:_) -> u -- ≥1 terms are not from common modules, return first of those info2status :: Maybe ModuleName -> Ident -> Info -> StatusInfo info2status mq c i = case i of From dff215504a71235d0aeb6852e64ef682cc095668 Mon Sep 17 00:00:00 2001 From: Meowyam Date: Tue, 6 Jul 2021 15:00:17 +0800 Subject: [PATCH 70/75] resolves GrammaticalFramework/gf-core/#97, without l --- src/compiler/GF/Command/CommonCommands.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/GF/Command/CommonCommands.hs b/src/compiler/GF/Command/CommonCommands.hs index 578331e65..7ca2c0ee4 100644 --- a/src/compiler/GF/Command/CommonCommands.hs +++ b/src/compiler/GF/Command/CommonCommands.hs @@ -15,6 +15,7 @@ import GF.Command.Abstract --(isOpt,valStrOpts,prOpt) import GF.Text.Pretty import GF.Text.Transliterations import GF.Text.Lexing(stringOp,opInEnv) +import Data.Char (isSpace) import qualified PGF as H(showCId,showExpr,toATree,toTrie,Trie(..)) @@ -170,7 +171,8 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [ restrictedSystem $ syst ++ " <" ++ tmpi ++ " >" ++ tmpo fmap fromString $ restricted $ readFile tmpo, -} - fmap (fromStrings . lines) . restricted . readShellProcess syst . unlines $ toStrings arg, + fmap (fromStrings . lines) . restricted . readShellProcess syst . unlines . map (dropWhile (=='\n')) $ toStrings $ arg, + flags = [ ("command","the system command applied to the argument") ], From 1e3de38ac4e9d4eee8bb947fb16682490a1130c5 Mon Sep 17 00:00:00 2001 From: Meowyam Date: Tue, 6 Jul 2021 15:22:59 +0800 Subject: [PATCH 71/75] remove redundant options --- src/compiler/GF/Command/CommonCommands.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/compiler/GF/Command/CommonCommands.hs b/src/compiler/GF/Command/CommonCommands.hs index 7ca2c0ee4..c685fc525 100644 --- a/src/compiler/GF/Command/CommonCommands.hs +++ b/src/compiler/GF/Command/CommonCommands.hs @@ -176,9 +176,6 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [ flags = [ ("command","the system command applied to the argument") ], - options = [ - ("lines","preserve input lines, and return output as a list of lines") - ], examples = [ mkEx "gt | l | ? wc -- generate trees, linearize, and count words" ] From 84b4b6fab93a2ef9367878a6055595f81552791d Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 6 Jul 2021 14:11:30 +0200 Subject: [PATCH 72/75] Some more cabal file cleanup. Add stack files for pgf, pgf2. --- gf.cabal | 9 ++++----- src/runtime/haskell-bind/pgf2.cabal | 15 +++++++++------ src/runtime/haskell-bind/stack-ghc7.10.3.yaml | 3 +++ src/runtime/haskell-bind/stack-ghc8.0.2.yaml | 1 + src/runtime/haskell-bind/stack-ghc8.10.4.yaml | 1 + src/runtime/haskell/pgf.cabal | 13 +++++++------ src/runtime/haskell/stack-ghc7.10.3.yaml | 3 +++ src/runtime/haskell/stack-ghc8.0.2.yaml | 1 + src/runtime/haskell/stack-ghc8.10.4.yaml | 1 + 9 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 src/runtime/haskell-bind/stack-ghc7.10.3.yaml create mode 100644 src/runtime/haskell-bind/stack-ghc8.0.2.yaml create mode 100644 src/runtime/haskell-bind/stack-ghc8.10.4.yaml create mode 100644 src/runtime/haskell/stack-ghc7.10.3.yaml create mode 100644 src/runtime/haskell/stack-ghc8.0.2.yaml create mode 100644 src/runtime/haskell/stack-ghc8.10.4.yaml diff --git a/gf.cabal b/gf.cabal index 0eba0ead3..b9c7d9631 100644 --- a/gf.cabal +++ b/gf.cabal @@ -8,10 +8,9 @@ license-file: LICENSE category: Natural Language Processing, Compiler synopsis: Grammatical Framework description: GF, Grammatical Framework, is a programming language for multilingual grammar applications -homepage: http://www.grammaticalframework.org/ +homepage: https://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues -maintainer: Thomas Hallgren -tested-with: GHC==8.0.2, GHC==8.10.4 +tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4 data-dir: src extra-source-files: WebSetup.hs @@ -75,7 +74,7 @@ flag c-runtime library default-language: Haskell2010 build-depends: - -- | GHC 8.0.2 to GHC 8.10.4 + -- GHC 8.0.2 to GHC 8.10.4 base >= 4.9.1 && <4.15, array >= 0.5.1 && < 0.6, containers >= 0.5.7 && < 0.7, @@ -84,9 +83,9 @@ library random >= 1.1 && < 1.3, pretty >= 1.1.3 && < 1.2, mtl >= 2.2.1 && < 2.3, + -- For compatability with GHC < 8 exceptions >= 0.8.3 && < 0.11, fail >= 4.9.0 && < 4.10, - -- 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 >= 0.5.1.4 && < 0.7, ghc-prim >= 0.5.0 && < 0.7 diff --git a/src/runtime/haskell-bind/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal index fcd854d72..eb1e3c708 100644 --- a/src/runtime/haskell-bind/pgf2.cabal +++ b/src/runtime/haskell-bind/pgf2.cabal @@ -1,18 +1,21 @@ name: pgf2 version: 1.3.0 + +cabal-version: 1.22 +build-type: Simple +license: LGPL-3 +license-file: LICENSE +category: Natural Language Processing synopsis: Bindings to the C version of the PGF runtime description: GF, Grammatical Framework, is a programming language for multilingual grammar applications. GF grammars are compiled into Portable Grammar Format (PGF) which can be used with the PGF runtime, written in C. This package provides Haskell bindings to that runtime. -homepage: https://www.grammaticalframework.org -license: LGPL-3 -license-file: LICENSE +homepage: https://www.grammaticalframework.org/ +bug-reports: https://github.com/GrammaticalFramework/gf-core/issues author: Krasimir Angelov -category: Natural Language Processing -build-type: Simple extra-source-files: CHANGELOG.md, README.md -cabal-version: >=1.10 +tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4 library exposed-modules: diff --git a/src/runtime/haskell-bind/stack-ghc7.10.3.yaml b/src/runtime/haskell-bind/stack-ghc7.10.3.yaml new file mode 100644 index 000000000..c916b4bb0 --- /dev/null +++ b/src/runtime/haskell-bind/stack-ghc7.10.3.yaml @@ -0,0 +1,3 @@ +resolver: lts-6.35 # ghc 7.10.3 + +allow-newer: true diff --git a/src/runtime/haskell-bind/stack-ghc8.0.2.yaml b/src/runtime/haskell-bind/stack-ghc8.0.2.yaml new file mode 100644 index 000000000..af08206d9 --- /dev/null +++ b/src/runtime/haskell-bind/stack-ghc8.0.2.yaml @@ -0,0 +1 @@ +resolver: lts-9.21 # ghc 8.0.2 diff --git a/src/runtime/haskell-bind/stack-ghc8.10.4.yaml b/src/runtime/haskell-bind/stack-ghc8.10.4.yaml new file mode 100644 index 000000000..195e90993 --- /dev/null +++ b/src/runtime/haskell-bind/stack-ghc8.10.4.yaml @@ -0,0 +1 @@ +resolver: lts-18.0 # ghc 8.10.4 diff --git a/src/runtime/haskell/pgf.cabal b/src/runtime/haskell/pgf.cabal index 9a59502c4..56c1ca04a 100644 --- a/src/runtime/haskell/pgf.cabal +++ b/src/runtime/haskell/pgf.cabal @@ -1,15 +1,15 @@ name: pgf -version: 3.10.1-git +version: 3.11.0-git -cabal-version: >= 1.20 +cabal-version: 1.22 build-type: Simple license: OtherLicense category: Natural Language Processing synopsis: Grammatical Framework description: A library for interpreting the Portable Grammar Format (PGF) -homepage: http://www.grammaticalframework.org/ +homepage: https://www.grammaticalframework.org/ bug-reports: https://github.com/GrammaticalFramework/gf-core/issues -tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC==8.4.4 +tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4 library default-language: Haskell2010 @@ -22,8 +22,9 @@ library random >= 1.1 && < 1.3, pretty >= 1.1.3 && < 1.2, mtl >= 2.2.1 && < 2.3, - ghc-prim >= 0.5.0 && < 0.7 - -- exceptions, + ghc-prim >= 0.5.0 && < 0.7, + -- For compatability with GHC < 8 + fail >= 4.9.0 && < 4.10 other-modules: -- not really part of GF but I have changed the original binary library diff --git a/src/runtime/haskell/stack-ghc7.10.3.yaml b/src/runtime/haskell/stack-ghc7.10.3.yaml new file mode 100644 index 000000000..c916b4bb0 --- /dev/null +++ b/src/runtime/haskell/stack-ghc7.10.3.yaml @@ -0,0 +1,3 @@ +resolver: lts-6.35 # ghc 7.10.3 + +allow-newer: true diff --git a/src/runtime/haskell/stack-ghc8.0.2.yaml b/src/runtime/haskell/stack-ghc8.0.2.yaml new file mode 100644 index 000000000..af08206d9 --- /dev/null +++ b/src/runtime/haskell/stack-ghc8.0.2.yaml @@ -0,0 +1 @@ +resolver: lts-9.21 # ghc 8.0.2 diff --git a/src/runtime/haskell/stack-ghc8.10.4.yaml b/src/runtime/haskell/stack-ghc8.10.4.yaml new file mode 100644 index 000000000..195e90993 --- /dev/null +++ b/src/runtime/haskell/stack-ghc8.10.4.yaml @@ -0,0 +1 @@ +resolver: lts-18.0 # ghc 8.10.4 From 0c3ca3d79acb34e0159cf6b51ba41ff570ad2af1 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 6 Jul 2021 14:43:21 +0200 Subject: [PATCH 73/75] Add note in PGF2 documentation about risk for integer overflow. Closes #109 --- src/runtime/haskell-bind/PGF2/Expr.hsc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/runtime/haskell-bind/PGF2/Expr.hsc b/src/runtime/haskell-bind/PGF2/Expr.hsc index 85e55ab40..35ee628d1 100644 --- a/src/runtime/haskell-bind/PGF2/Expr.hsc +++ b/src/runtime/haskell-bind/PGF2/Expr.hsc @@ -19,7 +19,7 @@ wildCId = "_" :: CId type Cat = CId -- ^ Name of syntactic category type Fun = CId -- ^ Name of function -data BindType = +data BindType = Explicit | Implicit deriving Show @@ -38,7 +38,7 @@ instance Show Expr where show = showExpr [] instance Eq Expr where - (Expr e1 e1_touch) == (Expr e2 e2_touch) = + (Expr e1 e1_touch) == (Expr e2 e2_touch) = unsafePerformIO $ do res <- pgf_expr_eq e1 e2 e1_touch >> e2_touch @@ -113,9 +113,9 @@ unApp (Expr expr touch) = appl <- pgf_expr_unapply expr pl if appl == nullPtr then return Nothing - else do + else do fun <- peekCString =<< (#peek PgfApplication, fun) appl - arity <- (#peek PgfApplication, n_args) appl :: IO CInt + arity <- (#peek PgfApplication, n_args) appl :: IO CInt c_args <- peekArray (fromIntegral arity) (appl `plusPtr` (#offset PgfApplication, args)) return $ Just (fun, [Expr c_arg touch | c_arg <- c_args]) @@ -140,7 +140,9 @@ unStr (Expr expr touch) = touch return (Just s) --- | Constructs an expression from an integer literal +-- | Constructs an expression from an integer literal. +-- Note that the C runtime does not support long integers, and you may run into overflow issues with large values. +-- See [here](https://github.com/GrammaticalFramework/gf-core/issues/109) for more details. mkInt :: Int -> Expr mkInt val = unsafePerformIO $ do @@ -267,7 +269,7 @@ foreign import ccall "wrapper" -- in the expression in order reverse to the order -- of binding. showExpr :: [CId] -> Expr -> String -showExpr scope e = +showExpr scope e = unsafePerformIO $ withGuPool $ \tmpPl -> do (sb,out) <- newOut tmpPl From ef422164154e093b1231c2ee905c0539c0c0a1b3 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 6 Jul 2021 15:35:03 +0200 Subject: [PATCH 74/75] Add import from command line invocation to command history Closes #64 --- src/compiler/GF/Interactive.hs | 2 +- src/compiler/GF/Interactive2.hs | 11 ++++++----- src/compiler/GF/Main.hs | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/GF/Interactive.hs b/src/compiler/GF/Interactive.hs index 9987b7c39..855ab22d1 100644 --- a/src/compiler/GF/Interactive.hs +++ b/src/compiler/GF/Interactive.hs @@ -38,7 +38,6 @@ import GF.Server(server) #endif 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 () @@ -56,6 +55,7 @@ mainGFI opts files = do shell opts files = flip evalStateT (emptyGFEnv opts) $ do mapStateT runSIO $ importInEnv opts files + modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]} loop #ifdef SERVER_MODE diff --git a/src/compiler/GF/Interactive2.hs b/src/compiler/GF/Interactive2.hs index 02e42e19e..6967309b9 100644 --- a/src/compiler/GF/Interactive2.hs +++ b/src/compiler/GF/Interactive2.hs @@ -58,6 +58,7 @@ mainGFI opts files = do shell opts files = flip evalStateT (emptyGFEnv opts) $ do mapStateT runSIO $ importInEnv opts files + modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]} loop {- @@ -101,7 +102,7 @@ timeIt act = -- | Optionally show how much CPU time was used to run an IO action optionallyShowCPUTime :: (Monad m,MonadSIO m) => Options -> m a -> m a -optionallyShowCPUTime opts act +optionallyShowCPUTime opts act | not (verbAtLeast opts Normal) = act | otherwise = do (dt,r) <- timeIt act liftSIO $ putStrLnFlush $ show (dt `div` 1000000000) ++ " msec" @@ -358,7 +359,7 @@ wordCompletion gfenv (left,right) = do CmplIdent _ pref -> case mb_pgf of Just pgf -> ret (length pref) - [Haskeline.simpleCompletion name + [Haskeline.simpleCompletion name | name <- C.functions pgf, isPrefixOf pref name] _ -> ret (length pref) [] @@ -369,7 +370,7 @@ wordCompletion gfenv (left,right) = do cmdEnv = commandenv gfenv {- optLang opts = valStrOpts "lang" (head $ Map.keys (concretes cmdEnv)) opts - optType opts = + optType opts = let str = valStrOpts "cat" (H.showCId $ H.lookStartCat pgf) opts in case H.readType str of Just ty -> ty @@ -416,7 +417,7 @@ wc_type = cmd_name option x y (c :cs) | isIdent c = option x y cs | otherwise = cmd x cs - + optValue x y ('"':cs) = str x y cs optValue x y cs = cmd x cs @@ -434,7 +435,7 @@ wc_type = cmd_name where x1 = take (length x - length y - d) x 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 [x] -> Just x _ -> Nothing diff --git a/src/compiler/GF/Main.hs b/src/compiler/GF/Main.hs index 7cde1ce97..7d4500c7b 100644 --- a/src/compiler/GF/Main.hs +++ b/src/compiler/GF/Main.hs @@ -16,18 +16,19 @@ import Data.Version import System.Directory import System.Environment (getArgs) import System.Exit -import GF.System.Console (setConsoleEncoding) +-- import GF.System.Console (setConsoleEncoding) -- | Run the GF main program, taking arguments from the command line. -- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.) -- Run @gf --help@ for usage info. main :: IO () main = do - --setConsoleEncoding + -- setConsoleEncoding uncurry mainOpts =<< getOptions -- | Get and parse GF command line arguments. Fix relative paths. -- Calls 'getArgs' and 'parseOptions'. +getOptions :: IO (Options, [FilePath]) getOptions = do args <- getArgs case parseOptions args of @@ -43,7 +44,7 @@ getOptions = do -- the options it invokes 'mainGFC', 'mainGFI', 'mainRunGFI', 'mainServerGFI', -- or it just prints version/usage info. mainOpts :: Options -> [FilePath] -> IO () -mainOpts opts files = +mainOpts opts files = case flag optMode opts of ModeVersion -> putStrLn $ "Grammatical Framework (GF) version " ++ showVersion version ++ "\n" ++ buildInfo ModeHelp -> putStrLn helpMessage From 0886eb520d9e48c64df44d6c5e83c8c934edbf8d Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 6 Jul 2021 15:45:21 +0200 Subject: [PATCH 75/75] Update 3.11 release notes --- download/release-3.11.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/download/release-3.11.md b/download/release-3.11.md index 3cb448303..2e9de41a9 100644 --- a/download/release-3.11.md +++ b/download/release-3.11.md @@ -1,6 +1,6 @@ --- title: GF 3.11 Release Notes -date: ... December 2020 +date: ... July 2021 ... ## 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. 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. ## General - Make the test suite work again. - Compatibility with new versions of GHC, including multiple Stack files for the different versions. -- Updates to build scripts and CI. -- Bug fixes. +- Support for newer version of Ubuntu 20.04 in the precompiled binaries. +- Updates to build scripts and CI workflows. +- Bug fixes and code cleanup. ## 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 canonical GF 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). +- Improvements in time & space requirements when compiling certain grammars. - Improvements to Haskell export. +- Improvements to the GF shell. +- Improvements to canonical GF compilation. - Improvements to the C runtime. - Improvements to `gf -server` mode. - Clearer compiler error messages.