1
0
forked from GitHub/gf-core

"create lin/lincat" should be able to see funs & cats in the current transaction

This commit is contained in:
Krasimir Angelov
2022-11-04 22:03:29 +01:00
parent 58910975ad
commit a88c412e87
2 changed files with 79 additions and 27 deletions

View File

@@ -289,20 +289,22 @@ transactionCommand (CreateLin opts f t) pgf mb_txnid = do
lang <- optLang pgf opts lang <- optLang pgf opts
mo <- maybe (fail "no source grammar in scope") return $ mo <- maybe (fail "no source grammar in scope") return $
greatestResource sgr greatestResource sgr
(fields,ty) <- lift $ updatePGF pgf mb_txnid $ do
case functionType pgf f of mb_ty <- getFunctionType f
Just ty -> let DTyp _ cat _ = ty case mb_ty of
Just cnc = Map.lookup lang (languages pgf) Just ty@(DTyp _ cat _) ->
Just fields = categoryFields cnc cat alterConcrete lang $ do
in return (fields,type2term mo ty) mb_fields <- getCategoryFields cat
Nothing -> fail ("Function "++f++" is not in the abstract syntax") case mb_fields of
case runCheck (compileLinTerm sgr mo t ty) of Just fields -> case runCheck (compileLinTerm sgr mo t (type2term mo ty)) of
Ok ((prods,seqtbl,fields'),_) Ok ((prods,seqtbl,fields'),_)
| fields == fields' -> | fields == fields' -> do
do lift $ updatePGF pgf mb_txnid (alterConcrete lang (createLin f prods seqtbl >> return ())) createLin f prods seqtbl
return () return ()
| otherwise -> fail "The linearization categories in the resource and the compiled grammar does not match" | otherwise -> fail "The linearization categories in the resource and the compiled grammar does not match"
Bad msg -> fail msg Bad msg -> fail msg
Nothing -> fail ("Category "++cat++" is not in the concrete syntax")
_ -> fail ("Function "++f++" is not in the abstract syntax")
where where
type2term mo (DTyp hypos cat _) = type2term mo (DTyp hypos cat _) =
foldr (\(b,x,ty1) ty2 -> Prod b (identS x) (type2term mo ty1) ty2) foldr (\(b,x,ty1) ty2 -> Prod b (identS x) (type2term mo ty1) ty2)
@@ -422,16 +424,14 @@ fetchCommand gfenv = do
importInEnv :: ReadNGF -> Options -> [FilePath] -> ShellM () importInEnv :: ReadNGF -> Options -> [FilePath] -> ShellM ()
importInEnv readNGF opts files = importInEnv readNGF opts files =
do env <- gets pgfenv do (_,pgf0,mb_txnid) <- gets pgfenv
case env of case (flag optRetainResource opts,mb_txnid) of
(_,pgf0,Nothing) -> (RetainAll,Nothing) -> do src <- lift $ importSource opts files
case flag optRetainResource opts of
RetainAll -> do src <- lift $ importSource opts files
pgf <- lift $ link opts pgf0 src pgf <- lift $ link opts pgf0 src
modify $ \gfenv -> gfenv{pgfenv = (snd src,Just pgf,Nothing)} modify $ \gfenv -> gfenv{pgfenv = (snd src,Just pgf,Nothing)}
RetainSource -> do src <- lift $ importSource opts files (RetainSource,mb_txn) -> do src <- lift $ importSource opts files
modify $ \gfenv -> gfenv{pgfenv = (snd src,pgf0,Nothing)} modify $ \gfenv -> gfenv{pgfenv = (snd src,pgf0,mb_txn)}
RetainCompiled -> do pgf <- lift $ importPGF pgf0 (RetainCompiled,Nothing) -> do pgf <- lift $ importPGF pgf0
modify $ \gfenv -> gfenv{pgfenv = (emptyGrammar,pgf,Nothing)} modify $ \gfenv -> gfenv{pgfenv = (emptyGrammar,pgf,Nothing)}
_ -> fail "You must commit/rollback the transaction before loading a new grammar" _ -> fail "You must commit/rollback the transaction before loading a new grammar"
where where

View File

