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)