summaryrefslogtreecommitdiff
path: root/contrib/c-bindings/PGFFFI.hs
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/c-bindings/PGFFFI.hs')
-rw-r--r--contrib/c-bindings/PGFFFI.hs230
1 files changed, 230 insertions, 0 deletions
diff --git a/contrib/c-bindings/PGFFFI.hs b/contrib/c-bindings/PGFFFI.hs
new file mode 100644
index 000000000..9fccdd20c
--- /dev/null
+++ b/contrib/c-bindings/PGFFFI.hs
@@ -0,0 +1,230 @@
+-- GF C Bindings
+-- Copyright (C) 2008-2009 Kevin Kofler
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public
+-- License as published by the Free Software Foundation; either
+-- version 2.1 of the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+
+module PGFFFI where
+
+import PGF
+import CString
+import Foreign
+import Foreign.C.Types
+import Control.Exception
+import IO
+import Data.Maybe
+import GF.Text.Lexing
+
+
+-- Utility functions used in the implementation (not exported):
+
+-- This is a kind of a hack, the FFI spec doesn't guarantee that this will work.
+-- The alternative would be to use Ptr () instead of StablePtr a everywhere.
+nullStablePtr :: StablePtr a
+nullStablePtr = (castPtrToStablePtr nullPtr)
+
+sizeOfStablePtr :: Int
+sizeOfStablePtr = (sizeOf (nullStablePtr))
+
+storeList :: [a] -> Ptr (StablePtr a) -> IO ()
+storeList list buf = do
+ case list of
+ carlist:cdrlist -> do
+ sptr <- (newStablePtr carlist)
+ (poke buf sptr)
+ (storeList cdrlist (plusPtr buf sizeOfStablePtr))
+ [] -> (poke buf nullStablePtr)
+
+listToArray :: [a] -> IO (Ptr (StablePtr a))
+listToArray list = do
+ buf <- (mallocBytes ((sizeOfStablePtr) * ((length list) + 1)))
+ (storeList list buf)
+ return buf
+
+
+-- PGF:
+
+foreign export ccall "gf_freePGF" freeStablePtr :: StablePtr PGF -> IO ()
+
+foreign export ccall gf_readPGF :: CString -> IO (StablePtr PGF)
+gf_readPGF path = do
+ p <- (peekCString path)
+ result <- (readPGF p)
+ (newStablePtr result)
+
+foreign export ccall "gf_freeLanguage" freeStablePtr :: StablePtr Language -> IO ()
+
+foreign export ccall gf_showLanguage :: StablePtr Language -> IO CString
+gf_showLanguage lang = do
+ l <- (deRefStablePtr lang)
+ (newCString (showLanguage l))
+
+foreign export ccall gf_readLanguage :: CString -> IO (StablePtr Language)
+gf_readLanguage str = do
+ s <- (peekCString str)
+ case (readLanguage s) of
+ Just x -> (newStablePtr x)
+ Nothing -> (return (nullStablePtr))
+
+foreign export ccall gf_languages :: StablePtr PGF -> IO (Ptr (StablePtr Language))
+gf_languages pgf = do
+ p <- (deRefStablePtr pgf)
+ (listToArray (languages p))
+
+foreign export ccall gf_abstractName :: StablePtr PGF -> IO (StablePtr Language)
+gf_abstractName pgf = do
+ p <- (deRefStablePtr pgf)
+ (newStablePtr (abstractName p))
+
+foreign export ccall gf_languageCode :: StablePtr PGF -> StablePtr Language -> IO CString
+gf_languageCode pgf lang = do
+ p <- (deRefStablePtr pgf)
+ l <- (deRefStablePtr lang)
+ case (languageCode p l) of
+ Just s -> (newCString s)
+ Nothing -> (return nullPtr)
+
+foreign export ccall "gf_freeType" freeStablePtr :: StablePtr Type -> IO ()
+
+foreign export ccall gf_showType :: StablePtr Type -> IO CString
+gf_showType tp = do
+ t <- (deRefStablePtr tp)
+ (newCString (showType t))
+
+foreign export ccall gf_readType :: CString -> IO (StablePtr Type)
+gf_readType str = do
+ s <- (peekCString str)
+ case (readType s) of
+ Just x -> (newStablePtr x)
+ Nothing -> (return (nullStablePtr))
+
+foreign export ccall gf_categories :: StablePtr PGF -> IO (Ptr (StablePtr Type))
+gf_categories pgf = do
+ p <- (deRefStablePtr pgf)
+ (listToArray (categories p))
+
+foreign export ccall gf_startCat :: StablePtr PGF -> IO (StablePtr Type)
+gf_startCat pgf = do
+ p <- (deRefStablePtr pgf)
+ (newStablePtr (startCat p))
+
+foreign export ccall "gf_freeCId" freeStablePtr :: StablePtr CId -> IO ()
+
+foreign export ccall gf_mkCId :: CString -> IO (StablePtr CId)
+gf_mkCId str = do
+ s <- (peekCString str)
+ (newStablePtr (mkCId s))
+
+foreign export ccall gf_prCId :: StablePtr CId -> IO CString
+gf_prCId cid = do
+ c <- (deRefStablePtr cid)
+ (newCString (prCId c))
+
+foreign export ccall gf_wildCId :: IO (StablePtr CId)
+gf_wildCId = do
+ (newStablePtr (wildCId))
+
+-- TODO: So we can create, print and free a CId, but can we do anything useful with it?
+-- We need some kind of C wrapper for the tree datastructures.
+
+foreign export ccall "gf_freeTree" freeStablePtr :: StablePtr Tree -> IO ()
+
+-- TODO: Literal(..)
+-- (Not much use exporting a free function for that type if you can't do anything with it.)
+
+foreign export ccall gf_showTree :: StablePtr Tree -> IO CString
+gf_showTree tree = do
+ t <- (deRefStablePtr tree)
+ (newCString (showTree t))
+
+foreign export ccall gf_readTree :: CString -> IO (StablePtr Tree)
+gf_readTree str = do
+ s <- (peekCString str)
+ case (readTree s) of
+ Just x -> (newStablePtr x)
+ Nothing -> (return (nullStablePtr))
+
+foreign export ccall "gf_freeExpr" freeStablePtr :: StablePtr Expr -> IO ()
+
+-- TODO: Equation(..)
+-- (Not much use exporting a free function for that type if you can't do anything with it.)
+
+foreign export ccall gf_showExpr :: StablePtr Expr -> IO CString
+gf_showExpr expr = do
+ e <- (deRefStablePtr expr)
+ (newCString (showExpr e))
+
+foreign export ccall gf_readExpr :: CString -> IO (StablePtr Expr)
+gf_readExpr str = do
+ s <- (peekCString str)
+ case (readExpr s) of
+ Just x -> (newStablePtr x)
+ Nothing -> (return (nullStablePtr))
+
+foreign export ccall gf_linearize :: StablePtr PGF -> StablePtr Language -> StablePtr Tree -> IO CString
+gf_linearize pgf lang tree = do
+ p <- (deRefStablePtr pgf)
+ l <- (deRefStablePtr lang)
+ t <- (deRefStablePtr tree)
+ (newCString (linearize p l t))
+
+-- TODO: linearizeAllLang, linearizeAll
+
+foreign export ccall gf_showPrintName :: StablePtr PGF -> StablePtr Language -> StablePtr Type -> IO CString
+gf_showPrintName pgf lang tp = do
+ p <- (deRefStablePtr pgf)
+ l <- (deRefStablePtr lang)
+ t <- (deRefStablePtr tp)
+ (newCString (showPrintName p l t))
+
+foreign export ccall gf_parse :: StablePtr PGF -> StablePtr Language -> StablePtr Type -> CString -> IO (Ptr (StablePtr Tree))
+gf_parse pgf lang cat input = do
+ p <- (deRefStablePtr pgf)
+ l <- (deRefStablePtr lang)
+ c <- (deRefStablePtr cat)
+ i <- (peekCString input)
+ (listToArray (parse p l c i))
+
+foreign export ccall gf_canParse :: StablePtr PGF -> StablePtr Language -> IO CInt
+gf_canParse pgf lang = do
+ p <- (deRefStablePtr pgf)
+ l <- (deRefStablePtr lang)
+ case (canParse p l) of
+ True -> (return 1)
+ False -> (return 0)
+
+-- TODO: parseAllLang, parseAll
+
+-- TODO: tree2expr, expr2tree, PGF.compute, paraphrase, typecheck
+
+-- TODO: complete, Incremental.ParseState, initState, Incremental.nextState, Incremental.getCompletions, extractExps
+
+-- TODO: generateRandom, generateAll, generateAllDepth
+
+
+-- GF.Text.Lexing:
+
+foreign export ccall gf_stringOp :: CString -> CString -> IO CString
+gf_stringOp op str = do
+ o <- (peekCString op)
+ s <- (peekCString str)
+ case (stringOp o) of
+ Just fn -> (newCString (fn s))
+ Nothing -> (return nullPtr)
+
+
+-- Unused (exception handling):
+-- (Control.Exception.catch (listToArray (parse p l c i)) (\(e::SomeException) -> do
+-- (hPutStr stderr ("error: " ++ show e))
+-- (return nullPtr)))