summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjordi.saludes <jordi.saludes@upc.edu>2010-07-25 14:48:25 +0000
committerjordi.saludes <jordi.saludes@upc.edu>2010-07-25 14:48:25 +0000
commit23eb7b6df612c7b03407d45a3606086d8b182948 (patch)
tree2866748e9827c69f1bfc645aa36063f6ab21110b
parentac23280320313b0e470c8de6d49415e93d3c9d97 (diff)
Added unapplying of Expr in py-bindings.
-rw-r--r--contrib/py-bindings/PyGF.hsc33
-rw-r--r--contrib/py-bindings/gfmodule.c37
-rw-r--r--contrib/py-bindings/test.py15
3 files changed, 80 insertions, 5 deletions
diff --git a/contrib/py-bindings/PyGF.hsc b/contrib/py-bindings/PyGF.hsc
index 27c87b1a0..6ac5b05d7 100644
--- a/contrib/py-bindings/PyGF.hsc
+++ b/contrib/py-bindings/PyGF.hsc
@@ -127,10 +127,7 @@ gf_showExpr pexpr = do
listToPy :: Storable a => IO (Ptr a) -> [a] -> IO (Ptr ()) -- opaque -- IO (Ptr (Ptr Language))
listToPy mk ls = do
- let bufl = length ls + 1
- -- buf <- mallocBytes $ (#size PyGF) * bufl
pyls <- pyList
- -- pokeElemOff buf (length ls) nullPtr
mapM_ (mpoke pyls) ls
return pyls
where mpoke pyl l = do
@@ -138,7 +135,6 @@ listToPy mk ls = do
poke pl l
pyl << pl
-
-- foreign export ccall "gf_freeArray" free :: Ptr a -> IO ()
@@ -194,9 +190,38 @@ gf_showCId pcid = do
cid <- peek pcid
newCString $ showCId cid
+foreign export ccall gf_unapp :: Ptr Expr -> IO (Ptr ())
+foreign export ccall gf_unint :: Ptr Expr -> IO CInt
+foreign export ccall gf_unstr :: Ptr Expr -> IO CString
+
+gf_unapp pexp = do
+ exp <- peek pexp
+ case unApp exp of
+ Just (f,args) -> do
+ puexp <- pyList
+ pf <- pyCId
+ poke pf f
+ puexp << pf
+ mapM_ (\e -> do
+ pe <- pyExpr
+ poke pe e
+ puexp << pe) args
+ return puexp
+ Nothing -> return nullPtr
+gf_unint pexp = do
+ exp <- peek pexp
+ return $ fromIntegral $ case unInt exp of
+ Just n -> n
+ _ -> (-9)
+gf_unstr pexp = do
+ exp <- peek pexp
+ case unStr exp of
+ Just s -> newCString s
+ _ -> return nullPtr
foreign import ccall "newLang" pyLang :: IO (Ptr Language)
foreign import ccall "newTree" pyTree :: IO (Ptr Tree)
foreign import ccall "newCId" pyCId :: IO (Ptr CId)
+foreign import ccall "newExpr" pyExpr :: IO (Ptr Expr)
foreign import ccall "newList" pyList :: IO (Ptr ())
foreign import ccall "append" (<<) :: Ptr () -> Ptr a -> IO ()
diff --git a/contrib/py-bindings/gfmodule.c b/contrib/py-bindings/gfmodule.c
index 8c04de5d2..06896b9ba 100644
--- a/contrib/py-bindings/gfmodule.c
+++ b/contrib/py-bindings/gfmodule.c
@@ -225,6 +225,38 @@ DEALLOCFN(expr_dealloc, Expr, gf_freeExpr, "freeExpr")
REPRCB(expr_repr, Expr, gf_showExpr)
+static PyObject*
+unapp(Expr *self) {
+ PyObject* obj = gf_unapp(self);
+ if (!obj) {
+ char* s = gf_unstr(self);
+ if (s) {
+ obj = PyString_FromString(s);
+ free(s);
+ } else {
+ long n = gf_unint(self);
+ if (n != -9) {
+ obj = PyInt_FromLong(n);
+ } else {
+ PyErr_Format(PyExc_TypeError, "Cannot unapply expr.");
+ }
+ }
+ }
+ return obj;
+}
+
+static PyMethodDef tree_methods[] = {
+ {"unapply", (PyCFunction)unapp, METH_NOARGS,"Unapply a tree."},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+static PyMethodDef expr_methods[] = {
+ {"unapply", (PyCFunction)unapp, METH_NOARGS,"Unapply an expression."},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+
+
/* tree typr: methods, constructor and destructor */
// Are Expr and Tree equivalent ?
@@ -232,6 +264,9 @@ REPRCB(tree_repr, Tree, gf_showExpr)
DEALLOCFN(Tree_dealloc, Tree, gf_freeTree, "freeTree")
+
+
+
/* gf module methods */
static PyMethodDef gf_methods[] = {
@@ -260,7 +295,9 @@ initgf(void)
READYTYPE(PGFType, pgf_repr, PGF_dealloc)
READYTYPE(LangType, lang_repr, Lang_dealloc)
READYTYPE(gfTypeType, gfType_repr, gfType_dealloc)
+ ExprType.tp_methods = expr_methods;
READYTYPE(ExprType, expr_repr, expr_dealloc)
+ TreeType.tp_methods = tree_methods;
READYTYPE(TreeType, tree_repr, Tree_dealloc)
m = Py_InitModule3("gf", gf_methods,
diff --git a/contrib/py-bindings/test.py b/contrib/py-bindings/test.py
index 716aba6c3..69b1f000a 100644
--- a/contrib/py-bindings/test.py
+++ b/contrib/py-bindings/test.py
@@ -101,6 +101,19 @@ class TestTranslate(unittest.TestCase):
assert len(parsed) == 1
lin = self.pgf.lin(m,parsed[0])
self.assertEqual(lin,cnc[j])
-
+
+class TestUnapplyExpr(unittest.TestCase):
+ def setUp(self):
+ self.pgf = gf.read_pgf('Query.pgf')
+ self.langs = dict([(lang2iso(l),l) for l in self.pgf.languages()])
+
+ def test_unapply(self):
+ ps = self.pgf.parse('is 23 odd',self.langs['eng'])
+ f,es = ps[0].unapply()
+ self.assertEqual(`f`,'Odd')
+ f,es = es.unapply()
+ self.assertEqual(`f`,'Number')
+ self.assertEqual(es.unapply(),23)
+
if __name__ == '__main__':
unittest.main()