From 9608af8423cbb924141d976e8d280aa25319f85c Mon Sep 17 00:00:00 2001 From: "jordi.saludes" Date: Thu, 15 Jul 2010 08:15:41 +0000 Subject: [PATCH] New interface to gf based in Storable. --- contrib/py-bindings/Makefile | 10 +++- contrib/py-bindings/PyGF.hsc | 111 +++++++++++++++++++++++++++++++++++ contrib/py-bindings/mtest.c | 66 +++++++++++++++++++++ contrib/py-bindings/pygf.h | 68 +++++++++++++++++++++ 4 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 contrib/py-bindings/PyGF.hsc create mode 100644 contrib/py-bindings/mtest.c create mode 100644 contrib/py-bindings/pygf.h diff --git a/contrib/py-bindings/Makefile b/contrib/py-bindings/Makefile index 707c6925e..51380c06c 100644 --- a/contrib/py-bindings/Makefile +++ b/contrib/py-bindings/Makefile @@ -1,5 +1,5 @@ src=../../src -import=-i$src/runtime/haskell:$src/compiler +import=-i$(src)/runtime/haskell:$(src)/compiler cbind=../c-bindings pythoninc=/usr/include/python2.5 debug= #-optc '-DDEBUG=1' @@ -22,3 +22,11 @@ superclean: make clean rm -f PGFFFI.hs pgf.h Query.pgf rm -f gf.so + +PyGF.hs: PyGF.hsc + hsc2hs -I$(pythoninc) $< + +mtest: PyGF.hs mtest.c + ghc $(import) --make -fglasgow-exts -O2 -no-hs-main -c $< + ghc -O2 --make -fglasgow-exts -no-hs-main \ + -optc '-DMODULE=PyGF' -optc '-I$(pythoninc)' -o $@ $^ \ No newline at end of file diff --git a/contrib/py-bindings/PyGF.hsc b/contrib/py-bindings/PyGF.hsc new file mode 100644 index 000000000..7292277dd --- /dev/null +++ b/contrib/py-bindings/PyGF.hsc @@ -0,0 +1,111 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +module PyGF where + +import PGF +import Foreign +import CString +import Foreign.C.Types + +#include "pygf.h" + +-- type PyPtr = Ptr Py + +instance Storable PGF where + sizeOf _ = (#size PyGF) + alignment _ = alignment (undefined::CInt) + poke p o = do + sp <- newStablePtr o + (#poke PyGF, sp) p sp + peek p = do + sp <- (#peek PyGF, sp) p + deRefStablePtr sp + +instance Storable Type where + sizeOf _ = (#size PyGF) + alignment _ = alignment (undefined::CInt) + poke p o = do + sp <- newStablePtr o + (#poke PyGF, sp) p sp + peek p = do + sp <- (#peek PyGF, sp) p + deRefStablePtr sp + +instance Storable Language where + sizeOf _ = (#size PyGF) + alignment _ = alignment (undefined::CInt) + poke p o = do + sp <- newStablePtr o + (#poke PyGF, sp) p sp + peek p = do + sp <- (#peek PyGF, sp) p + deRefStablePtr sp + +instance Storable Tree where + sizeOf _ = (#size PyGF) + alignment _ = alignment (undefined::CInt) + poke p o = do + sp <- newStablePtr o + (#poke PyGF, sp) p sp + peek p = do + sp <- (#peek PyGF, sp) p + deRefStablePtr sp + + +{-foreign export ccall gf_printCId :: Ptr CId-> IO CString +gf_printCId p = do + c <- peek p + newCString (showCId c) +-} +foreign export ccall gf_readPGF :: Ptr PGF -> CString -> IO () +gf_readPGF pt path = do + p <- (peekCString path) + result <- (readPGF p) + poke pt result + +foreign export ccall gf_readLanguage :: Ptr Language -> CString -> IO Bool +gf_readLanguage pt str = do + s <- (peekCString str) + case (readLanguage s) of + Just x -> do + poke pt x + return True + Nothing -> return False + +foreign export ccall gf_startCat :: Ptr PGF -> Ptr Type -> IO () +gf_startCat ppgf pcat= do + pgf <- peek ppgf + poke pcat (startCat pgf) + +foreign export ccall gf_parse :: Ptr PGF -> Ptr Language -> Ptr Type -> CString -> IO (Ptr Tree) +gf_parse ppgf plang pcat input = do + p <- peek ppgf + c <- peek pcat + i <- peekCString input + l <- peek plang + let parsed = parse p l c i + -- putStrLn $ (show $ length parsed) ++ " parsings" + listToArray $ parsed + +foreign export ccall gf_showExpr :: Ptr Expr -> IO CString +gf_showExpr pexpr = do + e <- peek pexpr + newCString (showExpr [] e) + +listToArray :: Storable a => [a] -> IO (Ptr a) +listToArray list = do + buf <- mallocBytes $ (#size PyGF) * (length list + 1) + sequence $ zipWith (dpoke buf) [0..] list + return buf + where + dpoke buf n x = do + pokeElemOff buf n x + +foreign export ccall gf_showLanguage :: Ptr Language -> IO CString +gf_showLanguage plang = do + l <- peek plang + newCString $ showLanguage l + +foreign export ccall gf_showType :: Ptr Type -> IO CString +gf_showType ptp = do + t <- peek ptp + newCString $ showType [] t \ No newline at end of file diff --git a/contrib/py-bindings/mtest.c b/contrib/py-bindings/mtest.c new file mode 100644 index 000000000..1a323468a --- /dev/null +++ b/contrib/py-bindings/mtest.c @@ -0,0 +1,66 @@ +/* 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 . +*/ + +#include +#include +#include "pygf.h" +//#include "gf_lexing.h" + +PyGF pgf, lang, cat; + +int main(int argc, char *argv[]) +{ + int has_lang; + gf_init(&argc, &argv); + printf("Passed init\n"); + gf_readPGF(&pgf, "Query.pgf"); + printf("passed readPGF\n"); + if (!gf_readLanguage(&lang, "QueryEng")) + return 1; + printf("passed readLanguage: %s\n", gf_showLanguage(&lang)); + gf_startCat(&pgf, &cat); + printf("passed startcat: %s\n", gf_showType(&cat)); + // char *lexed = gf_stringOp("lextext")("Is 2 prime"); + char lexed[] = "is 23 odd"; + PyGF *result = gf_parse(&pgf, &lang, &cat, &lexed); + int k; + for (k = 0; result[k].sp ; k++) { + char *str = gf_showExpr(&result[k]); + puts(str); + free(str); + printf("next: 0x%x\n",result[k+1].sp); + } + /* // free(lexed); + PyGF *p = result; + if (result[0]) { + int k = 0; + do { + printf("tree %d\n",++k); + char *str = gf_showExpr(*(p++)); + puts(str); + free(str); + } while (*p && k < 5); + } else + puts("no match"); + gf_freeTrees(result); + gf_freeType(cat); + gf_freeLanguage(lang); + gf_freePGF(pgf); */ + + gf_exit(); + return 0; +} diff --git a/contrib/py-bindings/pygf.h b/contrib/py-bindings/pygf.h new file mode 100644 index 000000000..3a63090ca --- /dev/null +++ b/contrib/py-bindings/pygf.h @@ -0,0 +1,68 @@ +#include +//#include "pgf.h" +#include "HsFFI.h" + +#ifdef __GLASGOW_HASKELL__ +#include "PyGF_stub.h" + +extern void __stginit_PyGF ( void ); +#endif + +static inline void gf_init(int *argc, char ***argv) +{ + hs_init(argc, argv); +#ifdef __GLASGOW_HASKELL__ + hs_add_root(__stginit_PyGF); +#endif +} + +static inline void gf_exit(void) +{ + hs_exit(); +} + +typedef HsStablePtr GF_PGF; +typedef HsStablePtr GF_CId; +typedef HsStablePtr GF_Language; +typedef HsStablePtr GF_Type; +typedef HsStablePtr GF_Tree; +typedef HsStablePtr GF_Expr; +typedef struct { + PyObject_HEAD; + HsStablePtr sp; +} PyGF; + +#define NEWOBJECT(OBJ, GFTYPE) typedef struct {\ + PyObject_HEAD \ + GFTYPE obj; \ + } OBJ; + +#define NEWTYPE(TYPE,NAME,OBJECT,DOC) static PyTypeObject TYPE = {\ + PyObject_HEAD_INIT(NULL)\ + 0, /*ob_size*/\ + NAME, /*tp_name*/\ + sizeof(OBJECT), /*tp_basicsize*/\ + 0, /*tp_itemsize*/\ + 0, /*tp_dealloc*/\ + 0, /*tp_print*/\ + 0, /*tp_getattr*/\ + 0, /*tp_setattr*/\ + 0, /*tp_compare*/\ + 0, /*tp_repr*/\ + 0, /*tp_as_number*/\ + 0, /*tp_as_sequence*/\ + 0, /*tp_as_mapping*/\ + 0, /*tp_hash */\ + 0, /*tp_call*/\ + 0, /*tp_str*/\ + 0, /*tp_getattro*/\ + 0, /*tp_setattro*/\ + 0, /*tp_as_buffer*/\ + Py_TPFLAGS_DEFAULT, /*tp_flags*/\ + DOC, /* tp_doc */\ + }; +#define NEWGF(OBJ,GFTYPE,TYPE,NAME,DOC) NEWOBJECT(OBJ,GFTYPE) \ + NEWTYPE(TYPE,NAME,OBJ,DOC) + + +NEWOBJECT(CID, GF_CId)