1
0
forked from GitHub/gf-core

an almost complete API for building new PGF files in the Haskell binding

This commit is contained in:
Krasimir Angelov
2017-09-14 15:23:13 +02:00
parent 1ff8dd88e8
commit d574bb2164
2 changed files with 360 additions and 44 deletions

View File

@@ -29,13 +29,14 @@ data Concr = Concr {concr :: Ptr PgfConcr, touchConcr :: Touch}
data GuEnum
data GuExn
data GuIn
data GuOut
data GuKind
data GuType
data GuString
data GuStringBuf
data GuMap
data GuMapItor
data GuOut
data GuHasher
data GuSeq
data GuPool
type GuVariant = Ptr ()
@@ -111,12 +112,27 @@ foreign import ccall unsafe "gu/utf8.h gu_utf8_encode"
foreign import ccall unsafe "gu/seq.h gu_make_seq"
gu_make_seq :: CSizeT -> CSizeT -> Ptr GuPool -> IO (Ptr GuSeq)
foreign import ccall unsafe "gu/map.h gu_make_map"
gu_make_map :: CSizeT -> Ptr GuHasher -> CSizeT -> Ptr a -> CSizeT -> Ptr GuPool -> IO (Ptr GuMap)
foreign import ccall unsafe "gu/map.h gu_map_insert"
gu_map_insert :: Ptr GuMap -> Ptr a -> IO (Ptr b)
foreign import ccall unsafe "gu/map.h gu_map_find_default"
gu_map_find_default :: Ptr GuMap -> Ptr a -> IO (Ptr b)
foreign import ccall "gu/map.h gu_map_iter"
gu_map_iter :: Ptr GuMap -> Ptr GuMapItor -> Ptr GuExn -> IO ()
foreign import ccall unsafe "gu/hash.h &gu_int_hasher"
gu_int_hasher :: Ptr GuHasher
foreign import ccall unsafe "gu/hash.h &gu_string_hasher"
gu_string_hasher :: Ptr GuHasher
foreign import ccall unsafe "gu/hash.h &gu_null_struct"
gu_null_struct :: Ptr a
foreign import ccall unsafe "gu/variant.h gu_variant_tag"
gu_variant_tag :: GuVariant -> IO CInt
@@ -209,6 +225,8 @@ data PgfCncTree
data PgfLinFuncs
data PgfGraphvizOptions
type PgfBindType = (#type PgfBindType)
data PgfAbsFun
data PgfAbsCat
foreign import ccall "pgf/pgf.h pgf_read"
pgf_read :: CString -> Ptr GuPool -> Ptr GuExn -> IO (Ptr PgfPGF)

View File

@@ -10,7 +10,7 @@ module PGF2.Internal(-- * Access the internal structures
-- * Building new PGFs in memory
build, eAbs, eApp, eMeta, eFun, eVar, eTyped, eImplArg, dTyp, hypo,
newAbstr, newPGF,
AbstrInfo, newAbstr, ConcrInfo, newConcr, newPGF,
-- * Write an in-memory PGF to a file
writePGF
@@ -26,8 +26,10 @@ import System.IO.Unsafe(unsafePerformIO)
import Foreign
import Foreign.C
import Data.IORef
import qualified Data.Map as Map
import Data.Maybe(fromMaybe)
import Data.List(sortBy)
import Control.Exception(Exception,throwIO)
import qualified Data.Map as Map
type Token = String
data Symbol
@@ -61,32 +63,31 @@ data Literal =
-- Access the internal structures
-----------------------------------------------------------------------
globalFlags :: PGF -> Map.Map String Literal
globalFlags :: PGF -> [(String,Literal)]
globalFlags p = unsafePerformIO $ do
c_flags <- (#peek PgfPGF, gflags) (pgf p)
flags <- peekFlags c_flags
touchPGF p
return flags
abstrFlags :: PGF -> Map.Map String Literal
abstrFlags :: PGF -> [(String,Literal)]
abstrFlags p = unsafePerformIO $ do
c_flags <- (#peek PgfPGF, abstract.aflags) (pgf p)
flags <- peekFlags c_flags
touchPGF p
return flags
concrFlags :: Concr -> Map.Map String Literal
concrFlags :: Concr -> [(String,Literal)]
concrFlags c = unsafePerformIO $ do
c_flags <- (#peek PgfConcr, cflags) (concr c)
flags <- peekFlags c_flags
touchConcr c
return flags
peekFlags :: Ptr GuSeq -> IO (Map.Map String Literal)
peekFlags :: Ptr GuSeq -> IO [(String,Literal)]
peekFlags c_flags = do
c_len <- (#peek GuSeq, len) c_flags
list <- peekFlags (c_len :: CInt) (c_flags `plusPtr` (#offset GuSeq, data))
return (Map.fromAscList list)
peekFlags (c_len :: CInt) (c_flags `plusPtr` (#offset GuSeq, data))
where
peekFlags 0 ptr = return []
peekFlags c_len ptr = do
@@ -114,7 +115,7 @@ concrTotalCats c = unsafePerformIO $ do
touchConcr c
return (fromIntegral (c_total_cats :: CInt))
concrCategories :: Concr -> [(CId,FId,FId,[String])]
concrCategories :: Concr -> [(Cat,FId,FId,[String])]
concrCategories c =
unsafePerformIO $
withGuPool $ \tmpPl ->
@@ -348,7 +349,7 @@ eMeta id =
alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_EXPR_META)
(fromIntegral (#size PgfExprMeta))
(#const gu_flex_alignof(PgfExprMeta))
(#const gu_alignof(PgfExprMeta))
pptr pool
(#poke PgfExprMeta, id) ptr (fromIntegral id :: CInt)
e <- peek pptr
@@ -452,28 +453,51 @@ newHypos hypos pool = do
Explicit -> (#const PGF_BIND_TYPE_EXPLICIT)
Implicit -> (#const PGF_BIND_TYPE_IMPLICIT)
data AbstrInfo = Abstr (Ptr GuSeq) (Ptr GuSeq) (Ptr GuSeq) Touch
newAbstr :: (?builder :: Builder s) => Map.Map String Literal ->
Map.Map Cat ([B s Hypo],Float) ->
Map.Map Fun (B s Type,Int,Float) ->
data AbstrInfo = AbstrInfo (Ptr GuSeq) (Ptr GuSeq) (Map.Map String (Ptr PgfAbsCat)) (Ptr GuSeq) (Map.Map String (Ptr PgfAbsFun)) (Ptr PgfAbsFun) Touch
newAbstr :: (?builder :: Builder s) => [(String,Literal)] ->
[(Cat,[B s Hypo],Float)] ->
[(Fun,B s Type,Int,Float)] ->
AbstrInfo
newAbstr aflags cats funs = unsafePerformIO $ do
c_aflags <- newFlags aflags pool
c_cats <- newMap (#size PgfAbsCat) pokeAbsCat cats pool
c_funs <- newMap (#size PgfAbsFun) pokeAbsFun funs pool
return (Abstr c_aflags c_cats c_funs touch)
(c_cats,abscats) <- newAbsCats (sortByFst3 cats) pool
(c_funs,absfuns) <- newAbsFuns (sortByFst4 funs) pool
c_abs_lin_fun <- newAbsLinFun
return (AbstrInfo c_aflags c_cats abscats c_funs absfuns c_abs_lin_fun touch)
where
(Builder pool touch) = ?builder
pokeAbsCat ptr name (hypos,prob) = do
newAbsCats values pool = do
c_seq <- gu_make_seq (#size PgfAbsCat) (fromIntegral (length values)) pool
abscats <- pokeElems (c_seq `plusPtr` (#offset GuSeq, data)) Map.empty values
return (c_seq,abscats)
where
pokeElems ptr abscats [] = return abscats
pokeElems ptr abscats (x:xs) = do
abscats <- pokeAbsCat ptr abscats x
pokeElems (ptr `plusPtr` (#size PgfAbsCat)) abscats xs
pokeAbsCat ptr abscats (name,hypos,prob) = do
c_name <- newUtf8CString name pool
c_hypos <- newHypos hypos pool
(#poke PgfAbsCat, name) ptr c_name
(#poke PgfAbsCat, context) ptr c_hypos
(#poke PgfAbsCat, prob) ptr (realToFrac prob :: CFloat)
return (Map.insert name ptr abscats)
pokeAbsFun ptr name (B (Type c_ty _),arity,prob) = do
newAbsFuns values pool = do
c_seq <- gu_make_seq (#size PgfAbsFun) (fromIntegral (length values)) pool
absfuns <- pokeElems (c_seq `plusPtr` (#offset GuSeq, data)) Map.empty values
return (c_seq,absfuns)
where
pokeElems ptr absfuns [] = return absfuns
pokeElems ptr absfuns (x:xs) = do
absfuns <- pokeAbsFun ptr absfuns x
pokeElems (ptr `plusPtr` (#size PgfAbsFun)) absfuns xs
pokeAbsFun ptr absfuns (name,B (Type c_ty _),arity,prob) = do
pfun <- gu_alloc_variant (#const PGF_EXPR_FUN)
(fromIntegral ((#size PgfExprFun)+utf8Length name))
(#const gu_flex_alignof(PgfExprFun))
@@ -485,42 +509,159 @@ newAbstr aflags cats funs = unsafePerformIO $ do
(#poke PgfAbsFun, arity) ptr (fromIntegral arity :: CInt)
(#poke PgfAbsFun, defns) ptr nullPtr
(#poke PgfAbsFun, ep.prob) ptr (realToFrac prob :: CFloat)
return (Map.insert name ptr absfuns)
data ConcrInfo
newAbsLinFun = do
ptr <- gu_malloc_aligned pool
(#size PgfAbsFun)
(#const gu_alignof(PgfAbsFun))
c_wild <- newUtf8CString "_" pool
c_ty <- gu_malloc_aligned pool
(#size PgfType)
(#const gu_alignof(PgfType))
(#poke PgfType, hypos) c_ty nullPtr
(#poke PgfType, cid) c_ty c_wild
(#poke PgfType, n_exprs) c_ty (0 :: CSizeT)
(#poke PgfAbsFun, name) ptr c_wild
(#poke PgfAbsFun, type) ptr c_ty
(#poke PgfAbsFun, arity) ptr (0 :: CSizeT)
(#poke PgfAbsFun, defns) ptr nullPtr
(#poke PgfAbsFun, ep.prob) ptr (- log 0 :: CFloat)
(#poke PgfAbsFun, ep.expr) ptr nullPtr
return ptr
newPGF :: (?builder :: Builder s) => Map.Map String Literal ->
data ConcrInfo = ConcrInfo (Ptr GuSeq) (Ptr GuMap) (Ptr GuMap) (Ptr GuSeq) (Ptr GuSeq) (Ptr GuMap)
newConcr :: (?builder :: Builder s) => AbstrInfo ->
[(String,Literal)] -> -- ^ Concrete syntax flags
[(String,String)] -> -- ^ Printnames
[(FId,[FunId])] -> -- ^ Lindefs
[(FId,[FunId])] -> -- ^ Linrefs
[(FId,[Production])] -> -- ^ Productions
[(Fun,[SeqId])] -> -- ^ Concrete functions (must be sorted by Fun)
[[Symbol]] -> -- ^ Sequences (must be sorted)
[(Cat,FId,FId,[String])] -> -- ^ Concrete categories
ConcrInfo
newConcr (AbstrInfo _ _ abscats _ absfuns c_abs_lin_fun _) cflags printnames lindefs linrefs prods cncfuns sequences cnccats = unsafePerformIO $ do
c_cflags <- newFlags cflags pool
c_printname <- newMap (#size GuString) gu_string_hasher newUtf8CString
(#size GuString) (pokeString pool)
printnames pool
c_seqs <- newSequence (#size PgfSequence) pokeSequence sequences pool
let seqs_ptr = c_seqs `plusPtr` (#offset GuSeq, data)
c_cncfuns <- newSequence (#size PgfCncFun*) (pokeCncFun seqs_ptr) (zip [0..] cncfuns) pool
let funs_ptr = c_cncfuns `plusPtr` (#offset GuSeq, data)
c_ccats <- gu_make_map (#size int) gu_int_hasher
(#size PgfCCat*) gu_null_struct
(#const GU_MAP_DEFAULT_INIT_SIZE)
pool
mapM_ (addLindefs c_ccats funs_ptr) lindefs
mapM_ (addLinrefs c_ccats funs_ptr) linrefs
mapM_ (addProductions c_ccats funs_ptr) prods
c_cnccats <- newMap (#size GuString) gu_string_hasher newUtf8CString (#size PgfCncCat*) (pokeCncCat c_ccats) (map (\v@(k,_,_,_) -> (k,v)) cnccats) pool
return (ConcrInfo c_cflags c_printname c_ccats c_cncfuns c_seqs c_cnccats)
where
(Builder pool touch) = ?builder
pokeCncFun seqs_ptr ptr cncfun = do
c_cncfun <- newCncFun absfuns nullPtr cncfun pool
poke ptr c_cncfun
pokeSequence c_seq syms = do
c_syms <- newSymbols syms pool
(#poke PgfSequence, syms) c_seq c_syms
(#poke PgfSequence, idx) c_seq nullPtr
addLindefs c_ccats funs_ptr (fid,funids) = do
c_ccat <- getCCat c_ccats fid pool
c_funs <- newSequence (#size PgfCncFun*) (pokeFunId funs_ptr) funids pool
(#poke PgfCCat, lindefs) c_ccat c_funs
addLinrefs c_ccats funs_ptr (fid,funids) = do
c_ccat <- getCCat c_ccats fid pool
c_funs <- newSequence (#size PgfCncFun*) (pokeFunId funs_ptr) funids pool
(#poke PgfCCat, linrefs) c_ccat c_funs
addProductions c_ccats funs_ptr (fid,prods) = do
c_ccat <- getCCat c_ccats fid pool
c_prods <- gu_make_seq (#size PgfProduction) (fromIntegral (length prods)) pool
(#poke PgfCCat, prods) c_ccat c_prods
pokeFunId funs_ptr ptr funid = do
let c_fun = funs_ptr `plusPtr` (funid * (#size PgfCncFun))
(#poke PgfCncFun, absfun) c_fun c_abs_lin_fun
poke ptr c_fun
pokeCncCat c_ccats ptr (name,start,end,labels) = do
let n_lins = fromIntegral (length labels) :: CSizeT
c_cnccat <- gu_malloc_aligned pool
((#size PgfCncCat)+n_lins*(#size GuString))
(#const gu_flex_alignof(PgfCncCat))
case Map.lookup name abscats of
Just c_abscat -> (#poke PgfCncCat, abscat) c_cnccat c_abscat
Nothing -> throwIO (PGFError ("The category "++name++" is not in the abstract syntax"))
c_ccats <- newSequence (#size PgfCCat*) pokeFId [start..end] pool
(#poke PgfCncCat, cats) c_cnccat c_ccats
pokeLabels (c_cnccat `plusPtr` (#offset PgfCncCat, labels)) labels
poke ptr c_cnccat
where
pokeFId ptr fid = do
c_ccat <- getCCat c_ccats fid pool
poke ptr c_ccat
pokeLabels ptr [] = return []
pokeLabels ptr (l:ls) = do
c_l <- newUtf8CString l pool
poke ptr c_l
pokeLabels (ptr `plusPtr` (#size GuString)) ls
newPGF :: (?builder :: Builder s) => [(String,Literal)] ->
AbsName ->
AbstrInfo ->
Map.Map ConcName ConcrInfo ->
[(ConcName,ConcrInfo)] ->
B s PGF
newPGF gflags absname (Abstr c_aflags c_cats c_funs _) concrs =
newPGF gflags absname (AbstrInfo c_aflags c_cats _ c_funs _ c_abs_lin_fun _) concrs =
unsafePerformIO $ do
ptr <- gu_malloc_aligned pool
(#size PgfPGF)
(#const gu_alignof(PgfPGF))
c_gflags <- newFlags gflags pool
c_absname <- newUtf8CString absname pool
c_concrs <- newMap (#size PgfConcr) pokeConcr concrs pool
let c_abstr = ptr `plusPtr` (#offset PgfPGF, abstract)
c_concrs <- newSequence (#size PgfConcr) (pokeConcr c_abstr) concrs pool
(#poke PgfPGF, major_version) ptr (2 :: (#type uint16_t))
(#poke PgfPGF, minor_version) ptr (0 :: (#type uint16_t))
(#poke PgfPGF, gflags) ptr c_gflags
(#poke PgfPGF, abstract.name) ptr c_absname
(#poke PgfPGF, abstract.aflags) ptr c_aflags
(#poke PgfPGF, abstract.cats) ptr c_cats
(#poke PgfPGF, abstract.funs) ptr c_funs
(#poke PgfPGF, abstract.cats) ptr c_cats
(#poke PgfPGF, abstract.abs_lin_fun) ptr c_abs_lin_fun
(#poke PgfPGF, concretes) ptr c_concrs
(#poke PgfPGF, pool) ptr pool
return (B (PGF ptr touch))
where
(Builder pool touch) = ?builder
pokeConcr ptr name concr = do
undefined
pokeConcr c_abstr ptr (name, ConcrInfo c_cflags c_printnames c_ccats c_cncfuns c_seqs c_cnccats) = do
c_name <- newUtf8CString name pool
(#poke PgfConcr, name) ptr c_name
(#poke PgfConcr, abstr) ptr c_abstr
(#poke PgfConcr, cflags) ptr c_cflags
(#poke PgfConcr, printnames) ptr c_printnames
(#poke PgfConcr, ccats) ptr c_ccats
(#poke PgfConcr, cncfuns) ptr c_cncfuns
(#poke PgfConcr, sequences) ptr c_seqs
(#poke PgfConcr, cnccats) ptr c_cnccats
(#poke PgfConcr, pool) ptr nullPtr
newFlags :: Map.Map String Literal -> Ptr GuPool -> IO (Ptr GuSeq)
newFlags flags pool = newMap (#size PgfFlag) pokeFlag flags pool
newFlags :: [(String,Literal)] -> Ptr GuPool -> IO (Ptr GuSeq)
newFlags flags pool = newSequence (#size PgfFlag) pokeFlag (sortByFst flags) pool
where
pokeFlag c_flag name value = do
pokeFlag c_flag (name,value) = do
c_name <- newUtf8CString name pool
c_value <- newLiteral value pool
(#poke PgfFlag, name) c_flag c_name
@@ -539,7 +680,7 @@ newLiteral (LInt val) pool =
alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_LITERAL_INT)
(fromIntegral (#size PgfLiteralInt))
(#const gu_flex_alignof(PgfLiteralInt))
(#const gu_alignof(PgfLiteralInt))
pptr pool
(#poke PgfLiteralInt, val) ptr (fromIntegral val :: CInt)
peek pptr
@@ -547,25 +688,178 @@ newLiteral (LFlt val) pool =
alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_LITERAL_FLT)
(fromIntegral (#size PgfLiteralFlt))
(#const gu_flex_alignof(PgfLiteralFlt))
(#const gu_alignof(PgfLiteralFlt))
pptr pool
(#poke PgfLiteralFlt, val) ptr (realToFrac val :: CDouble)
peek pptr
newSymbol :: Symbol -> Ptr GuPool -> IO GuVariant
newSymbol pool = undefined
newMap :: CSizeT -> (Ptr a -> k -> v -> IO ()) -> Map.Map k v -> Ptr GuPool -> IO (Ptr GuSeq)
newMap elem_size pokeElem m pool = do
c_m <- gu_make_seq elem_size (fromIntegral (Map.size m)) pool
pokeElems (c_m `plusPtr` (#offset GuSeq, data)) (Map.toAscList m)
return c_m
newCncFun absfuns seqs_ptr (funid,(fun,seqids)) pool =
do let c_absfun = fromMaybe nullPtr (Map.lookup fun absfuns)
c_ep = if c_absfun == nullPtr
then nullPtr
else c_absfun `plusPtr` (#offset PgfAbsFun, ep)
n_lins = fromIntegral (length seqids) :: CSizeT
ptr <- gu_malloc_aligned pool
((#size PgfCncFun)+n_lins*(#size PgfSequence*))
(#const gu_flex_alignof(PgfCncFun))
(#poke PgfCncFun, absfun) ptr c_absfun
(#poke PgfCncFun, ep) ptr c_ep
(#poke PgfCncFun, funid) ptr (funid :: CInt)
(#poke PgfCncFun, n_lins) ptr n_lins
pokeSequences seqs_ptr (ptr `plusPtr` (#offset PgfCncFun, lins)) seqids
return ptr
where
pokeElems ptr [] = return ()
pokeElems ptr ((key,value):xs) = do
pokeElem ptr key value
pokeSequences seqs_ptr ptr [] = return ()
pokeSequences seqs_ptr ptr (seqid:seqids) = do
poke ptr (seqs_ptr `plusPtr` (seqid * (#size PgfSequence)))
pokeSequences seqs_ptr (ptr `plusPtr` (#size PgfSequence*)) seqids
getCCat c_ccats fid pool =
alloca $ \pfid -> do
poke pfid (fromIntegral fid :: CInt)
ptr <- gu_map_find_default c_ccats pfid
c_ccat <- peek ptr
if c_ccat /= nullPtr
then return c_ccat
else do c_ccat <- gu_malloc_aligned pool
(#size PgfCCat)
(#const gu_alignof(PgfCCat))
(#poke PgfCCat, cnccat) c_ccat nullPtr
(#poke PgfCCat, lindefs) c_ccat nullPtr
(#poke PgfCCat, linrefs) c_ccat nullPtr
(#poke PgfCCat, n_synprods) c_ccat (0 :: CSizeT)
(#poke PgfCCat, prods) c_ccat nullPtr
(#poke PgfCCat, viterbi_prob) c_ccat (0 :: CFloat)
(#poke PgfCCat, fid) c_ccat fid
(#poke PgfCCat, conts) c_ccat nullPtr
(#poke PgfCCat, answers) c_ccat nullPtr
ptr <- gu_map_insert c_ccats pfid
poke ptr c_ccat
return c_ccat
newSymbol :: Symbol -> Ptr GuPool -> IO GuVariant
newSymbol (SymCat d r) pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_CAT)
(fromIntegral (#size PgfSymbolCat))
(#const gu_alignof(PgfSymbolCat))
pptr pool
(#poke PgfSymbolCat, d) ptr (fromIntegral d :: CInt)
(#poke PgfSymbolCat, r) ptr (fromIntegral r :: CInt)
peek pptr
newSymbol (SymLit d r) pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_LIT)
(fromIntegral (#size PgfSymbolLit))
(#const gu_alignof(PgfSymbolLit))
pptr pool
(#poke PgfSymbolLit, d) ptr (fromIntegral d :: CInt)
(#poke PgfSymbolLit, r) ptr (fromIntegral r :: CInt)
peek pptr
newSymbol (SymVar d r) pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_VAR)
(fromIntegral (#size PgfSymbolVar))
(#const gu_alignof(PgfSymbolVar))
pptr pool
(#poke PgfSymbolVar, d) ptr (fromIntegral d :: CInt)
(#poke PgfSymbolVar, r) ptr (fromIntegral r :: CInt)
peek pptr
newSymbol (SymKS t) pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_KS)
(fromIntegral ((#size PgfSymbolKS)+utf8Length t))
(#const gu_flex_alignof(PgfSymbolKS))
pptr pool
pokeUtf8CString t (ptr `plusPtr` (#offset PgfSymbolKS, token))
peek pptr
newSymbol (SymKP def alts) pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_KP)
(fromIntegral ((#size PgfSymbolKP)+(length alts * (#size PgfAlternative))))
(#const gu_flex_alignof(PgfSymbolKP))
pptr pool
c_def <- newSymbols def pool
(#poke PgfSymbolKP, default_form) ptr c_def
pokeAlternatives (ptr `plusPtr` (#offset PgfSymbolKP, forms)) alts pool
peek pptr
newSymbol SymBIND pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_BIND)
(fromIntegral (#size PgfSymbolBIND))
(#const gu_alignof(PgfSymbolBIND))
pptr pool
peek pptr
newSymbol SymNE pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_NE)
(fromIntegral (#size PgfSymbolNE))
(#const gu_alignof(PgfSymbolNE))
pptr pool
peek pptr
newSymbol SymSOFT_BIND pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_SOFT_BIND)
(fromIntegral (#size PgfSymbolBIND))
(#const gu_alignof(PgfSymbolBIND))
pptr pool
peek pptr
newSymbol SymSOFT_SPACE pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_SOFT_SPACE)
(fromIntegral (#size PgfSymbolBIND))
(#const gu_alignof(PgfSymbolBIND))
pptr pool
peek pptr
newSymbol SymCAPIT pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_CAPIT)
(fromIntegral (#size PgfSymbolCAPIT))
(#const gu_alignof(PgfSymbolCAPIT))
pptr pool
peek pptr
newSymbol SymALL_CAPIT pool = alloca $ \pptr -> do
ptr <- gu_alloc_variant (#const PGF_SYMBOL_ALL_CAPIT)
(fromIntegral (#size PgfSymbolCAPIT))
(#const gu_alignof(PgfSymbolCAPIT))
pptr pool
peek pptr
newSymbols syms pool = newSequence (#size PgfSymbol) pokeSymbol syms pool
where
pokeSymbol p_sym sym = do
c_sym <- newSymbol sym pool
poke p_sym c_sym
pokeAlternatives ptr [] pool = return ()
pokeAlternatives ptr ((syms,prefixes):alts) pool = do
c_syms <- newSymbols syms pool
c_prefixes <- newSequence (#size GuString) (pokeString pool) prefixes pool
(#poke PgfAlternative, form) ptr c_syms
(#poke PgfAlternative, prefixes) ptr c_prefixes
pokeAlternatives (ptr `plusPtr` (#size PgfAlternative)) alts pool
pokeString pool c_elem str = do
c_str <- newUtf8CString str pool
poke c_elem c_str
newSequence :: CSizeT -> (Ptr a -> v -> IO ()) -> [v] -> Ptr GuPool -> IO (Ptr GuSeq)
newSequence elem_size pokeElem values pool = do
c_seq <- gu_make_seq elem_size (fromIntegral (length values)) pool
pokeElems (c_seq `plusPtr` (#offset GuSeq, data)) values
return c_seq
where
pokeElems ptr [] = return ()
pokeElems ptr (x:xs) = do
pokeElem ptr x
pokeElems (ptr `plusPtr` (fromIntegral elem_size)) xs
newMap key_size hasher newKey elem_size pokeElem values pool = do
map <- gu_make_map key_size hasher
elem_size gu_null_struct
(#const GU_MAP_DEFAULT_INIT_SIZE)
pool
insert map values pool
return map
where
insert map [] pool = return ()
insert map ((key,elem):values) pool = do
c_key <- newKey key pool
c_elem <- gu_map_insert map c_key
pokeElem c_elem elem
insert map values pool
writePGF :: FilePath -> PGF -> IO ()
writePGF fpath p = do
pool <- gu_new_pool
@@ -585,3 +879,7 @@ writePGF fpath p = do
throwIO (PGFError "The grammar cannot be stored")
else do gu_pool_free pool
return ()
sortByFst = sortBy (\(x,_) (y,_) -> compare x y)
sortByFst3 = sortBy (\(x,_,_) (y,_,_) -> compare x y)
sortByFst4 = sortBy (\(x,_,_,_) (y,_,_,_) -> compare x y)