@@ -32,6 +32,8 @@ module PGF2.Transactions
, createLin , createLin
, dropLin , dropLin
, setPrintName , setPrintName
, getFunctionType
, getCategoryFields
) where ) where
import PGF2.FFI import PGF2.FFI
@@ -41,6 +43,7 @@ import PGF2.ByteCode
import Foreign import Foreign
import Foreign.C import Foreign.C
import Control.Exception import Control.Exception
import qualified Control.Monad.Fail as Fail
import qualified Data.Sequence as Seq import qualified Data.Sequence as Seq
import Data.IORef import Data.IORef
@@ -70,6 +73,14 @@ instance Monad (Transaction k) where
Transaction g -> g c_db c_abstr c_revision c_exn Transaction g -> g c_db c_abstr c_revision c_exn
else return undefined else return undefined
#if !(MIN_VERSION_base(4,13,0))
-- Monad(fail) will be removed in GHC 8.8+
fail = Fail.fail
#endif
instance Fail.MonadFail (Transaction k) where
fail msg = Transaction $ \c_db c_abstr c_revision c_exn -> fail msg
data TxnID = TxnID (Ptr PgfDB) (ForeignPtr PGF) data TxnID = TxnID (Ptr PgfDB) (ForeignPtr PGF)
startTransaction :: PGF -> IO TxnID startTransaction :: PGF -> IO TxnID
@@ -166,7 +177,7 @@ createConcrete name (Transaction f) = Transaction $ \c_db c_abstr c_revision c_e
(pgf_free_concr_revision_ c_db) $ \c_concr_revision -> (pgf_free_concr_revision_ c_db) $ \c_concr_revision ->
f c_db c_abstr c_concr_revision c_exn f c_db c_abstr c_concr_revision c_exn
alterConcrete :: ConcName -> Transaction Concr () -> Transaction PGF () alterConcrete :: ConcName -> Transaction Concr a -> Transaction PGF a
alterConcrete name (Transaction f) = Transaction $ \c_db c_abstr c_revision c_exn -> alterConcrete name (Transaction f) = Transaction $ \c_db c_abstr c_revision c_exn ->
withText name $ \c_name -> do withText name $ \c_name -> do
bracket (pgf_clone_concrete c_db c_revision c_name c_exn) bracket (pgf_clone_concrete c_db c_revision c_name c_exn)
@@ -383,4 +394,45 @@ setPrintName :: Fun -> String -> Transaction Concr ()
setPrintName fun name = Transaction $ \c_db _ c_revision c_exn -> setPrintName fun name = Transaction $ \c_db _ c_revision c_exn ->
withText fun $ \c_fun -> withText fun $ \c_fun ->
withText name $ \c_name -> do withText name $ \c_name -> do
withPgfExn "setPrintName" (pgf_set_printname c_db c_revision c_fun c_name) pgf_set_printname c_db c_revision c_fun c_name c_exn
-- | A monadic version of 'functionType' which returns the type of
-- the function in the current transaction.
getFunctionType :: Fun -> Transaction PGF (Maybe Type)
getFunctionType fun = Transaction $ \c_db c_revision _ c_exn -> do
c_typ <- withForeignPtr unmarshaller $ \u ->
withText fun $ \c_fun ->
pgf_function_type c_db c_revision c_fun u c_exn
ex_type <- (#peek PgfExn, type) c_exn
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
then if c_typ == castPtrToStablePtr nullPtr
then return Nothing
else do typ <- deRefStablePtr c_typ
freeStablePtr c_typ
return (Just typ)
else return undefined
-- | A monadic version of 'categoryFields' which returns the fields of
-- a category from grammar in the current transaction.
getCategoryFields :: Cat -> Transaction Concr (Maybe [String])
getCategoryFields cat = Transaction $ \c_db _ c_revision c_exn ->
withText cat $ \c_cat ->
alloca $ \p_n_fields -> do
c_fields <- pgf_category_fields c_db c_revision c_cat p_n_fields c_exn
ex_type <- (#peek PgfExn, type) c_exn
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
then if c_fields == nullPtr
then return Nothing
else do n_fields <- peek p_n_fields
fs <- peekFields n_fields c_fields
free c_fields
return (Just fs)
else return undefined
where
peekFields n_fields c_fields
| n_fields == 0 = return []
| otherwise = do c_text <- peek c_fields
f <- peekText c_text
free c_text
fs <- peekFields (n_fields-1) (c_fields `plusPtr` (#size PgfText*))
return (f:fs)