From 7dba3465d0d3b27b4105f0c96233fa7a655ab348 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 20 Sep 2021 23:42:50 +0200 Subject: [PATCH 1/6] Refactor modules in Python bindings. Start work on grammar-update functions, but without transactions. --- .gitignore | 4 +- src/runtime/python/expr.c | 2 +- src/runtime/python/{marshaller.c => ffi.c} | 20 +++- src/runtime/python/{marshaller.h => ffi.h} | 9 ++ src/runtime/python/pypgf.c | 55 +++++----- src/runtime/python/setup.py | 7 +- .../{test_suite.py => tests/test_basic.py} | 0 src/runtime/python/tests/test_transactions.py | 41 +++++++ src/runtime/python/transactions.c | 102 ++++++++++++++++++ src/runtime/python/transactions.h | 38 +++++++ 10 files changed, 243 insertions(+), 35 deletions(-) rename src/runtime/python/{marshaller.c => ffi.c} (95%) rename src/runtime/python/{marshaller.h => ffi.h} (67%) rename src/runtime/python/{test_suite.py => tests/test_basic.py} (100%) create mode 100644 src/runtime/python/tests/test_transactions.py create mode 100644 src/runtime/python/transactions.c create mode 100644 src/runtime/python/transactions.h diff --git a/.gitignore b/.gitignore index 8e9cac9a3..aedc1fd42 100644 --- a/.gitignore +++ b/.gitignore @@ -47,8 +47,8 @@ src/runtime/c/sg/.dirstamp src/runtime/c/stamp-h1 src/runtime/java/.libs/ src/runtime/python/build/ -src/runtime/python/__pycache__/ -src/runtime/python/.pytest_cache/ +src/runtime/python/**/__pycache__/ +src/runtime/python/**/.pytest_cache/ .cabal-sandbox cabal.sandbox.config .stack-work diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index 2a90b9e18..b36a8b80d 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -4,7 +4,7 @@ #include #include "./expr.h" -#include "./marshaller.h" +#include "./ffi.h" // ---------------------------------------------------------------------------- diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/ffi.c similarity index 95% rename from src/runtime/python/marshaller.c rename to src/runtime/python/ffi.c index 562d7853f..74e95fdf6 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/ffi.c @@ -5,7 +5,25 @@ #include #include "./expr.h" -#include "./marshaller.h" +#include "./ffi.h" + +/* static */ +PyObject *PGFError; + +/* static */ +PgfExnType handleError(PgfExn err) +{ + if (err.type == PGF_EXN_SYSTEM_ERROR) { + errno = err.code; + PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg); + } else if (err.type == PGF_EXN_PGF_ERROR) { + PyErr_SetString(PGFError, err.msg); + free((char*) err.msg); + } else if (err.type == PGF_EXN_OTHER_ERROR) { + PyErr_SetString(PGFError, "an unknown error occured"); + } + return err.type; +} // ---------------------------------------------------------------------------- diff --git a/src/runtime/python/marshaller.h b/src/runtime/python/ffi.h similarity index 67% rename from src/runtime/python/marshaller.h rename to src/runtime/python/ffi.h index 032b0f90b..c8b140c02 100644 --- a/src/runtime/python/marshaller.h +++ b/src/runtime/python/ffi.h @@ -6,6 +6,15 @@ #include +typedef struct { + PyObject_HEAD + PgfDB *db; + PgfRevision revision; +} PGFObject; + +extern PyObject *PGFError; +PgfExnType handleError(PgfExn err); + PgfText *PyUnicode_AsPgfText(PyObject *pystr); PyObject *PyUnicode_FromPgfText(PgfText *text); diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 3fe02a86c..b53820a7d 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -4,35 +4,13 @@ #include #include "./expr.h" -#include "./marshaller.h" - -static PyObject *PGFError; - -static -PgfExnType handleError(PgfExn err) -{ - if (err.type == PGF_EXN_SYSTEM_ERROR) { - errno = err.code; - PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg); - } else if (err.type == PGF_EXN_PGF_ERROR) { - PyErr_SetString(PGFError, err.msg); - free((char*) err.msg); - } else if (err.type == PGF_EXN_OTHER_ERROR) { - PyErr_SetString(PGFError, "an unknown error occured"); - } - return err.type; -} +#include "./ffi.h" +#include "./transactions.h" // static PyObject* ParseError; // static PyObject* TypeError; -typedef struct { - PyObject_HEAD - PgfDB *db; - PgfRevision revision; -} PGFObject; - // typedef struct IterObject { // PyObject_HEAD // PyObject* source; @@ -1753,9 +1731,9 @@ typedef struct { // gu_buf_push((GuBuf*) clo->collection, PgfConcr*, concr); // } -static PyObject* -PGF_str(PGFObject *self) -{ +// static PyObject* +// PGF_str(PGFObject *self) +// { // GuPool* tmp_pool = gu_local_pool(); // // GuExn* err = gu_exn(tmp_pool); @@ -1776,8 +1754,8 @@ PGF_str(PGFObject *self) // // gu_pool_free(tmp_pool); // return pystr; - return NULL; -} +// return NULL; +// } static PyObject* PGF_getAbstractName(PGFObject *self, void *closure) @@ -2410,6 +2388,21 @@ static PyMethodDef PGF_methods[] = { {"functionIsConstructor", (PyCFunction)PGF_functionIsConstructor, METH_VARARGS, "Checks whether a function is a constructor" }, + + + {"createFunction", (PyCFunction)PGF_createFunction, METH_VARARGS, + "Create function" + }, + {"dropFunction", (PyCFunction)PGF_dropFunction, METH_VARARGS, + "Drop function" + }, + {"createCategory", (PyCFunction)PGF_createCategory, METH_VARARGS, + "Create category" + }, + {"dropCategory", (PyCFunction)PGF_dropCategory, METH_VARARGS, + "Drop category" + }, + // {"generateAll", (PyCFunction)PGF_generateAll, METH_VARARGS | METH_KEYWORDS, // "Generates abstract syntax trees of given category in decreasing probability order" // }, @@ -2454,7 +2447,7 @@ static PyTypeObject pgf_PGFType = { 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ - (reprfunc) PGF_str, /*tp_str*/ + 0, // (reprfunc) PGF_str, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ @@ -2479,6 +2472,8 @@ static PyTypeObject pgf_PGFType = { 0, /*tp_new */ }; +// ---------------------------------------------------------------------------- + static PGFObject* pgf_readPGF(PyObject *self, PyObject *args) { diff --git a/src/runtime/python/setup.py b/src/runtime/python/setup.py index c41b11aeb..208857f70 100644 --- a/src/runtime/python/setup.py +++ b/src/runtime/python/setup.py @@ -10,7 +10,12 @@ if libraries==['']: pgf_module = Extension( 'pgf', - sources = ['pypgf.c', 'marshaller.c', 'expr.c'], + sources = [ + 'pypgf.c', + 'expr.c', + 'ffi.c', + 'transactions.c' + ], extra_compile_args = ['-std=c99', '-Werror', '-Wno-error=unused-variable', '-Wno-comment'], include_dirs = includes, library_dirs = libraries, diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/tests/test_basic.py similarity index 100% rename from src/runtime/python/test_suite.py rename to src/runtime/python/tests/test_basic.py diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py new file mode 100644 index 000000000..26ea56a0d --- /dev/null +++ b/src/runtime/python/tests/test_transactions.py @@ -0,0 +1,41 @@ +import pytest +from pgf import * + +ty = readType("(N -> N) -> P (s z)") +pi = 3.142 + +# @pytest.fixture(scope="module") +# def gr1(): +# return pgf.readPGF("../haskell/tests/basic.pgf") +# +# @pytest.fixture(scope="module") +# def gr2(gr1): +# transaction = [ +# createFunction("foo", ty, 0, pi), +# createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], pi) +# ] +# return gr1.modifyPGF(transaction) +# +# @pytest.fixture(scope="module") +# def gr3(gr1): +# transaction = [ +# createFunction("bar", ty, 0, pi), +# createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], pi) +# ] +# return gr1.branchPGF("bar_branch", transaction) +# +# def original_functions(gr1): +# assert gr1.functions == ["c", "ind", "s", "z"] +# +# def extended_functions(gr2): +# assert gr2.functions == ["c", "foo", "ind", "s", "z"] +# +# def branched_functions(gr3): +# assert gr3.functions == ["bar", "c", "ind", "s", "z"] + +def test_non_transactional(): + gr1 = readPGF("../haskell/tests/basic.pgf") + assert gr1.functions == ["c", "ind", "s", "z"] + + gr1.createFunction("foo", ty, 0, pi) + assert gr1.functions == ["c", "foo", "ind", "s", "z"] diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c new file mode 100644 index 000000000..8ff2e2e58 --- /dev/null +++ b/src/runtime/python/transactions.c @@ -0,0 +1,102 @@ +#define PY_SSIZE_T_CLEAN +#include +// #include + +#include +#include "./expr.h" +#include "./ffi.h" + +PyObject * +PGF_createFunction(PGFObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + TypeObject *type; + Py_ssize_t arity = 0; + float prob = 0.0; + if (!PyArg_ParseTuple(args, "s#O!nf", &s, &size, &pgf_TypeType, &type, &arity, &prob)) + return NULL; + + PgfText *fname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(fname->text, s, size+1); + fname->size = size; + + PgfExn err; + pgf_create_function(self->db, self->revision, fname, (PgfType) type, arity, prob, &marshaller, &err); + PyMem_Free(fname); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * +PGF_dropFunction(PGFObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &s, &size)) + return NULL; + + PgfText *fname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(fname->text, s, size+1); + fname->size = size; + + PgfExn err; + pgf_drop_category(self->db, self->revision, fname, &err); + PyMem_Free(fname); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * +PGF_createCategory(PGFObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + float prob = 0.0; + if (!PyArg_ParseTuple(args, "s#f", &s, &size, prob)) + return NULL; + + PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(catname->text, s, size+1); + catname->size = size; + + Py_ssize_t n_hypos = 0; + PgfTypeHypo *context = NULL; + + PgfExn err; + pgf_create_category(self->db, self->revision, catname, n_hypos, context, prob, &marshaller, &err); + PyMem_Free(catname); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * +PGF_dropCategory(PGFObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &s, &size)) + return NULL; + + PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(catname->text, s, size+1); + catname->size = size; + + PgfExn err; + pgf_drop_function(self->db, self->revision, catname, &err); + PyMem_Free(catname); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + Py_RETURN_NONE; +} diff --git a/src/runtime/python/transactions.h b/src/runtime/python/transactions.h new file mode 100644 index 000000000..39b6a1e0e --- /dev/null +++ b/src/runtime/python/transactions.h @@ -0,0 +1,38 @@ +#ifndef PYPGF_TRANSACTIONS_H_ +#define PYPGF_TRANSACTIONS_H_ + +#define PY_SSIZE_T_CLEAN +#include + +#include + +// typedef struct { +// PyObject_HEAD +// PyObject *thing; +// } TransactionObject; + +// modifyPGF +// +// branchPGF +// +// checkoutPGF + +PyObject * +PGF_createFunction(PGFObject *self, PyObject *args); + +PyObject * +PGF_dropFunction(PGFObject *self, PyObject *args); + +PyObject * +PGF_createCategory(PGFObject *self, PyObject *args); + +PyObject * +PGF_dropCategory(PGFObject *self, PyObject *args); + +// setGlobalFlag +// +// setAbstractFlag + + + +#endif // PYPGF_TRANSACTIONS_H_ From 6edf7e6405c019765cfe4a0cf671d2613612d3ba Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 21 Sep 2021 14:55:20 +0200 Subject: [PATCH 2/6] Add Transaction type to Python bindings, get first tests working. --- src/runtime/python/ffi.h | 6 +- src/runtime/python/pypgf.c | 110 ++++--- src/runtime/python/tests/test_basic.py | 276 +++++++++--------- src/runtime/python/tests/test_transactions.py | 75 ++--- src/runtime/python/transactions.c | 128 +++++++- src/runtime/python/transactions.h | 33 +-- 6 files changed, 371 insertions(+), 257 deletions(-) diff --git a/src/runtime/python/ffi.h b/src/runtime/python/ffi.h index c8b140c02..751cd74f8 100644 --- a/src/runtime/python/ffi.h +++ b/src/runtime/python/ffi.h @@ -1,5 +1,5 @@ -#ifndef PYPGF_MARSHALLER_H_ -#define PYPGF_MARSHALLER_H_ +#ifndef PYPGF_FFI_H_ +#define PYPGF_FFI_H_ #define PY_SSIZE_T_CLEAN #include @@ -21,4 +21,4 @@ PyObject *PyUnicode_FromPgfText(PgfText *text); extern PgfUnmarshaller unmarshaller; extern PgfMarshaller marshaller; -#endif // PYPGF_MARSHALLER_H_ +#endif // PYPGF_FFI_H_ diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index b53820a7d..dc8baa233 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -1710,16 +1710,16 @@ // }; static void -PGF_dealloc(PGFObject* self) +PGF_dealloc(PGFObject *self) { pgf_free(self->db); - Py_TYPE(self)->tp_free((PyObject*)self); + Py_TYPE(self)->tp_free((PyObject *)self); } typedef struct { PgfItor fn; - PGFObject* grammar; - void* collection; + PGFObject *grammar; + void *collection; } PyPGFClosure; // static void @@ -1757,11 +1757,11 @@ typedef struct { // return NULL; // } -static PyObject* +static PyObject * PGF_getAbstractName(PGFObject *self, void *closure) { PgfExn err; - PgfText* txt = pgf_abstract_name(self->db, self->revision, &err); + PgfText *txt = pgf_abstract_name(self->db, self->revision, &err); if (handleError(err) != PGF_EXN_NONE) { return NULL; @@ -1837,12 +1837,12 @@ PGF_getAbstractName(PGFObject *self, void *closure) // } static void -pgf_collect_cats(PgfItor* fn, PgfText* key, void* value, PgfExn *err) +pgf_collect_cats(PgfItor *fn, PgfText *key, void *value, PgfExn *err) { - PgfText* name = key; - PyPGFClosure* clo = (PyPGFClosure*) fn; + PgfText *name = key; + PyPGFClosure *clo = (PyPGFClosure*) fn; - PyObject* py_name = PyUnicode_FromStringAndSize(name->text, name->size); + PyObject *py_name = PyUnicode_FromStringAndSize(name->text, name->size); if (py_name == NULL) { err->type = PGF_EXN_OTHER_ERROR; err->msg = "unable to create string from category"; @@ -1856,10 +1856,10 @@ pgf_collect_cats(PgfItor* fn, PgfText* key, void* value, PgfExn *err) } } -static PyObject* +static PyObject * PGF_getCategories(PGFObject *self, void *closure) { - PyObject* categories = PyList_New(0); + PyObject *categories = PyList_New(0); if (categories == NULL) return NULL; @@ -1874,7 +1874,7 @@ PGF_getCategories(PGFObject *self, void *closure) return categories; } -static PyObject* +static PyObject * PGF_categoryContext(PGFObject *self, PyObject *args) { const char *s; @@ -1937,12 +1937,12 @@ PGF_getStartCat(PGFObject *self, void *closure) } static void -pgf_collect_funs(PgfItor* fn, PgfText* key, void* value, PgfExn *err) +pgf_collect_funs(PgfItor *fn, PgfText *key, void *value, PgfExn *err) { - PgfText* name = key; - PyPGFClosure* clo = (PyPGFClosure*) fn; + PgfText *name = key; + PyPGFClosure *clo = (PyPGFClosure*) fn; - PyObject* py_name = PyUnicode_FromStringAndSize(name->text, name->size); + PyObject *py_name = PyUnicode_FromStringAndSize(name->text, name->size); if (py_name == NULL) { err->type = PGF_EXN_OTHER_ERROR; err->msg = "unable to create string from function"; @@ -1955,10 +1955,10 @@ pgf_collect_funs(PgfItor* fn, PgfText* key, void* value, PgfExn *err) } } -static PyObject* +static PyObject * PGF_getFunctions(PGFObject *self, void *closure) { - PyObject* functions = PyList_New(0); + PyObject *functions = PyList_New(0); if (functions == NULL) return NULL; @@ -2389,18 +2389,8 @@ static PyMethodDef PGF_methods[] = { "Checks whether a function is a constructor" }, - - {"createFunction", (PyCFunction)PGF_createFunction, METH_VARARGS, - "Create function" - }, - {"dropFunction", (PyCFunction)PGF_dropFunction, METH_VARARGS, - "Drop function" - }, - {"createCategory", (PyCFunction)PGF_createCategory, METH_VARARGS, - "Create category" - }, - {"dropCategory", (PyCFunction)PGF_dropCategory, METH_VARARGS, - "Drop category" + {"newTransaction", (PyCFunction)PGF_newTransaction, METH_VARARGS, + "Create new transaction" }, // {"generateAll", (PyCFunction)PGF_generateAll, METH_VARARGS | METH_KEYWORDS, @@ -2474,14 +2464,14 @@ static PyTypeObject pgf_PGFType = { // ---------------------------------------------------------------------------- -static PGFObject* +static PGFObject * pgf_readPGF(PyObject *self, PyObject *args) { const char *fpath; if (!PyArg_ParseTuple(args, "s", &fpath)) return NULL; - PGFObject* py_pgf = (PGFObject*) pgf_PGFType.tp_alloc(&pgf_PGFType, 0); + PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0); // Read the PGF grammar. PgfExn err; @@ -2494,7 +2484,7 @@ pgf_readPGF(PyObject *self, PyObject *args) return py_pgf; } -static PGFObject* +static PGFObject * pgf_bootNGF(PyObject *self, PyObject *args) { const char *fpath; // pgf @@ -2502,7 +2492,7 @@ pgf_bootNGF(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "ss", &fpath, &npath)) return NULL; - PGFObject* py_pgf = (PGFObject*) pgf_PGFType.tp_alloc(&pgf_PGFType, 0); + PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0); // Read the PGF grammar. PgfExn err; @@ -2515,14 +2505,14 @@ pgf_bootNGF(PyObject *self, PyObject *args) return py_pgf; } -static PGFObject* +static PGFObject * pgf_readNGF(PyObject *self, PyObject *args) { const char *fpath; if (!PyArg_ParseTuple(args, "s", &fpath)) return NULL; - PGFObject* py_pgf = (PGFObject*) pgf_PGFType.tp_alloc(&pgf_PGFType, 0); + PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0); // Read the NGF grammar. PgfExn err; @@ -2535,7 +2525,7 @@ pgf_readNGF(PyObject *self, PyObject *args) return py_pgf; } -static PGFObject* +static PGFObject * pgf_newNGF(PyObject *self, PyObject *args) { const char *s; @@ -2548,7 +2538,7 @@ pgf_newNGF(PyObject *self, PyObject *args) memcpy(absname->text, s, size+1); absname->size = size; - PGFObject* py_pgf = (PGFObject*) pgf_PGFType.tp_alloc(&pgf_PGFType, 0); + PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0); // Read the NGF grammar. PgfExn err; @@ -2769,9 +2759,15 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_PGFType) < 0) return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_TransactionType) < 0) + return MOD_ERROR_VAL; + // if (PyType_Ready(&pgf_ConcrType) < 0) // return MOD_ERROR_VAL; // + // if (PyType_Ready(&pgf_IterType) < 0) + // return MOD_ERROR_VAL; + // // if (PyType_Ready(&pgf_BracketType) < 0) // return MOD_ERROR_VAL; // @@ -2808,9 +2804,6 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_TypeType) < 0) return MOD_ERROR_VAL; - // if (PyType_Ready(&pgf_IterType) < 0) - // return MOD_ERROR_VAL; - MOD_DEF(m, "pgf", "The Runtime for Portable Grammar Format in Python", module_methods); if (m == NULL) return MOD_ERROR_VAL; @@ -2829,6 +2822,24 @@ MOD_INIT(pgf) // PyModule_AddObject(m, "TypeError", TypeError); // Py_INCREF(TypeError); + PyModule_AddObject(m, "PGF", (PyObject *) &pgf_PGFType); + Py_INCREF(&pgf_PGFType); + + PyModule_AddObject(m, "Transaction", (PyObject *) &pgf_TransactionType); + Py_INCREF(&pgf_TransactionType); + + // PyModule_AddObject(m, "Concr", (PyObject *) &pgf_ConcrType); + // Py_INCREF(&pgf_ConcrType); + // + // PyModule_AddObject(m, "Iter", (PyObject *) &pgf_IterType); + // Py_INCREF(&pgf_IterType); + // + // PyModule_AddObject(m, "Bracket", (PyObject *) &pgf_BracketType); + // Py_INCREF(&pgf_BracketType); + // + // PyModule_AddObject(m, "BIND", (PyObject *) &pgf_BINDType); + // Py_INCREF(&pgf_BINDType); + PyModule_AddObject(m, "Expr", (PyObject *) &pgf_ExprType); Py_INCREF(&pgf_ExprType); @@ -2859,21 +2870,6 @@ MOD_INIT(pgf) PyModule_AddObject(m, "Type", (PyObject *) &pgf_TypeType); Py_INCREF(&pgf_TypeType); - PyModule_AddObject(m, "PGF", (PyObject *) &pgf_PGFType); - Py_INCREF(&pgf_PGFType); - - // PyModule_AddObject(m, "Concr", (PyObject *) &pgf_ConcrType); - // Py_INCREF(&pgf_ConcrType); - // - // PyModule_AddObject(m, "Iter", (PyObject *) &pgf_IterType); - // Py_INCREF(&pgf_IterType); - // - // PyModule_AddObject(m, "Bracket", (PyObject *) &pgf_BracketType); - // Py_INCREF(&pgf_BracketType); - // - // PyModule_AddObject(m, "BIND", (PyObject *) &pgf_BINDType); - // Py_INCREF(&pgf_BINDType); - PyModule_AddIntConstant(m, "BIND_TYPE_EXPLICIT", 0); PyModule_AddIntConstant(m, "BIND_TYPE_IMPLICIT", 1); diff --git a/src/runtime/python/tests/test_basic.py b/src/runtime/python/tests/test_basic.py index fdee52434..161571e32 100644 --- a/src/runtime/python/tests/test_basic.py +++ b/src/runtime/python/tests/test_basic.py @@ -1,81 +1,81 @@ import os import pytest -import pgf +from pgf import * # readPGF @pytest.fixture(scope="module") def PGF(): - return pgf.readPGF("../haskell/tests/basic.pgf") + return readPGF("../haskell/tests/basic.pgf") def test_readPGF_non_existant(): with pytest.raises(FileNotFoundError): - pgf.readPGF("../haskell/tests/abc.pgf") + readPGF("../haskell/tests/abc.pgf") def test_readPGF_GF(): - with pytest.raises(pgf.PGFError): - pgf.readPGF("../haskell/tests/basic.gf") + with pytest.raises(PGFError): + readPGF("../haskell/tests/basic.gf") def test_readPGF_NGF(NGF): - with pytest.raises(pgf.PGFError): - pgf.readPGF("./basic.ngf") + with pytest.raises(PGFError): + readPGF("./basic.ngf") # bootNGF @pytest.fixture(scope="module") def NGF(): - ngf = pgf.bootNGF("../haskell/tests/basic.pgf", "./basic.ngf") + ngf = bootNGF("../haskell/tests/basic.pgf", "./basic.ngf") yield ngf os.remove("./basic.ngf") def test_bootNGF_non_existant(): with pytest.raises(FileNotFoundError): - pgf.bootNGF("../haskell/tests/abc.pgf", "./abc.ngf") + bootNGF("../haskell/tests/abc.pgf", "./abc.ngf") def test_bootNGF_GF(): - with pytest.raises(pgf.PGFError): - pgf.bootNGF("../haskell/tests/basic.gf", "./abc.ngf") + with pytest.raises(PGFError): + bootNGF("../haskell/tests/basic.gf", "./abc.ngf") def test_bootNGF_NGF(NGF): - with pytest.raises(pgf.PGFError): - pgf.bootNGF("./basic.ngf", "./abc.ngf") + with pytest.raises(PGFError): + bootNGF("./basic.ngf", "./abc.ngf") def test_bootNGF_existing(NGF): with pytest.raises(FileExistsError): - pgf.bootNGF("../haskell/tests/basic.pgf", "./basic.ngf") + bootNGF("../haskell/tests/basic.pgf", "./basic.ngf") # readNGF def test_readNGF_non_existant(): with pytest.raises(FileNotFoundError): - pgf.readNGF("./abc.ngf") + readNGF("./abc.ngf") def test_readNGF_GF(): - with pytest.raises(pgf.PGFError): - pgf.readNGF("../haskell/tests/basic.gf") + with pytest.raises(PGFError): + readNGF("../haskell/tests/basic.gf") def test_readNGF_PGF(): - with pytest.raises(pgf.PGFError): - pgf.readNGF("../haskell/tests/basic.pgf") + with pytest.raises(PGFError): + readNGF("../haskell/tests/basic.pgf") def test_readNGF(NGF): - PGF = pgf.readNGF("./basic.ngf") + PGF = readNGF("./basic.ngf") assert len(PGF.categories) > 0 # newNGF def test_newNGF_file(NGF): - PGF = pgf.newNGF("empty", "./empty.ngf") + PGF = newNGF("empty", "./empty.ngf") assert len(PGF.categories) == 0 os.remove("./empty.ngf") # cleanup def test_newNGF_memory(NGF): - PGF = pgf.newNGF("empty") + PGF = newNGF("empty") assert len(PGF.categories) == 0 def test_newNGF_existing(NGF): with pytest.raises(FileExistsError): - pgf.newNGF("empty", "./basic.ngf") + newNGF("empty", "./basic.ngf") # abstract syntax @@ -109,7 +109,7 @@ def test_categoryContext_3(PGF): tup = cxt[0] assert tup[0] == 0 # explicit assert tup[1] == "_" # cid - assert tup[2] == pgf.readType("N") + assert tup[2] == readType("N") def test_categoryContext_4(PGF): assert PGF.categoryContext("X") == None @@ -129,293 +129,293 @@ def test_functionIsConstructor_4(PGF): # types def test_readType_invalid(): - with pytest.raises(pgf.PGFError): - pgf.readType("->") + with pytest.raises(PGFError): + readType("->") def test_readType_equality_1(): - assert pgf.readType("A") == pgf.readType("A") + assert readType("A") == readType("A") def test_readType_equality_2(): - assert pgf.readType("A -> B") == pgf.readType("A->B") + assert readType("A -> B") == readType("A->B") def test_readType_equality_3(): - assert pgf.readType("A -> B -> C") == pgf.readType("A->B -> C") + assert readType("A -> B -> C") == readType("A->B -> C") def test_readType_inequality_1(): - assert pgf.readType("A") != pgf.readType("B") + assert readType("A") != readType("B") def test_readType_inequality_2(): - assert pgf.readType("A -> B") != pgf.readType("B->B") + assert readType("A -> B") != readType("B->B") def test_readType_str(): - assert str(pgf.readType("A-> BÄ->C")) == "A -> BÄ -> C" + assert str(readType("A-> BÄ->C")) == "A -> BÄ -> C" def test_functionType_1(PGF): - assert PGF.functionType("z") == pgf.readType("N") + assert PGF.functionType("z") == readType("N") def test_functionType_2(PGF): - assert PGF.functionType("s") == pgf.readType("N->N") + assert PGF.functionType("s") == readType("N->N") def test_functionType_3(PGF): - assert PGF.functionType("c") == pgf.readType("N -> S") + assert PGF.functionType("c") == readType("N -> S") def test_functionType_non_existant(PGF): with pytest.raises(KeyError): assert PGF.functionType("cbx") def test_functionType_wrong(PGF): - assert PGF.functionType("c") != pgf.readType("N -> S -> X") + assert PGF.functionType("c") != readType("N -> S -> X") def test_startCat(PGF): - assert PGF.startCat == pgf.readType("S") + assert PGF.startCat == readType("S") def test_showType_1(PGF): - type = pgf.Type([], "N", []) - assert pgf.showType([], type) == "N" + type = Type([], "N", []) + assert showType([], type) == "N" def test_showType_2(PGF): - type = pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []) - assert pgf.showType([], type) == "N -> N" + type = Type([mkHypo(Type([], "N", []))], "N", []) + assert showType([], type) == "N -> N" def test_showType_3(PGF): - type = pgf.Type([pgf.mkHypo(pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "N", []) - assert pgf.showType([], type) == "(N -> N) -> N" + type = Type([mkHypo(Type([mkHypo(Type([], "N", []))], "N", []))], "N", []) + assert showType([], type) == "(N -> N) -> N" def test_showType_4(PGF): - type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", []))], "P", [pgf.ExprVar(0)]) - assert pgf.showType([], type) == "(x : N) -> P x" + type = Type([mkDepHypo("x", Type([], "N", []))], "P", [ExprVar(0)]) + assert showType([], type) == "(x : N) -> P x" def test_showType_5(PGF): - type = pgf.Type([pgf.mkDepHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprFun("z"))]) - assert pgf.showType([], type) == "(f : N -> N) -> P (f z)" + type = Type([mkDepHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprFun("z"))]) + assert showType([], type) == "(f : N -> N) -> P (f z)" def test_showType_6(PGF): - type = pgf.Type([pgf.mkDepHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprVar(1))]) - assert pgf.showType(["n"], type) == "(f : N -> N) -> P (f n)" + type = Type([mkDepHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprVar(1))]) + assert showType(["n"], type) == "(f : N -> N) -> P (f n)" def test_showType_7(PGF): - type = pgf.Type([pgf.mkImplHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprVar(1))]) - assert pgf.showType(["n"], type) == "({f} : N -> N) -> P (f n)" + type = Type([mkImplHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprVar(1))]) + assert showType(["n"], type) == "({f} : N -> N) -> P (f n)" def test_showType_8(PGF): - type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", [])), pgf.mkHypo(pgf.Type([], "P", [pgf.ExprVar(0)]))], "S", []) - assert pgf.showType(["n"], type) == "(x : N) -> P x -> S" + type = Type([mkDepHypo("x", Type([], "N", [])), mkHypo(Type([], "P", [ExprVar(0)]))], "S", []) + assert showType(["n"], type) == "(x : N) -> P x -> S" def test_showType_9(PGF): - type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", [])), pgf.mkDepHypo("y", pgf.Type([], "P", [pgf.ExprVar(0)]))], "S", []) - assert pgf.showType(["n"], type) == "(x : N) -> (y : P x) -> S" + type = Type([mkDepHypo("x", Type([], "N", [])), mkDepHypo("y", Type([], "P", [ExprVar(0)]))], "S", []) + assert showType(["n"], type) == "(x : N) -> (y : P x) -> S" # expressions def test_readExpr_invalid(): - with pytest.raises(pgf.PGFError): - pgf.readExpr("->") + with pytest.raises(PGFError): + readExpr("->") # expressions: literals def test_readExpr_lint_equality(): - assert pgf.readExpr("123") == pgf.ExprLit(123) + assert readExpr("123") == ExprLit(123) def test_readExpr_lint_equality_neg(): - assert pgf.readExpr("-123") == pgf.ExprLit(-123) + assert readExpr("-123") == ExprLit(-123) def test_readExpr_lint_equality_big2(): - assert pgf.readExpr("774763251095801167872") == pgf.ExprLit(774763251095801167872) + assert readExpr("774763251095801167872") == ExprLit(774763251095801167872) def test_readExpr_lint_equality_big2_neg(): - assert pgf.readExpr("-774763251095801167872") == pgf.ExprLit(-774763251095801167872) + assert readExpr("-774763251095801167872") == ExprLit(-774763251095801167872) def test_readExpr_lint_inequality(): - assert pgf.readExpr("123") != pgf.ExprLit(456) + assert readExpr("123") != ExprLit(456) def test_readExpr_lflt_equality(): - assert pgf.readExpr("3.142") == pgf.ExprLit(3.142) + assert readExpr("3.142") == ExprLit(3.142) def test_readExpr_lflt_inequality(): - assert pgf.readExpr("3.142") != pgf.ExprLit(3) + assert readExpr("3.142") != ExprLit(3) def test_readExpr_lstr_equality(): - assert pgf.readExpr("\"abc\"") == pgf.ExprLit("abc") + assert readExpr("\"abc\"") == ExprLit("abc") def test_readExpr_lstr_inequality(): - assert pgf.readExpr("\"abc\"") != pgf.ExprLit("def") + assert readExpr("\"abc\"") != ExprLit("def") def test_readExpr_lint_str(): - assert str(pgf.readExpr("123")) == "123" + assert str(readExpr("123")) == "123" def test_readExpr_lint_str_neg(): - assert str(pgf.readExpr("-123")) == "-123" + assert str(readExpr("-123")) == "-123" def test_readExpr_lint_str_big2(): - assert str(pgf.readExpr("774763251095801167872")) == "774763251095801167872" + assert str(readExpr("774763251095801167872")) == "774763251095801167872" def test_readExpr_lint_str_big3(): - assert str(pgf.readExpr("7747632510958011678729003251095801167999")) == "7747632510958011678729003251095801167999" + assert str(readExpr("7747632510958011678729003251095801167999")) == "7747632510958011678729003251095801167999" def test_readExpr_lint_str_big2_neg(): - assert str(pgf.readExpr("-774763251095801167872")) == "-774763251095801167872" + assert str(readExpr("-774763251095801167872")) == "-774763251095801167872" def test_readExpr_lint_str_big3_neg(): - assert str(pgf.readExpr("-7747632510958011678729003251095801167999")) == "-7747632510958011678729003251095801167999" + assert str(readExpr("-7747632510958011678729003251095801167999")) == "-7747632510958011678729003251095801167999" def test_readExpr_lflt_str(): - assert str(pgf.readExpr("3.142")) == "3.142" + assert str(readExpr("3.142")) == "3.142" def test_readExpr_lstr_str_unicode(): - assert str(pgf.readExpr("\"açġħ\"")) == "\"açġħ\"" + assert str(readExpr("\"açġħ\"")) == "\"açġħ\"" def test_readExpr_lstr_null(): - assert str(pgf.ExprLit("ab\0c")) == "\"ab\\0c\"" + assert str(ExprLit("ab\0c")) == "\"ab\\0c\"" def test_readExpr_lstr_newline(): - assert str(pgf.ExprLit("ab\nc")) == "\"ab\\nc\"" + assert str(ExprLit("ab\nc")) == "\"ab\\nc\"" # expressions: functions def test_readExpr_efun_equality_1(): - assert pgf.readExpr("f") == pgf.ExprFun("f") + assert readExpr("f") == ExprFun("f") def test_readExpr_efun_equality_2(): assert \ - pgf.readExpr("f x y") == \ - pgf.ExprApp( - pgf.ExprApp( - pgf.ExprFun("f"), - pgf.ExprFun("x") + readExpr("f x y") == \ + ExprApp( + ExprApp( + ExprFun("f"), + ExprFun("x") ), - pgf.ExprFun("y") + ExprFun("y") ) def test_readExpr_efun_equality_3(): assert \ - pgf.readExpr("f (g x)") == \ - pgf.ExprApp( - pgf.ExprFun("f"), - pgf.ExprApp( - pgf.ExprFun("g"), - pgf.ExprFun("x") + readExpr("f (g x)") == \ + ExprApp( + ExprFun("f"), + ExprApp( + ExprFun("g"), + ExprFun("x") ) ) def test_readExpr_efun_equality_4(): assert \ - pgf.readExpr("f {g x}") == \ - pgf.ExprApp( - pgf.ExprFun("f"), - pgf.ExprImplArg( - pgf.ExprApp( - pgf.ExprFun("g"), - pgf.ExprFun("x") + readExpr("f {g x}") == \ + ExprApp( + ExprFun("f"), + ExprImplArg( + ExprApp( + ExprFun("g"), + ExprFun("x") ) ) ) def test_readExpr_efun_str_unicode_1(): - assert str(pgf.readExpr("'абв'")) == "'абв'" + assert str(readExpr("'абв'")) == "'абв'" @pytest.mark.skip(reason="failing") def test_readExpr_efun_str_unicode_2(): - assert str(pgf.readExpr("'аb'")) == "аb" + assert str(readExpr("'аb'")) == "аb" @pytest.mark.skip(reason="failing") def test_readExpr_efun_str_unicode_3(): - assert str(pgf.readExpr("'а\\'b'")) == "а'b" + assert str(readExpr("'а\\'b'")) == "а'b" def test_readExpr_efun_str_unicode_4(): - assert str(pgf.readExpr("'а\\'б'")) == "'а\\'б'" + assert str(readExpr("'а\\'б'")) == "'а\\'б'" # expressions: variables # def test_readExpr_evar_equality_1(): -# assert pgf.readExpr("#0") == pgf.ExprVar() -# assert pgf.readExpr("#0") == pgf.ExprVar(0) +# assert readExpr("#0") == ExprVar() +# assert readExpr("#0") == ExprVar(0) # def test_readExpr_evar_equality_2(): -# assert pgf.readExpr("#42") == pgf.ExprVar(42) +# assert readExpr("#42") == ExprVar(42) def test_readExpr_evar_str_1(): - assert str(pgf.ExprVar(0)) == "#0" + assert str(ExprVar(0)) == "#0" def test_readExpr_evar_str_2(): - assert str(pgf.ExprVar(42)) == "#42" + assert str(ExprVar(42)) == "#42" def test_showExpr_evar_1(): - assert pgf.showExpr(["x"], pgf.ExprVar(0)) == "x" + assert showExpr(["x"], ExprVar(0)) == "x" def test_showExpr_evar_2(): - assert pgf.showExpr(["x"], pgf.ExprVar(1)) == "#1" + assert showExpr(["x"], ExprVar(1)) == "#1" def test_showExpr_evar_3(): - assert pgf.showExpr(["z", "y", "x"], pgf.ExprVar(0)) == "z" + assert showExpr(["z", "y", "x"], ExprVar(0)) == "z" def test_showExpr_evar_4(): - assert pgf.showExpr(["z", "y", "x"], pgf.ExprVar(1)) == "y" + assert showExpr(["z", "y", "x"], ExprVar(1)) == "y" # expressions: lambda abstractions def test_showExpr_eabs_1(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "w", pgf.ExprVar(0)) - assert pgf.showExpr(["z", "y", "x"], expr) == "\\w->w" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "w", ExprVar(0)) + assert showExpr(["z", "y", "x"], expr) == "\\w->w" def test_showExpr_eabs_2(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "w", pgf.ExprVar(2))) - assert pgf.showExpr(["z", "y", "x"], expr) == "\\v,w->z" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "w", ExprVar(2))) + assert showExpr(["z", "y", "x"], expr) == "\\v,w->z" def test_showExpr_eabs_3(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprVar(2))) - assert pgf.showExpr(["z", "y", "x"], expr) == "\\v,{w}->z" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprVar(2))) + assert showExpr(["z", "y", "x"], expr) == "\\v,{w}->z" def test_showExpr_eabs_4(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "z", pgf.ExprVar(0)))) - assert pgf.showExpr(["y", "x"], expr) == "\\v,{w},z->z" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_EXPLICIT, "z", ExprVar(0)))) + assert showExpr(["y", "x"], expr) == "\\v,{w},z->z" def test_showExpr_eabs_5(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprVar(2)))) - assert pgf.showExpr(["y", "x"], expr) == "\\v,{w,z}->v" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprVar(2)))) + assert showExpr(["y", "x"], expr) == "\\v,{w,z}->v" def test_showExpr_eabs_6(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "t", pgf.ExprVar(3))))) - assert pgf.showExpr(["y", "x"], expr) == "\\v,{w,z},t->v" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprAbs(BIND_TYPE_EXPLICIT, "t", ExprVar(3))))) + assert showExpr(["y", "x"], expr) == "\\v,{w,z},t->v" def test_showExpr_eabs_7(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "u", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "t", pgf.ExprVar(3)))))) - assert pgf.showExpr(["y", "x"], expr) == "\\u,v,{w,z},t->v" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "u", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprAbs(BIND_TYPE_EXPLICIT, "t", ExprVar(3)))))) + assert showExpr(["y", "x"], expr) == "\\u,v,{w,z},t->v" def test_showExpr_eabs_8(): - expr = pgf.ExprApp(pgf.ExprFun("f"), pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "x", pgf.ExprVar(0))) - assert pgf.showExpr([], expr) == "f (\\x->x)" + expr = ExprApp(ExprFun("f"), ExprAbs(BIND_TYPE_EXPLICIT, "x", ExprVar(0))) + assert showExpr([], expr) == "f (\\x->x)" def test_showExpr_eabs_freshvars_1(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(0))) - assert pgf.showExpr([], expr) == "\\v,v1->v1" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(0))) + assert showExpr([], expr) == "\\v,v1->v1" def test_showExpr_eabs_freshvars_2(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(1))) - assert pgf.showExpr([], expr) == "\\v,v1->v" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(1))) + assert showExpr([], expr) == "\\v,v1->v" def test_showExpr_eabs_freshvars_3(): - expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(1)))) - assert pgf.showExpr([], expr) == "\\v,v1,v2->v1" + expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(1)))) + assert showExpr([], expr) == "\\v,v1,v2->v1" # expressions: meta variables def test_readExpr_emeta_1(): - assert pgf.readExpr("?") == pgf.ExprMeta() - assert pgf.readExpr("?") == pgf.ExprMeta(0) + assert readExpr("?") == ExprMeta() + assert readExpr("?") == ExprMeta(0) def test_readExpr_emeta_2(): - assert pgf.readExpr("?42") == pgf.ExprMeta(42) + assert readExpr("?42") == ExprMeta(42) def test_readExpr_emeta_str_1(): - assert str(pgf.readExpr("?")) == "?" + assert str(readExpr("?")) == "?" def test_readExpr_emeta_str_2(): - assert str(pgf.readExpr("?42")) == "?42" + assert str(readExpr("?42")) == "?42" # expressions: typed expressions def test_readExpr_emeta_equality(): - assert pgf.readExpr("") == pgf.ExprTyped(pgf.ExprFun("z"), pgf.readType("N")) + assert readExpr("") == ExprTyped(ExprFun("z"), readType("N")) def test_readExpr_emeta_str(): - assert str(pgf.readExpr("")) == "" + assert str(readExpr("")) == "" diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py index 26ea56a0d..97e1b789c 100644 --- a/src/runtime/python/tests/test_transactions.py +++ b/src/runtime/python/tests/test_transactions.py @@ -2,40 +2,49 @@ import pytest from pgf import * ty = readType("(N -> N) -> P (s z)") -pi = 3.142 +prob = 3.142 -# @pytest.fixture(scope="module") -# def gr1(): -# return pgf.readPGF("../haskell/tests/basic.pgf") -# -# @pytest.fixture(scope="module") -# def gr2(gr1): -# transaction = [ -# createFunction("foo", ty, 0, pi), -# createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], pi) -# ] -# return gr1.modifyPGF(transaction) -# -# @pytest.fixture(scope="module") -# def gr3(gr1): -# transaction = [ -# createFunction("bar", ty, 0, pi), -# createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], pi) -# ] -# return gr1.branchPGF("bar_branch", transaction) -# -# def original_functions(gr1): -# assert gr1.functions == ["c", "ind", "s", "z"] -# -# def extended_functions(gr2): -# assert gr2.functions == ["c", "foo", "ind", "s", "z"] -# -# def branched_functions(gr3): -# assert gr3.functions == ["bar", "c", "ind", "s", "z"] +@pytest.fixture(scope="module") +def gr1(): + return readPGF("../haskell/tests/basic.pgf") -def test_non_transactional(): - gr1 = readPGF("../haskell/tests/basic.pgf") +@pytest.fixture(scope="module") +def gr2(gr1): + t = gr1.newTransaction() + t.createFunction("foo", ty, 0, prob), + # t.createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) + assert t.commit() + return gr1 + +# gr1 + +def test_original_functions(gr1): assert gr1.functions == ["c", "ind", "s", "z"] - gr1.createFunction("foo", ty, 0, pi) - assert gr1.functions == ["c", "foo", "ind", "s", "z"] +def test_original_categories(gr1): + assert gr1.categories == ["Float","Int","N","P","S","String"] + +def test_original_function_type(gr1): + with pytest.raises(KeyError): + gr1.functionType("foo") + +# def test_original_function_prob(gr1): +# with pytest.raises(KeyError): +# gr1.functionProbability("foo") + +# gr2 + +def test_extended_functions(gr2): + assert gr2.functions == ["c", "foo", "ind", "s", "z"] + +# def test_extended_categories(gr2): +# assert gr2.categories == ["Float","Int","N","P","Q","S","String"] +# +# def test_extended_category_context(gr2): +# assert gr2.categoryContext("Q") == [(BIND_TYPE_EXPLICIT, "x", ty)] + +def test_extended_function_type(gr2): + assert gr2.functionType("foo") == ty + +# def test_extended_function_prob(gr2): +# assert gr2.functionProbability("foo") == prob diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index 8ff2e2e58..6fee73152 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -5,9 +5,43 @@ #include #include "./expr.h" #include "./ffi.h" +#include "./transactions.h" + +TransactionObject * +PGF_newTransaction(PGFObject *self, PyObject *args) +{ + PgfText *name = NULL; + // PgfText *name = PyUnicode_AsPgfText(PyUnicode_FromString("transient")); + + PgfExn err; + PgfRevision rev = pgf_clone_revision(self->db, self->revision, name, &err); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + TransactionObject *trans = (TransactionObject *)pgf_TransactionType.tp_alloc(&pgf_TransactionType, 0); + trans->pgf = self; + trans->revision = rev; + + return trans; +} PyObject * -PGF_createFunction(PGFObject *self, PyObject *args) +Transaction_commit(TransactionObject *self, PyObject *args) +{ + PgfExn err; + pgf_commit_revision(self->pgf->db, self->revision, &err); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + self->pgf->revision = self->revision; + + Py_RETURN_TRUE; +} + +PyObject * +Transaction_createFunction(TransactionObject *self, PyObject *args) { const char *s; Py_ssize_t size; @@ -22,7 +56,7 @@ PGF_createFunction(PGFObject *self, PyObject *args) fname->size = size; PgfExn err; - pgf_create_function(self->db, self->revision, fname, (PgfType) type, arity, prob, &marshaller, &err); + pgf_create_function(self->pgf->db, self->revision, fname, (PgfType) type, arity, prob, &marshaller, &err); PyMem_Free(fname); if (handleError(err) != PGF_EXN_NONE) { return NULL; @@ -32,7 +66,7 @@ PGF_createFunction(PGFObject *self, PyObject *args) } PyObject * -PGF_dropFunction(PGFObject *self, PyObject *args) +Transaction_dropFunction(TransactionObject *self, PyObject *args) { const char *s; Py_ssize_t size; @@ -44,7 +78,7 @@ PGF_dropFunction(PGFObject *self, PyObject *args) fname->size = size; PgfExn err; - pgf_drop_category(self->db, self->revision, fname, &err); + pgf_drop_category(self->pgf->db, self->revision, fname, &err); PyMem_Free(fname); if (handleError(err) != PGF_EXN_NONE) { return NULL; @@ -54,7 +88,7 @@ PGF_dropFunction(PGFObject *self, PyObject *args) } PyObject * -PGF_createCategory(PGFObject *self, PyObject *args) +Transaction_createCategory(TransactionObject *self, PyObject *args) { const char *s; Py_ssize_t size; @@ -70,7 +104,7 @@ PGF_createCategory(PGFObject *self, PyObject *args) PgfTypeHypo *context = NULL; PgfExn err; - pgf_create_category(self->db, self->revision, catname, n_hypos, context, prob, &marshaller, &err); + pgf_create_category(self->pgf->db, self->revision, catname, n_hypos, context, prob, &marshaller, &err); PyMem_Free(catname); if (handleError(err) != PGF_EXN_NONE) { return NULL; @@ -80,7 +114,7 @@ PGF_createCategory(PGFObject *self, PyObject *args) } PyObject * -PGF_dropCategory(PGFObject *self, PyObject *args) +Transaction_dropCategory(TransactionObject *self, PyObject *args) { const char *s; Py_ssize_t size; @@ -92,7 +126,7 @@ PGF_dropCategory(PGFObject *self, PyObject *args) catname->size = size; PgfExn err; - pgf_drop_function(self->db, self->revision, catname, &err); + pgf_drop_function(self->pgf->db, self->revision, catname, &err); PyMem_Free(catname); if (handleError(err) != PGF_EXN_NONE) { return NULL; @@ -100,3 +134,81 @@ PGF_dropCategory(PGFObject *self, PyObject *args) Py_RETURN_NONE; } + +// ---------------------------------------------------------------------------- + +// static void +// Transaction_dealloc(PGFObject* self) +// { +// Py_TYPE(self)->tp_free((PyObject*)self); +// } + +static PyGetSetDef Transaction_getseters[] = { + {NULL} /* Sentinel */ +}; + +// static PyMemberDef Transaction_members[] = { +// {NULL} /* Sentinel */ +// }; + +static PyMethodDef Transaction_methods[] = { + {"commit", (PyCFunction)Transaction_commit, METH_VARARGS, + "Commit transaction" + }, + + {"createFunction", (PyCFunction)Transaction_createFunction, METH_VARARGS, + "Create function" + }, + {"dropFunction", (PyCFunction)Transaction_dropFunction, METH_VARARGS, + "Drop function" + }, + {"createCategory", (PyCFunction)Transaction_createCategory, METH_VARARGS, + "Create category" + }, + {"dropCategory", (PyCFunction)Transaction_dropCategory, METH_VARARGS, + "Drop category" + }, + {NULL} /* Sentinel */ +}; + +PyTypeObject pgf_TransactionType = { + PyVarObject_HEAD_INIT(NULL, 0) + //0, /*ob_size*/ + "pgf.Transaction", /*tp_name*/ + sizeof(PGFObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, //(destructor)Transaction_dealloc, /*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, // (reprfunc) Transaction_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "PGF transaction", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + 0, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + Transaction_methods, /*tp_methods */ + 0, //Transaction_members, /*tp_members */ + Transaction_getseters, /*tp_getset */ + 0, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + 0, /*tp_init */ + 0, /*tp_alloc */ + 0, /*tp_new */ +}; diff --git a/src/runtime/python/transactions.h b/src/runtime/python/transactions.h index 39b6a1e0e..18083915f 100644 --- a/src/runtime/python/transactions.h +++ b/src/runtime/python/transactions.h @@ -6,33 +6,30 @@ #include -// typedef struct { -// PyObject_HEAD -// PyObject *thing; -// } TransactionObject; +typedef struct { + PyObject_HEAD + PGFObject *pgf; // original reference, gets updated on commit + PgfRevision revision; // transient branch +} TransactionObject; -// modifyPGF -// -// branchPGF -// -// checkoutPGF +extern PyTypeObject pgf_TransactionType; + +TransactionObject * +PGF_newTransaction(PGFObject *self, PyObject *args); PyObject * -PGF_createFunction(PGFObject *self, PyObject *args); +Transaction_commit(TransactionObject *self, PyObject *args); PyObject * -PGF_dropFunction(PGFObject *self, PyObject *args); +Transaction_createFunction(TransactionObject *self, PyObject *args); PyObject * -PGF_createCategory(PGFObject *self, PyObject *args); +Transaction_dropFunction(TransactionObject *self, PyObject *args); PyObject * -PGF_dropCategory(PGFObject *self, PyObject *args); - -// setGlobalFlag -// -// setAbstractFlag - +Transaction_createCategory(TransactionObject *self, PyObject *args); +PyObject * +Transaction_dropCategory(TransactionObject *self, PyObject *args); #endif // PYPGF_TRANSACTIONS_H_ From 71dac482c8d568634b5787826e7d0d266f4f26f9 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 21 Sep 2021 17:23:38 +0200 Subject: [PATCH 3/6] Started adding support for 'with' construct, failing tests commented out --- src/runtime/python/tests/test_transactions.py | 15 +++++ src/runtime/python/transactions.c | 56 ++++++++++++++++--- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py index 97e1b789c..d9c34f0f2 100644 --- a/src/runtime/python/tests/test_transactions.py +++ b/src/runtime/python/tests/test_transactions.py @@ -16,6 +16,13 @@ def gr2(gr1): assert t.commit() return gr1 +@pytest.fixture(scope="module") +def gr3(gr1): + with gr1.newTransaction() as t: + t.createFunction("bar", ty, 0, prob), + # t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) + return gr1 + # gr1 def test_original_functions(gr1): @@ -48,3 +55,11 @@ def test_extended_function_type(gr2): # def test_extended_function_prob(gr2): # assert gr2.functionProbability("foo") == prob + +# gr3 + +# def test_branched_functions(gr3): +# assert gr3.functions == ["bar", "c", "ind", "s", "z"] +# +# def test_branched_function_type(gr3): +# assert gr3.functionType("bar") == ty diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index 6fee73152..f4baaed99 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include -// #include +#include #include #include "./expr.h" @@ -137,6 +137,40 @@ Transaction_dropCategory(TransactionObject *self, PyObject *args) // ---------------------------------------------------------------------------- +static PyObject * +Transaction_enter(TransactionObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_RETURN_TRUE; +} + +static PyObject * +Transaction_exit(TransactionObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + // PyObject *exc_type = Py_None; + // PyObject *exc_value = Py_None; + // PyObject *exc_tb = Py_None; + + // if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) { + // Py_RETURN_FALSE; + // } + if (nargs < 1) { + goto skip_optional; + } + // exc_type = args[0]; + // if (nargs < 2) { + // goto skip_optional; + // } + // exc_value = args[1]; + // if (nargs < 3) { + // goto skip_optional; + // } + // exc_tb = args[2]; +skip_optional: + // TODO check exception + + return Transaction_commit(self, NULL); +} + // static void // Transaction_dealloc(PGFObject* self) // { @@ -147,15 +181,23 @@ static PyGetSetDef Transaction_getseters[] = { {NULL} /* Sentinel */ }; -// static PyMemberDef Transaction_members[] = { -// {NULL} /* Sentinel */ -// }; +static PyMemberDef Transaction_members[] = { + {NULL} /* Sentinel */ +}; static PyMethodDef Transaction_methods[] = { {"commit", (PyCFunction)Transaction_commit, METH_VARARGS, "Commit transaction" }, + {"__enter__", (PyCFunction)Transaction_enter, METH_NOARGS, + "" + }, + + {"__exit__", (PyCFunction)(void(*)(void))Transaction_exit, METH_FASTCALL, + "" + }, + {"createFunction", (PyCFunction)Transaction_createFunction, METH_VARARGS, "Create function" }, @@ -175,7 +217,7 @@ PyTypeObject pgf_TransactionType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ "pgf.Transaction", /*tp_name*/ - sizeof(PGFObject), /*tp_basicsize*/ + sizeof(TransactionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, //(destructor)Transaction_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ @@ -193,7 +235,7 @@ PyTypeObject pgf_TransactionType = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "PGF transaction", /*tp_doc*/ + "Transaction object", /*tp_doc*/ 0, /*tp_traverse */ 0, /*tp_clear */ 0, /*tp_richcompare */ @@ -201,7 +243,7 @@ PyTypeObject pgf_TransactionType = { 0, /*tp_iter */ 0, /*tp_iternext */ Transaction_methods, /*tp_methods */ - 0, //Transaction_members, /*tp_members */ + Transaction_members, /*tp_members */ Transaction_getseters, /*tp_getset */ 0, /*tp_base */ 0, /*tp_dict */ From b4b8572af3db10d3b7d73cf6685dabd54659013f Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 21 Sep 2021 22:28:44 +0200 Subject: [PATCH 4/6] Header and source file cleanup --- src/runtime/python/expr.c | 12 +- src/runtime/python/expr.h | 20 +- src/runtime/python/ffi.c | 65 +- src/runtime/python/ffi.h | 6 +- src/runtime/python/pypgf.c | 2137 +---------------- src/runtime/python/tests/test_transactions.py | 2 +- src/runtime/python/transactions.c | 26 +- src/runtime/python/transactions.h | 17 +- 8 files changed, 81 insertions(+), 2204 deletions(-) diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index b36a8b80d..f066c0ec8 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -7,6 +7,7 @@ #include "./ffi.h" // ---------------------------------------------------------------------------- +// types static TypeObject * Type_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) @@ -135,7 +136,6 @@ static PyGetSetDef Type_getseters[] = { {NULL} /* Sentinel */ }; -/* static */ PyTypeObject pgf_TypeType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -179,6 +179,7 @@ PyTypeObject pgf_TypeType = { }; // ---------------------------------------------------------------------------- +// expressions static PyObject * Expr_str(ExprObject *self) @@ -234,7 +235,6 @@ static PyGetSetDef Expr_getseters[] = { {NULL} /* Sentinel */ }; -/* static */ PyTypeObject pgf_ExprType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -327,7 +327,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprAbsType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -416,7 +415,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprAppType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -522,7 +520,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprLitType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -615,7 +612,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprMetaType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -700,7 +696,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprFunType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -793,7 +788,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprVarType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -882,7 +876,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprTypedType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ @@ -967,7 +960,6 @@ done: } } -/* static */ PyTypeObject pgf_ExprImplArgType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ diff --git a/src/runtime/python/expr.h b/src/runtime/python/expr.h index dbbdf1bde..5b623519f 100644 --- a/src/runtime/python/expr.h +++ b/src/runtime/python/expr.h @@ -13,7 +13,7 @@ typedef struct { PyObject *exprs; // PyListObject of ExprObject } TypeObject; -extern PyTypeObject pgf_TypeType; +PyTypeObject pgf_TypeType; typedef struct { PyObject_HEAD @@ -63,14 +63,14 @@ typedef struct { ExprObject *expr; } ExprImplArgObject; -extern PyTypeObject pgf_ExprType; -extern PyTypeObject pgf_ExprAbsType; -extern PyTypeObject pgf_ExprAppType; -extern PyTypeObject pgf_ExprLitType; -extern PyTypeObject pgf_ExprMetaType; -extern PyTypeObject pgf_ExprFunType; -extern PyTypeObject pgf_ExprVarType; -extern PyTypeObject pgf_ExprTypedType; -extern PyTypeObject pgf_ExprImplArgType; +PyTypeObject pgf_ExprType; +PyTypeObject pgf_ExprAbsType; +PyTypeObject pgf_ExprAppType; +PyTypeObject pgf_ExprLitType; +PyTypeObject pgf_ExprMetaType; +PyTypeObject pgf_ExprFunType; +PyTypeObject pgf_ExprVarType; +PyTypeObject pgf_ExprTypedType; +PyTypeObject pgf_ExprImplArgType; #endif // PYPGF_EXPR_H_ diff --git a/src/runtime/python/ffi.c b/src/runtime/python/ffi.c index 74e95fdf6..2315b5537 100644 --- a/src/runtime/python/ffi.c +++ b/src/runtime/python/ffi.c @@ -7,10 +7,11 @@ #include "./expr.h" #include "./ffi.h" -/* static */ +// ---------------------------------------------------------------------------- +// errors + PyObject *PGFError; -/* static */ PgfExnType handleError(PgfExn err) { if (err.type == PGF_EXN_SYSTEM_ERROR) { @@ -26,6 +27,7 @@ PgfExnType handleError(PgfExn err) } // ---------------------------------------------------------------------------- +// string conversions PgfText * PyUnicode_AsPgfText(PyObject *pystr) @@ -53,15 +55,10 @@ PyUnicode_FromPgfText(PgfText *text) } // ---------------------------------------------------------------------------- +// unmarshaller -/* The PgfUnmarshaller structure tells the runtime how to create - * abstract syntax expressions and types in the heap of the host language. - * In Python the expressions are normal objects. - * From the point of view of the runtime, each node is a value of type object. - * For Python that would be a PyObject pointer. - */ - -PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body) +static PgfExpr +eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body) { ExprAbsObject *pyexpr = (ExprAbsObject *)pgf_ExprAbsType.tp_alloc(&pgf_ExprAbsType, 0); pyexpr->bindType = PyLong_FromLong(btype); @@ -71,7 +68,8 @@ PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr bo return (PgfExpr) pyexpr; } -PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg) +static PgfExpr +eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg) { ExprAppObject *pyexpr = (ExprAppObject *)pgf_ExprAppType.tp_alloc(&pgf_ExprAppType, 0); pyexpr->e1 = (ExprObject *)fun; @@ -81,7 +79,8 @@ PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg) return (PgfExpr) pyexpr; } -PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit) +static PgfExpr +elit(PgfUnmarshaller *this, PgfLiteral lit) { ExprLitObject *pyexpr = (ExprLitObject *)pgf_ExprLitType.tp_alloc(&pgf_ExprLitType, 0); PyObject *pyobj = (PyObject *)lit; @@ -90,14 +89,16 @@ PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit) return (PgfExpr) pyexpr; } -PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta) +static PgfExpr +emeta(PgfUnmarshaller *this, PgfMetaId meta) { ExprMetaObject *pyexpr = (ExprMetaObject *)pgf_ExprMetaType.tp_alloc(&pgf_ExprMetaType, 0); pyexpr->id = PyLong_FromLong(meta); return (PgfExpr) pyexpr; } -PgfExpr efun(PgfUnmarshaller *this, PgfText *name) +static PgfExpr +efun(PgfUnmarshaller *this, PgfText *name) { ExprFunObject *pyexpr = (ExprFunObject *)pgf_ExprFunType.tp_alloc(&pgf_ExprFunType, 0); PyObject *pyobj = PyUnicode_FromPgfText(name); @@ -106,14 +107,16 @@ PgfExpr efun(PgfUnmarshaller *this, PgfText *name) return (PgfExpr) pyexpr; } -PgfExpr evar(PgfUnmarshaller *this, int index) +static PgfExpr +evar(PgfUnmarshaller *this, int index) { ExprVarObject *pyexpr = (ExprVarObject *)pgf_ExprVarType.tp_alloc(&pgf_ExprVarType, 0); pyexpr->index = PyLong_FromLong(index); return (PgfExpr) pyexpr; } -PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ) +static PgfExpr +etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ) { ExprTypedObject *pyexpr = (ExprTypedObject *)pgf_ExprTypedType.tp_alloc(&pgf_ExprTypedType, 0); pyexpr->expr = (ExprObject *)expr; @@ -123,7 +126,8 @@ PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ) return (PgfExpr) pyexpr; } -PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr) +static PgfExpr +eimplarg(PgfUnmarshaller *this, PgfExpr expr) { ExprImplArgObject *pyexpr = (ExprImplArgObject *)pgf_ExprImplArgType.tp_alloc(&pgf_ExprImplArgType, 0); pyexpr->expr = (ExprObject *)expr; @@ -131,7 +135,8 @@ PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr) return (PgfExpr) pyexpr; } -PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v) +static PgfLiteral +lint(PgfUnmarshaller *this, size_t size, uintmax_t *v) { intmax_t *v0 = (intmax_t *)v; PyObject *i = PyLong_FromLong(*v0); @@ -155,19 +160,22 @@ PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v) } } -PgfLiteral lflt(PgfUnmarshaller *this, double v) +static PgfLiteral +lflt(PgfUnmarshaller *this, double v) { PyObject *d = PyFloat_FromDouble(v); return (PgfLiteral) d; } -PgfLiteral lstr(PgfUnmarshaller *this, PgfText *v) +static PgfLiteral +lstr(PgfUnmarshaller *this, PgfText *v) { PyObject *s = PyUnicode_FromStringAndSize(v->text, v->size); return (PgfLiteral) s; } -PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs) +static PgfType +dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs) { TypeObject *pytype = (TypeObject *)pgf_TypeType.tp_alloc(&pgf_TypeType, 0); @@ -191,7 +199,8 @@ PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *ca return (PgfType) pytype; } -void free_ref(PgfUnmarshaller *this, object x) +static void +free_ref(PgfUnmarshaller *this, object x) { // Py_XDECREF(x); } @@ -213,12 +222,13 @@ static PgfUnmarshallerVtbl unmarshallerVtbl = free_ref }; -/* static */ PgfUnmarshaller unmarshaller = { &unmarshallerVtbl }; // ---------------------------------------------------------------------------- +// marshaller -object match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit) +static object +match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit) { PyObject *pyobj = (PyObject *)lit; @@ -265,7 +275,8 @@ object match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit) } } -object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr) +static object +match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr) { PyObject *pyobj = (PyObject *)expr; @@ -306,7 +317,8 @@ object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr) } } -object match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty) +static object +match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty) { TypeObject *type = (TypeObject *)ty; @@ -353,5 +365,4 @@ static PgfMarshallerVtbl marshallerVtbl = match_type }; -/* static */ PgfMarshaller marshaller = { &marshallerVtbl }; diff --git a/src/runtime/python/ffi.h b/src/runtime/python/ffi.h index 751cd74f8..7197c509e 100644 --- a/src/runtime/python/ffi.h +++ b/src/runtime/python/ffi.h @@ -12,13 +12,13 @@ typedef struct { PgfRevision revision; } PGFObject; -extern PyObject *PGFError; +PyObject *PGFError; PgfExnType handleError(PgfExn err); PgfText *PyUnicode_AsPgfText(PyObject *pystr); PyObject *PyUnicode_FromPgfText(PgfText *text); -extern PgfUnmarshaller unmarshaller; -extern PgfMarshaller marshaller; +PgfUnmarshaller unmarshaller; +PgfMarshaller marshaller; #endif // PYPGF_FFI_H_ diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index dc8baa233..cc5337886 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -7,1707 +7,8 @@ #include "./ffi.h" #include "./transactions.h" -// static PyObject* ParseError; - -// static PyObject* TypeError; - -// typedef struct IterObject { -// PyObject_HEAD -// PyObject* source; -// PyObject* container; -// GuPool* pool; -// int max_count; -// int counter; -// GuEnum* res; -// PyObject* (*fetch)(struct IterObject* self); -// } IterObject; -// -// static PyObject* -// Iter_fetch_expr(IterObject* self) -// { -// PgfExprProb* ep = gu_next(self->res, PgfExprProb*, self->pool); -// if (ep == NULL) -// return NULL; -// -// ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0); -// if (pyexpr == NULL) -// return NULL; -// pyexpr->pool = NULL; -// pyexpr->expr = ep->expr; -// pyexpr->master = self->container; -// Py_XINCREF(self->container); -// -// PyObject* res = Py_BuildValue("(f,O)", ep->prob, pyexpr); -// Py_DECREF(pyexpr); -// -// return res; -// } -// -// static PyObject* -// Iter_fetch_token(IterObject* self) -// { -// PgfTokenProb* tp = gu_next(self->res, PgfTokenProb*, self->pool); -// if (tp == NULL) -// return NULL; -// -// PyObject* py_tok = PyString_FromString(tp->tok); -// PyObject* py_cat = PyString_FromString(tp->cat); -// PyObject* py_fun = PyString_FromString(tp->fun); -// PyObject* res = Py_BuildValue("(f,O,O,O)", tp->prob, py_tok, py_cat, py_fun); -// Py_DECREF(py_fun); -// Py_DECREF(py_cat); -// Py_DECREF(py_tok); -// -// return res; -// } -// -// -// static IterObject* -// Iter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -// { -// IterObject* self = (IterObject *)type->tp_alloc(type, 0); -// if (self != NULL) { -// self->source = NULL; -// self->container = NULL; -// self->pool = NULL; -// self->max_count = -1; -// self->counter = 0; -// self->res = NULL; -// } -// -// return self; -// } -// -// static void -// Iter_dealloc(IterObject* self) -// { -// if (self->pool != NULL) -// gu_pool_free(self->pool); -// -// Py_XDECREF(self->source); -// -// Py_XDECREF(self->container); -// -// Py_TYPE(self)->tp_free((PyObject*)self); -// } -// -// static int -// Iter_init(IterObject *self, PyObject *args, PyObject *kwds) -// { -// return -1; -// } -// -// static PyObject* -// Iter_iter(IterObject *self) -// { -// Py_INCREF(self); -// return (PyObject*) self; -// } -// -// static PyObject* -// Iter_iternext(IterObject *self) -// { -// if (self->max_count >= 0 && self->counter >= self->max_count) { -// return NULL; -// } -// self->counter++; -// -// return self->fetch(self); -// } -// -// static PyMethodDef Iter_methods[] = { -// {NULL} /* Sentinel */ -// }; -// -// static PyTypeObject pgf_IterType = { -// PyVarObject_HEAD_INIT(NULL, 0) -// //0, /*ob_size*/ -// "pgf.Iter", /*tp_name*/ -// sizeof(IterObject), /*tp_basicsize*/ -// 0, /*tp_itemsize*/ -// (destructor)Iter_dealloc, /*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 | Py_TPFLAGS_BASETYPE, /*tp_flags*/ -// "an iterator over a sequence of expressions",/*tp_doc*/ -// 0, /*tp_traverse */ -// 0, /*tp_clear */ -// 0, /*tp_richcompare */ -// 0, /*tp_weaklistoffset */ -// (getiterfunc) Iter_iter, /*tp_iter */ -// (iternextfunc) Iter_iternext, /*tp_iternext */ -// Iter_methods, /*tp_methods */ -// 0, /*tp_members */ -// 0, /*tp_getset */ -// 0, /*tp_base */ -// 0, /*tp_dict */ -// 0, /*tp_descr_get */ -// 0, /*tp_descr_set */ -// 0, /*tp_dictoffset */ -// (initproc)Iter_init, /*tp_init */ -// 0, /*tp_alloc */ -// (newfunc) Iter_new, /*tp_new */ -// }; -// -// typedef struct { -// PyObject_HEAD -// PGFObject* grammar; -// PgfConcr* concr; -// } ConcrObject; -// -// static ConcrObject* -// Concr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -// { -// ConcrObject* self = (ConcrObject *)type->tp_alloc(type, 0); -// if (self != NULL) { -// self->grammar = NULL; -// self->concr = NULL; -// } -// -// return self; -// } -// -// static void -// Concr_dealloc(ConcrObject* self) -// { -// Py_XDECREF(self->grammar); -// Py_TYPE(self)->tp_free((PyObject*)self); -// } -// -// static int -// Concr_init(ConcrObject *self, PyObject *args, PyObject *kwds) -// { -// return -1; -// } -// -// static PyObject* -// Concr_printName(ConcrObject* self, PyObject *args) -// { -// GuString id; -// if (!PyArg_ParseTuple(args, "s", &id)) -// return NULL; -// -// GuString name = pgf_print_name(self->concr, id); -// if (name == NULL) -// Py_RETURN_NONE; -// -// return PyString_FromString(name); -// } -// -// #if ( (PY_VERSION_HEX < 0x02070000) \ -// || ((PY_VERSION_HEX >= 0x03000000) \ -// && (PY_VERSION_HEX < 0x03010000)) ) -// -// #define PyPool_New(pool) \ -// PyCObject_FromVoidPtr(pool, gu_pool_free) -// -// #else -// -// #define PGF_CONTAINER_NAME "pgf.Container" -// -// static void pypgf_container_descructor(PyObject *capsule) -// { -// GuPool* pool = PyCapsule_GetPointer(capsule, PGF_CONTAINER_NAME); -// gu_pool_free(pool); -// } -// -// #define PyPool_New(pool) \ -// PyCapsule_New(pool, PGF_CONTAINER_NAME, \ -// pypgf_container_descructor) -// -// #endif -// -// typedef struct { -// PgfLiteralCallback callback; -// PyObject* pycallback; -// GuFinalizer fin; -// } PyPgfLiteralCallback; -// -// #if PY_MAJOR_VERSION >= 3 -// static size_t -// utf8_to_unicode_offset(GuString sentence, size_t offset) -// { -// const uint8_t* start = (uint8_t*) sentence; -// const uint8_t* end = start+offset; -// -// size_t chars = 0; -// while (start < end) { -// gu_utf8_decode(&start); -// chars++; -// } -// -// return chars; -// } -// -// static size_t -// unicode_to_utf8_offset(GuString sentence, size_t chars) -// { -// const uint8_t* start = (uint8_t*) sentence; -// const uint8_t* end = start; -// -// while (chars > 0) { -// GuUCS ucs = gu_utf8_decode(&end); -// if (ucs == 0) -// break; -// chars--; -// } -// -// return (end-start); -// } -// #endif -// -// static PgfExprProb* -// pypgf_literal_callback_match(PgfLiteralCallback* self, PgfConcr* concr, -// GuString ann, -// GuString sentence, size_t* poffset, -// GuPool *out_pool) -// { -// PyPgfLiteralCallback* callback = -// gu_container(self, PyPgfLiteralCallback, callback); -// -// PyObject* result = -// PyObject_CallFunction(callback->pycallback, "si", -// ann, -// #if PY_MAJOR_VERSION >= 3 -// utf8_to_unicode_offset(sentence, *poffset) -// #else -// *poffset -// #endif -// ); -// if (result == NULL) { -// PyErr_Print(); -// return NULL; -// } -// -// if (result == Py_None) { -// Py_DECREF(result); -// return NULL; -// } -// -// PgfExprProb* ep = gu_new(PgfExprProb, out_pool); -// -// ExprObject* pyexpr; -// #if PY_MAJOR_VERSION >= 3 -// int chars; -// if (!PyArg_ParseTuple(result, "Ofi", &pyexpr, &ep->prob, &chars)) -// return NULL; -// *poffset = unicode_to_utf8_offset(sentence, chars); -// #else -// if (!PyArg_ParseTuple(result, "Ofi", &pyexpr, &ep->prob, poffset)) -// return NULL; -// #endif -// -// ep->expr = pgf_clone_expr(pyexpr->expr, out_pool); -// -// Py_DECREF(result); -// -// return ep; -// } -// -// static GuEnum* -// pypgf_literal_callback_predict(PgfLiteralCallback* self, PgfConcr* concr, -// GuString ann, -// GuString prefix, -// GuPool *out_pool) -// { -// return NULL; -// } -// -// static void -// pypgf_literal_callback_fin(GuFinalizer* self) -// { -// PyPgfLiteralCallback* callback = -// gu_container(self, PyPgfLiteralCallback, fin); -// -// Py_XDECREF(callback->pycallback); -// } -// -// static PgfCallbacksMap* -// pypgf_new_callbacks_map(PgfConcr* concr, PyObject *py_callbacks, -// GuPool* pool) -// { -// PgfCallbacksMap* callbacks = -// pgf_new_callbacks_map(concr, pool); -// -// if (py_callbacks == NULL) -// return callbacks; -// -// size_t n_callbacks = PyList_Size(py_callbacks); -// for (size_t i = 0; i < n_callbacks; i++) { -// PyObject* item = -// PyList_GetItem(py_callbacks, i); -// -// PyObject* pycallback = NULL; -// const char* cat = NULL; -// if (!PyArg_ParseTuple(item, "sO", &cat, &pycallback)) -// return NULL; -// -// PyPgfLiteralCallback* callback = gu_new(PyPgfLiteralCallback, pool); -// callback->callback.match = pypgf_literal_callback_match; -// callback->callback.predict = pypgf_literal_callback_predict; -// callback->pycallback = pycallback; -// callback->fin.fn = pypgf_literal_callback_fin; -// -// Py_XINCREF(callback->pycallback); -// -// gu_pool_finally(pool, &callback->fin); -// -// pgf_callbacks_map_add_literal(concr, callbacks, -// cat, &callback->callback); -// } -// -// return callbacks; -// } -// -// static PgfType* -// pgf_type_from_object(PyObject* obj, GuPool* pool) { -// if (PyString_Check(obj)) { -// PgfType* type = gu_new_flex(pool, PgfType, exprs, 0); -// type->hypos = gu_empty_seq(); -// type->cid = ""; -// type->n_exprs = 0; -// return type; -// } else if (obj->ob_type == &pgf_TypeType) { -// return ((TypeObject*) obj)->type; -// } else { -// PyErr_SetString(PyExc_TypeError, "the start category should be a string or a type"); -// return NULL; -// } -// } -// -// static IterObject* -// Concr_parse(ConcrObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"sentence", "cat", "n", "heuristics", "callbacks", NULL}; -// -// const char *sentence = NULL; -// PyObject* start = NULL; -// int max_count = -1; -// double heuristics = -1; -// PyObject* py_callbacks = NULL; -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|OidO!", kwlist, -// &sentence, &start, &max_count, -// &heuristics, -// &PyList_Type, &py_callbacks)) -// return NULL; -// -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// return NULL; -// } -// -// pyres->source = (PyObject*) self->grammar; -// Py_XINCREF(pyres->source); -// -// GuPool* out_pool = gu_new_pool(); -// -// PyObject* py_pool = PyPool_New(out_pool); -// pyres->container = PyTuple_Pack(2, pyres->source, py_pool); -// Py_DECREF(py_pool); -// -// pyres->pool = gu_new_pool(); -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_expr; -// -// GuExn* parse_err = gu_exn(pyres->pool); -// -// PgfCallbacksMap* callbacks = -// pypgf_new_callbacks_map(self->concr, py_callbacks, pyres->pool); -// if (callbacks == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// sentence = gu_string_copy(sentence, pyres->pool); -// -// PgfType* type; -// if (start == NULL) { -// type = pgf_start_cat(self->grammar->pgf, pyres->pool); -// } else { -// type = pgf_type_from_object(start, pyres->pool); -// } -// if (type == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// pyres->res = -// pgf_parse_with_heuristics(self->concr, type, sentence, -// heuristics, callbacks, parse_err, -// pyres->pool, out_pool); -// -// if (!gu_ok(parse_err)) { -// if (gu_exn_caught(parse_err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(parse_err); -// PyErr_SetString(PGFError, msg); -// } else if (gu_exn_caught(parse_err, PgfParseError)) { -// PgfParseError* err = (PgfParseError*) gu_exn_caught_data(parse_err); -// PyObject* py_offset = PyInt_FromLong(err->offset); -// if (err->incomplete) { -// PyObject_SetAttrString(ParseError, "incomplete", Py_True); -// PyObject_SetAttrString(ParseError, "offset", py_offset); -// PyErr_Format(ParseError, "The sentence is incomplete"); -// } else { -// PyObject* py_tok = PyString_FromStringAndSize(err->token_ptr, -// err->token_len); -// PyObject_SetAttrString(ParseError, "incomplete", Py_False); -// PyObject_SetAttrString(ParseError, "offset", py_offset); -// PyObject_SetAttrString(ParseError, "token", py_tok); -// #if PY_MAJOR_VERSION >= 3 -// PyErr_Format(ParseError, "Unexpected token: \"%U\"", py_tok); -// #else -// PyErr_Format(ParseError, "Unexpected token: \"%s\"", PyString_AsString(py_tok)); -// #endif -// Py_DECREF(py_tok); -// } -// Py_DECREF(py_offset); -// } -// -// Py_DECREF(pyres); -// pyres = NULL; -// } -// -// return pyres; -// } -// -// static IterObject* -// Concr_complete(ConcrObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"sentence", "cat", "prefix", "n", NULL}; -// -// const char *sentence = NULL; -// PyObject* start = NULL; -// GuString prefix = ""; -// int max_count = -1; -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|Osi", kwlist, -// &sentence, &start, -// &prefix, &max_count)) -// return NULL; -// -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// return NULL; -// } -// -// pyres->source = (PyObject*) self->grammar; -// Py_XINCREF(pyres->source); -// -// pyres->container = NULL; -// -// pyres->pool = gu_new_pool(); -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_token; -// -// GuPool *tmp_pool = gu_local_pool(); -// -// GuExn* parse_err = gu_new_exn(tmp_pool); -// -// PgfType* type; -// if (start == NULL) { -// type = pgf_start_cat(self->grammar->pgf, pyres->pool); -// } else { -// type = pgf_type_from_object(start, pyres->pool); -// } -// if (type == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// pyres->res = -// pgf_complete(self->concr, type, sentence, prefix, parse_err, pyres->pool); -// -// if (!gu_ok(parse_err)) { -// Py_DECREF(pyres); -// pyres = NULL; -// -// if (gu_exn_caught(parse_err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(parse_err); -// PyErr_SetString(PGFError, msg); -// } else if (gu_exn_caught(parse_err, PgfParseError)) { -// GuString tok = (GuString) gu_exn_caught_data(parse_err); -// PyObject* py_tok = PyString_FromString(tok); -// PyObject_SetAttrString(ParseError, "token", py_tok); -// PyErr_Format(ParseError, "Unexpected token: \"%s\"", tok); -// Py_DECREF(py_tok); -// } -// } -// -// gu_pool_free(tmp_pool); -// -// return pyres; -// } -// -// static PyObject* -// Concr_parseval(ConcrObject* self, PyObject *args) { -// ExprObject* pyexpr = NULL; -// PyObject* start = NULL; -// if (!PyArg_ParseTuple(args, "O!s", &pgf_ExprType, &pyexpr, &start)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// -// double precision = 0; -// double recall = 0; -// double exact = 0; -// -// PgfType* type = pgf_type_from_object(start, tmp_pool); -// if (type == NULL) { -// return NULL; -// } -// -// if (!pgf_parseval(self->concr, pyexpr->expr, type, -// &precision, &recall, &exact)) -// return NULL; -// -// gu_pool_free(tmp_pool); -// -// return Py_BuildValue("ddd", precision, recall, exact); -// } -// -// static IterObject* -// Concr_lookupSentence(ConcrObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"sentence", "cat", NULL}; -// -// const char *sentence = NULL; -// PyObject* start = NULL; -// int max_count = -1; -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|O", kwlist, -// &sentence, &start, &max_count)) -// return NULL; -// -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// return NULL; -// } -// -// pyres->source = (PyObject*) self->grammar; -// Py_XINCREF(pyres->source); -// -// GuPool* out_pool = gu_new_pool(); -// -// PyObject* py_pool = PyPool_New(out_pool); -// pyres->container = PyTuple_Pack(2, pyres->source, py_pool); -// Py_DECREF(py_pool); -// -// pyres->pool = gu_new_pool(); -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_expr; -// -// sentence = gu_string_copy(sentence, pyres->pool); -// -// PgfType* type; -// if (start == NULL) { -// type = pgf_start_cat(self->grammar->pgf, pyres->pool); -// } else { -// type = pgf_type_from_object(start, pyres->pool); -// } -// if (type == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// pyres->res = -// pgf_lookup_sentence(self->concr, type, sentence, -// pyres->pool, out_pool); -// -// return pyres; -// } -// -// static PyObject* -// Concr_linearize(ConcrObject* self, PyObject *args) -// { -// ExprObject* pyexpr; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &pyexpr)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool); -// GuOut* out = gu_string_buf_out(sbuf); -// -// pgf_linearize(self->concr, pyexpr->expr, out, err); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfLinNonExist)) { -// gu_pool_free(tmp_pool); -// Py_RETURN_NONE; -// } -// else if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// gu_pool_free(tmp_pool); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// } -// -// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf), -// gu_string_buf_length(sbuf)); -// -// gu_pool_free(tmp_pool); -// return pystr; -// } -// -// static PyObject* -// Iter_fetch_linearization(IterObject* self) -// { -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_new_exn(tmp_pool); -// -// restart:; -// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool); -// GuOut* out = gu_string_buf_out(sbuf); -// -// -// PgfCncTree ctree = gu_next(self->res, PgfCncTree, tmp_pool); -// if (gu_variant_is_null(ctree)) { -// gu_pool_free(tmp_pool); -// return NULL; -// } -// ctree = pgf_lzr_wrap_linref(ctree, tmp_pool); // to reduce tuple of strings to a single string; -// -// // Linearize the concrete tree as a simple sequence of strings. -// ConcrObject* pyconcr = (ConcrObject*)self->container; -// pgf_lzr_linearize_simple(pyconcr->concr, ctree, 0, out, err, tmp_pool); -// -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfLinNonExist)) { -// // encountered nonExist. Unfortunately there -// // might be some output printed already. The -// // right solution should be to use GuStringBuf. -// gu_exn_clear(err); -// goto restart; -// } -// else if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// gu_pool_free(tmp_pool); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// } -// -// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf), -// gu_string_buf_length(sbuf)); -// gu_pool_free(tmp_pool); -// return pystr; -// } -// -// static PyObject* -// Concr_linearizeAll(ConcrObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"expression", "n", NULL}; -// ExprObject* pyexpr = NULL; -// int max_count = -1; -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|i", kwlist, -// &pgf_ExprType, &pyexpr, &max_count)) -// return NULL; -// -// GuPool* pool = gu_new_pool(); -// -// GuExn* err = gu_exn(pool); -// GuEnum* cts = pgf_lzr_concretize(self->concr, pyexpr->expr, err, pool); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// gu_pool_free(pool); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); -// gu_pool_free(pool); -// return NULL; -// } -// } -// -// IterObject* pyres = (IterObject*) pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// gu_pool_free(pool); -// return NULL; -// } -// -// pyres->source = (PyObject*)pyexpr; -// Py_INCREF(pyres->source); -// pyres->container = (PyObject*)self; -// Py_INCREF(pyres->container); -// pyres->pool = pool; -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_linearization; -// pyres->res = cts; -// -// return (PyObject*)pyres; -// } -// -// static PyObject* -// Concr_tabularLinearize(ConcrObject* self, PyObject *args) -// { -// ExprObject* pyexpr; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &pyexpr)) -// return NULL; -// -// PyObject* table = PyDict_New(); -// if (table == NULL) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// -// GuEnum* cts = -// pgf_lzr_concretize(self->concr, -// pyexpr->expr, -// err, -// tmp_pool); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfLinNonExist)) -// Py_RETURN_NONE; -// else if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); -// return NULL; -// } -// } -// -// PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool); -// if (gu_variant_is_null(ctree)) { -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// size_t n_lins; -// GuString* labels; -// pgf_lzr_get_table(self->concr, ctree, &n_lins, &labels); -// -// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool); -// GuOut* out = gu_string_buf_out(sbuf); -// -// for (size_t lin_idx = 0; lin_idx < n_lins; lin_idx++) { -// -// -// pgf_lzr_linearize_simple(self->concr, ctree, lin_idx, out, err, tmp_pool); -// -// PyObject* pystr = NULL; -// if (gu_ok(err)) { -// pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf), -// gu_string_buf_length(sbuf)); -// } else { -// gu_exn_clear(err); -// pystr = Py_None; -// Py_INCREF(pystr); -// } -// -// gu_string_buf_flush(sbuf); -// -// if (PyDict_SetItemString(table, labels[lin_idx], pystr) < 0) -// return NULL; -// -// Py_XDECREF(pystr); -// } -// -// gu_pool_free(tmp_pool); -// -// return table; -// } -// -// -// typedef struct { -// PyObject_HEAD -// PyObject* cat; -// int fid; -// PyObject* ann; -// PyObject* fun; -// PyObject* children; -// } BracketObject; -// -// static void -// Bracket_dealloc(BracketObject* self) -// { -// Py_XDECREF(self->cat); -// Py_XDECREF(self->fun); -// Py_XDECREF(self->children); -// Py_TYPE(self)->tp_free((PyObject*)self); -// } -// -// static PyObject * -// Bracket_repr(BracketObject *self) -// { -// PyObject *repr = -// #if PY_MAJOR_VERSION >= 3 -// PyString_FromFormat("(%U:%d", self->cat, self->fid); -// #else -// PyString_FromFormat("(%s:%d", PyString_AsString(self->cat), self->fid); -// #endif -// if (repr == NULL) { -// return NULL; -// } -// -// PyObject *space = PyString_FromString(" "); -// -// size_t len = PyList_Size(self->children); -// for (size_t i = 0; i < len; i++) { -// PyObject *child = PyList_GetItem(self->children, i); -// -// PyString_Concat(&repr, space); -// if (repr == NULL) { -// Py_DECREF(space); -// return NULL; -// } -// -// PyObject *child_str = Py_TYPE(child)->tp_str(child); -// if (child_str == NULL) { -// Py_DECREF(repr); -// Py_DECREF(space); -// return NULL; -// } -// -// PyString_Concat(&repr, child_str); -// if (repr == NULL) { -// Py_DECREF(space); -// return NULL; -// } -// -// Py_DECREF(child_str); -// } -// -// Py_DECREF(space); -// -// PyObject *str = PyString_FromString(")"); -// PyString_Concat(&repr, str); -// if (repr == NULL) { -// Py_DECREF(str); -// return NULL; -// } -// Py_DECREF(str); -// -// return repr; -// } -// -// static PyMemberDef Bracket_members[] = { -// {"cat", T_OBJECT_EX, offsetof(BracketObject, cat), 0, -// "the syntactic category for this bracket"}, -// {"fun", T_OBJECT_EX, offsetof(BracketObject, fun), 0, -// "the abstract function for this bracket"}, -// {"fid", T_INT, offsetof(BracketObject, fid), 0, -// "an id which identifies this bracket in the bracketed string. If there are discontinuous phrases this id will be shared for all brackets belonging to the same phrase."}, -// {"ann", T_OBJECT_EX, offsetof(BracketObject, ann), 0, -// "the analysis of the constituent"}, -// {"children", T_OBJECT_EX, offsetof(BracketObject, children), 0, -// "a list with the children of this bracket"}, -// {NULL} /* Sentinel */ -// }; -// -// static PyTypeObject pgf_BracketType = { -// PyVarObject_HEAD_INIT(NULL, 0) -// //0, /*ob_size*/ -// "pgf.Bracket", /*tp_name*/ -// sizeof(BracketObject), /*tp_basicsize*/ -// 0, /*tp_itemsize*/ -// (destructor)Bracket_dealloc,/*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*/ -// (reprfunc) Bracket_repr, /*tp_str*/ -// 0, /*tp_getattro*/ -// 0, /*tp_setattro*/ -// 0, /*tp_as_buffer*/ -// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ -// "a linearization bracket", /*tp_doc*/ -// 0, /*tp_traverse */ -// 0, /*tp_clear */ -// 0, /*tp_richcompare */ -// 0, /*tp_weaklistoffset */ -// 0, /*tp_iter */ -// 0, /*tp_iternext */ -// 0, /*tp_methods */ -// Bracket_members, /*tp_members */ -// 0, /*tp_getset */ -// 0, /*tp_base */ -// 0, /*tp_dict */ -// 0, /*tp_descr_get */ -// 0, /*tp_descr_set */ -// 0, /*tp_dictoffset */ -// 0, /*tp_init */ -// 0, /*tp_alloc */ -// 0, /*tp_new */ -// }; -// -// typedef struct { -// PyObject_HEAD -// } BINDObject; -// -// static PyObject * -// BIND_repr(BINDObject *self) -// { -// return PyString_FromString("&+"); -// } -// -// static PyTypeObject pgf_BINDType = { -// PyVarObject_HEAD_INIT(NULL, 0) -// //0, /*ob_size*/ -// "pgf.BIND", /*tp_name*/ -// sizeof(BINDObject), /*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*/ -// (reprfunc) BIND_repr, /*tp_str*/ -// 0, /*tp_getattro*/ -// 0, /*tp_setattro*/ -// 0, /*tp_as_buffer*/ -// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ -// "a marker for BIND in a bracketed string", /*tp_doc*/ -// 0, /*tp_traverse */ -// 0, /*tp_clear */ -// 0, /*tp_richcompare */ -// 0, /*tp_weaklistoffset */ -// 0, /*tp_iter */ -// 0, /*tp_iternext */ -// 0, /*tp_methods */ -// 0, /*tp_members */ -// 0, /*tp_getset */ -// 0, /*tp_base */ -// 0, /*tp_dict */ -// 0, /*tp_descr_get */ -// 0, /*tp_descr_set */ -// 0, /*tp_dictoffset */ -// 0, /*tp_init */ -// 0, /*tp_alloc */ -// 0, /*tp_new */ -// }; -// -// typedef struct { -// PgfLinFuncs* funcs; -// GuBuf* stack; -// PyObject* list; -// } PgfBracketLznState; -// -// static void -// pgf_bracket_lzn_symbol_token(PgfLinFuncs** funcs, PgfToken tok) -// { -// PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs); -// -// PyObject* str = PyString_FromString(tok); -// PyList_Append(state->list, str); -// Py_DECREF(str); -// } -// -// static void -// pgf_bracket_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun) -// { -// PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs); -// -// gu_buf_push(state->stack, PyObject*, state->list); -// state->list = PyList_New(0); -// } -// -// static void -// pgf_bracket_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun) -// { -// PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs); -// -// PyObject* parent = gu_buf_pop(state->stack, PyObject*); -// -// if (PyList_Size(state->list) > 0) { -// BracketObject* bracket = (BracketObject *) -// pgf_BracketType.tp_alloc(&pgf_BracketType, 0); -// if (bracket != NULL) { -// bracket->cat = PyString_FromString(cat); -// bracket->fid = fid; -// bracket->ann = PyString_FromString(ann); -// bracket->fun = PyString_FromString(fun); -// bracket->children = state->list; -// PyList_Append(parent, (PyObject*) bracket); -// Py_DECREF(bracket); -// } -// } else { -// Py_DECREF(state->list); -// } -// -// state->list = parent; -// } -// -// static void -// pgf_bracket_lzn_symbol_bind(PgfLinFuncs** funcs) -// { -// PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs); -// -// PyObject* bind = pgf_BINDType.tp_alloc(&pgf_BINDType, 0); -// PyList_Append(state->list, bind); -// Py_DECREF(bind); -// } -// -// static void -// pgf_bracket_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId meta_id) -// { -// pgf_bracket_lzn_symbol_token(funcs, "?"); -// } -// -// static PgfLinFuncs pgf_bracket_lin_funcs = { -// .symbol_token = pgf_bracket_lzn_symbol_token, -// .begin_phrase = pgf_bracket_lzn_begin_phrase, -// .end_phrase = pgf_bracket_lzn_end_phrase, -// .symbol_ne = NULL, -// .symbol_bind = pgf_bracket_lzn_symbol_bind, -// .symbol_capit = NULL, -// .symbol_meta = pgf_bracket_lzn_symbol_meta -// }; -// -// static PyObject* -// Concr_bracketedLinearize(ConcrObject* self, PyObject *args) -// { -// ExprObject* pyexpr; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &pyexpr)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// -// GuEnum* cts = -// pgf_lzr_concretize(self->concr, pyexpr->expr, err, tmp_pool); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be concretized"); -// } -// } -// -// PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool); -// if (gu_variant_is_null(ctree)) { -// PyErr_SetString(PGFError, "The abstract tree cannot be concretized"); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// PyObject* list = PyList_New(0); -// -// ctree = pgf_lzr_wrap_linref(ctree, tmp_pool); -// -// PgfBracketLznState state; -// state.funcs = &pgf_bracket_lin_funcs; -// state.stack = gu_new_buf(PyObject*, tmp_pool); -// state.list = list; -// pgf_lzr_linearize(self->concr, ctree, 0, &state.funcs, tmp_pool); -// -// gu_pool_free(tmp_pool); -// -// return list; -// } -// -// static PyObject* -// Iter_fetch_bracketedLinearization(IterObject* self) -// { -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// -// restart:; -// -// PgfCncTree ctree = gu_next(self->res, PgfCncTree, tmp_pool); -// if (gu_variant_is_null(ctree)) { -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// PyObject* list = PyList_New(0); -// ctree = pgf_lzr_wrap_linref(ctree, tmp_pool); -// -// ConcrObject* pyconcr = (ConcrObject*) self->container; -// -// PgfBracketLznState state; -// state.funcs = &pgf_bracket_lin_funcs; -// state.stack = gu_new_buf(PyObject*, tmp_pool); -// state.list = list; -// pgf_lzr_linearize(pyconcr->concr, ctree, 0, &state.funcs, tmp_pool); -// -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfLinNonExist)) { -// // encountered nonExist. Unfortunately there -// // might be some output printed already. The -// // right solution should be to use GuStringBuf. -// gu_exn_clear(err); -// goto restart; -// } -// else if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// gu_pool_free(tmp_pool); -// return NULL; -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// } -// -// gu_pool_free(tmp_pool); -// return list; -// } -// -// static PyObject* -// Concr_bracketedLinearizeAll(ConcrObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"expression", "n", NULL}; -// ExprObject* pyexpr = NULL; -// int max_count = -1; -// -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|i", kwlist, -// &pgf_ExprType, &pyexpr, &max_count)) -// return NULL; -// -// GuPool* pool = gu_new_pool(); -// GuExn* err = gu_exn(pool); -// -// GuEnum* cts = -// pgf_lzr_concretize(self->concr, pyexpr->expr, err, pool); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// } else { -// PyErr_SetString(PGFError, "The abstract tree cannot be concretized"); -// } -// return NULL; -// } -// -// IterObject* pyres = (IterObject*) pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// gu_pool_free(pool); -// return NULL; -// } -// -// pyres->source = (PyObject*)pyexpr; -// Py_INCREF(pyres->source); -// pyres->container = (PyObject*)self; -// Py_INCREF(pyres->container); -// pyres->pool = pool; -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_bracketedLinearization; -// pyres->res = cts; -// -// return (PyObject*)pyres; -// } -// -// static PyObject* -// Concr_hasLinearization(ConcrObject* self, PyObject *args) -// { -// PgfCId id; -// if (!PyArg_ParseTuple(args, "s", &id)) -// return NULL; -// -// if (pgf_has_linearization(self->concr, id)) -// Py_RETURN_TRUE; -// else -// Py_RETURN_FALSE; -// } -// -// static PyObject* -// Concr_getName(ConcrObject *self, void *closure) -// { -// return PyString_FromString(pgf_concrete_name(self->concr)); -// } -// -// static PyObject* -// Concr_getLanguageCode(ConcrObject *self, void *closure) -// { -// GuString code = pgf_language_code(self->concr); -// if (code == NULL) -// Py_RETURN_NONE; -// return PyString_FromString(code); -// } -// -// static PyObject* -// Concr_graphvizParseTree(ConcrObject* self, PyObject *args) { -// ExprObject* pyexpr; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &pyexpr)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool); -// GuOut* out = gu_string_buf_out(sbuf); -// -// pgf_graphviz_parse_tree(self->concr, pyexpr->expr, pgf_default_graphviz_options, out, err); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// } else { -// PyErr_SetString(PGFError, "The parse tree cannot be visualized"); -// } -// return NULL; -// } -// -// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf), -// gu_string_buf_length(sbuf)); -// -// gu_pool_free(tmp_pool); -// return pystr; -// } -// -// typedef struct { -// PgfMorphoCallback fn; -// PyObject* analyses; -// } PyMorphoCallback; -// -// static void -// pypgf_collect_morpho(PgfMorphoCallback* self, -// PgfCId lemma, GuString analysis, prob_t prob, -// GuExn* err) -// { -// PyMorphoCallback* callback = (PyMorphoCallback*) self; -// -// PyObject* py_lemma = PyString_FromString(lemma); -// PyObject* py_analysis = PyString_FromString(analysis); -// PyObject* res = -// Py_BuildValue("OOf", py_lemma, py_analysis, prob); -// -// if (PyList_Append(callback->analyses, res) != 0) { -// gu_raise(err, PgfExn); -// } -// -// Py_DECREF(py_lemma); -// Py_DECREF(py_analysis); -// Py_DECREF(res); -// } -// -// static PyObject* -// Concr_lookupMorpho(ConcrObject* self, PyObject *args) { -// GuString sent; -// if (!PyArg_ParseTuple(args, "s", &sent)) -// return NULL; -// -// GuPool *tmp_pool = gu_local_pool(); -// GuExn* err = gu_exn(tmp_pool); -// -// PyObject* analyses = PyList_New(0); -// -// PyMorphoCallback callback = { { pypgf_collect_morpho }, analyses }; -// pgf_lookup_morpho(self->concr, sent, &callback.fn, err); -// if (!gu_ok(err)) { -// if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// } else { -// PyErr_SetString(PGFError, "The lookup failed"); -// } -// Py_DECREF(analyses); -// analyses = NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// return analyses; -// } -// -// #define PGF_MORPHOCALLBACK_NAME "pgf.MorphoCallback" -// -// static void -// pypgf_morphocallback_destructor(PyObject *capsule) -// { -// PyMorphoCallback* callback = -// PyCapsule_GetPointer(capsule, PGF_MORPHOCALLBACK_NAME); -// Py_XDECREF(callback->analyses); -// } -// -// static PyObject* -// Iter_fetch_cohort(IterObject* self) -// { -// PgfCohortRange range = -// gu_next(self->res, PgfCohortRange, self->pool); -// if (range.buf == NULL) -// return NULL; -// -// PyObject* py_start = PyLong_FromSize_t(range.start.pos); -// if (py_start == NULL) -// return NULL; -// PyObject* py_end = PyLong_FromSize_t(range.end.pos); -// if (py_end == NULL) { -// Py_DECREF(py_start); -// return NULL; -// } -// -// PyMorphoCallback* callback = -// PyCapsule_GetPointer(PyTuple_GetItem(self->container, 0), -// PGF_MORPHOCALLBACK_NAME); -// -// PyObject* py_slice = -// PySlice_New(py_start, py_end, NULL); -// if (py_slice == NULL) { -// Py_DECREF(py_start); -// Py_DECREF(py_end); -// return NULL; -// } -// -// PyObject* py_w = -// PyObject_GetItem(PyTuple_GetItem(self->container, 1), py_slice); -// -// PyObject* res = -// PyTuple_Pack(4, py_start, py_w, callback->analyses, py_end); -// -// Py_DECREF(callback->analyses); -// callback->analyses = PyList_New(0); -// -// Py_DECREF(py_w); -// Py_DECREF(py_slice); -// Py_DECREF(py_end); -// Py_DECREF(py_start); -// -// return res; -// } -// -// static PyObject* -// Concr_lookupCohorts(ConcrObject* self, PyObject *args) -// { -// PyObject* py_sent = NULL; -// if (!PyArg_ParseTuple(args, "U", &py_sent)) -// return NULL; -// -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) -// return NULL; -// -// pyres->pool = gu_new_pool(); -// pyres->source = (PyObject*) self->grammar; -// Py_XINCREF(pyres->source); -// -// PyMorphoCallback* callback = gu_new(PyMorphoCallback,pyres->pool); -// callback->fn.callback = pypgf_collect_morpho; -// callback->analyses = PyList_New(0); -// PyObject* capsule = -// PyCapsule_New(callback, PGF_MORPHOCALLBACK_NAME, -// pypgf_morphocallback_destructor); -// if (capsule == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// #if PY_MAJOR_VERSION >= 3 -// PyObject* bytes = PyUnicode_AsUTF8String(py_sent); -// if (!bytes) -// return NULL; -// GuString sent = PyBytes_AsString(bytes); -// if (!sent) { -// Py_DECREF(bytes); -// return NULL; -// } -// #else -// GuString sent = PyString_AsString(py_sent); -// if (!sent) -// return NULL; -// #endif -// -// -// pyres->container = -// #if PY_MAJOR_VERSION >= 3 -// PyTuple_Pack(3, capsule, py_sent, bytes); -// Py_DECREF(bytes); -// #else -// PyTuple_Pack(2, capsule, py_sent); -// #endif -// pyres->max_count = -1; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_cohort; -// -// Py_DECREF(capsule); -// -// GuExn* err = gu_new_exn(pyres->pool); -// pyres->res = pgf_lookup_cohorts(self->concr, sent, -// &callback->fn, pyres->pool, err); -// if (pyres->res == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// return (PyObject*) pyres; -// } -// -// static PyObject* -// Iter_fetch_fullform(IterObject* self) -// { -// PgfFullFormEntry* entry = -// gu_next(self->res, PgfFullFormEntry*, self->pool); -// if (entry == NULL) -// return NULL; -// -// PyObject* res = NULL; -// PyObject* py_tokens = NULL; -// PyObject* py_analyses = NULL; -// -// GuString tokens = -// pgf_fullform_get_string(entry); -// -// py_tokens = PyString_FromString(tokens); -// if (py_tokens == NULL) -// goto done; -// -// py_analyses = PyList_New(0); -// if (py_analyses == NULL) -// goto done; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_new_exn(tmp_pool); -// -// PyMorphoCallback callback = { { pypgf_collect_morpho }, py_analyses }; -// pgf_fullform_get_analyses(entry, &callback.fn, err); -// -// if (!gu_ok(err)) -// goto done; -// -// res = Py_BuildValue("OO", py_tokens, py_analyses); -// -// done: -// Py_XDECREF(py_tokens); -// Py_XDECREF(py_analyses); -// -// return res; -// } -// -// static PyObject* -// Concr_fullFormLexicon(ConcrObject* self, PyObject *args) -// { -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) -// return NULL; -// -// pyres->source = (PyObject*) self->grammar; -// Py_XINCREF(pyres->source); -// -// pyres->container = NULL; -// pyres->pool = gu_new_pool(); -// pyres->max_count = -1; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_fullform; -// -// pyres->res = pgf_fullform_lexicon(self->concr, pyres->pool); -// if (pyres->res == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// return (PyObject*) pyres; -// } -// -// static PyObject* -// Concr_load(ConcrObject* self, PyObject *args) -// { -// const char *fpath; -// if (!PyArg_ParseTuple(args, "s", &fpath)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// -// // Create an exception frame that catches all errors. -// GuExn* err = gu_new_exn(tmp_pool); -// -// FILE* infile = fopen(fpath, "rb"); -// if (infile == NULL) { -// PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath); -// return NULL; -// } -// -// // Create an input stream from the input file -// GuIn* in = gu_file_in(infile, tmp_pool); -// -// // Read the PGF grammar. -// pgf_concrete_load(self->concr, in, err); -// if (!gu_ok(err)) { -// fclose(infile); -// if (gu_exn_caught(err, GuErrno)) { -// errno = *((GuErrno*) gu_exn_caught_data(err)); -// PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath); -// } else if (gu_exn_caught(err, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// } else { -// PyErr_SetString(PGFError, "The language cannot be loaded"); -// } -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// fclose(infile); -// -// Py_RETURN_NONE; -// } -// -// static PyObject* -// Concr_unload(ConcrObject* self, PyObject *args) -// { -// if (!PyArg_ParseTuple(args, "")) -// return NULL; -// -// pgf_concrete_unload(self->concr); -// -// Py_RETURN_NONE; -// } -// -// static PyGetSetDef Concr_getseters[] = { -// {"name", -// (getter)Concr_getName, NULL, -// "the name of the concrete syntax", -// }, -// {"languageCode", -// (getter)Concr_getLanguageCode, NULL, -// "the language code for this concrete syntax", -// }, -// {NULL} /* Sentinel */ -// }; -// -// static PyMethodDef Concr_methods[] = { -// {"printName", (PyCFunction)Concr_printName, METH_VARARGS, -// "Returns the print name of a function or category" -// }, -// {"parse", (PyCFunction)Concr_parse, METH_VARARGS | METH_KEYWORDS, -// "Parses a string and returns an iterator over the abstract trees for this sentence\n\n" -// "Named arguments:\n" -// "- sentence (string)\n" -// "- cat (string); OPTIONAL, default: the startcat of the grammar\n" -// "- n (int), max. trees; OPTIONAL, default: extract all trees\n" -// "- heuristics (double >= 0.0); OPTIONAL, default: taken from the flags in the grammar\n" -// "- callbacks (list of category and callback); OPTIONAL, default: built-in callbacks only for Int, String and Float" -// }, -// {"complete", (PyCFunction)Concr_complete, METH_VARARGS | METH_KEYWORDS, -// "Parses a partial string and returns a list with the top n possible next tokens" -// }, -// {"parseval", (PyCFunction)Concr_parseval, METH_VARARGS, -// "Computes precision, recall and exact match for the parser on a given abstract tree" -// }, -// {"lookupSentence", (PyCFunction)Concr_lookupSentence, METH_VARARGS | METH_KEYWORDS, -// "Looks up a sentence from the grammar by a sequence of keywords\n\n" -// "Named arguments:\n" -// "- sentence (string) or tokens (list of strings)\n" -// "- cat (string); OPTIONAL, default: the startcat of the grammar\n" -// "- n (int), max. trees; OPTIONAL, default: extract all trees" -// }, -// {"linearize", (PyCFunction)Concr_linearize, METH_VARARGS, -// "Takes an abstract tree and linearizes it to a string" -// }, -// {"linearizeAll", (PyCFunction)Concr_linearizeAll, METH_VARARGS | METH_KEYWORDS, -// "Takes an abstract tree and linearizes with all variants" -// }, -// {"tabularLinearize", (PyCFunction)Concr_tabularLinearize, METH_VARARGS, -// "Takes an abstract tree and linearizes it to a table containing all fields" -// }, -// {"bracketedLinearize", (PyCFunction)Concr_bracketedLinearize, METH_VARARGS, -// "Takes an abstract tree and linearizes it to a bracketed string" -// }, -// {"bracketedLinearizeAll", (PyCFunction)Concr_bracketedLinearizeAll, METH_VARARGS | METH_KEYWORDS, -// "Takes an abstract tree and linearizes all variants into bracketed strings" -// }, -// {"hasLinearization", (PyCFunction)Concr_hasLinearization, METH_VARARGS, -// "hasLinearization(f) returns true if the function f has linearization in the concrete syntax" -// }, -// {"graphvizParseTree", (PyCFunction)Concr_graphvizParseTree, METH_VARARGS, -// "Renders an abstract syntax tree as a parse tree in Graphviz format" -// }, -// {"lookupMorpho", (PyCFunction)Concr_lookupMorpho, METH_VARARGS, -// "Looks up a word in the lexicon of the grammar" -// }, -// {"lookupCohorts", (PyCFunction)Concr_lookupCohorts, METH_VARARGS, -// "Takes a sentence and returns all matches for lexical items from the grammar in that sentence" -// }, -// {"fullFormLexicon", (PyCFunction)Concr_fullFormLexicon, METH_VARARGS, -// "Enumerates all words in the lexicon (useful for extracting full form lexicons)" -// }, -// {"load", (PyCFunction)Concr_load, METH_VARARGS, -// "Loads the concrete syntax from a .pgf_c file" -// }, -// {"unload", (PyCFunction)Concr_unload, METH_VARARGS, -// "Unloads the concrete syntax" -// }, -// {NULL} /* Sentinel */ -// }; -// -// static PyTypeObject pgf_ConcrType = { -// PyVarObject_HEAD_INIT(NULL, 0) -// //0, /*ob_size*/ -// "pgf.Concr", /*tp_name*/ -// sizeof(ConcrObject), /*tp_basicsize*/ -// 0, /*tp_itemsize*/ -// (destructor)Concr_dealloc, /*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 | Py_TPFLAGS_BASETYPE, /*tp_flags*/ -// "concrete syntax", /*tp_doc*/ -// 0, /*tp_traverse */ -// 0, /*tp_clear */ -// 0, /*tp_richcompare */ -// 0, /*tp_weaklistoffset */ -// 0, /*tp_iter */ -// 0, /*tp_iternext */ -// Concr_methods, /*tp_methods */ -// 0, /*tp_members */ -// Concr_getseters, /*tp_getset */ -// 0, /*tp_base */ -// 0, /*tp_dict */ -// 0, /*tp_descr_get */ -// 0, /*tp_descr_set */ -// 0, /*tp_dictoffset */ -// (initproc)Concr_init, /*tp_init */ -// 0, /*tp_alloc */ -// (newfunc)Concr_new, /*tp_new */ -// }; +// ---------------------------------------------------------------------------- +// PGF: the grammar object static void PGF_dealloc(PGFObject *self) @@ -1772,72 +73,8 @@ PGF_getAbstractName(PGFObject *self, void *closure) return name; } -// static void -// pgf_collect_langs_dict(GuMapItor* fn, const void* key, void* value, GuExn* err) -// { -// PgfCId name = (PgfCId) key; -// PgfConcr* concr = *((PgfConcr**) value); -// PyPGFClosure* clo = (PyPGFClosure*) fn; -// -// PyObject* py_name = NULL; -// PyObject* py_lang = NULL; -// -// py_name = PyString_FromString(name); -// if (py_name == NULL) { -// gu_raise(err, PgfExn); -// goto end; -// } -// -// py_lang = pgf_ConcrType.tp_alloc(&pgf_ConcrType, 0); -// if (py_lang == NULL) { -// gu_raise(err, PgfExn); -// goto end; -// } -// -// ((ConcrObject *) py_lang)->concr = concr; -// ((ConcrObject *) py_lang)->grammar = clo->grammar; -// Py_INCREF(clo->grammar); -// -// if (PyDict_SetItem((PyObject*) clo->collection, py_name, py_lang) != 0) { -// gu_raise(err, PgfExn); -// goto end; -// } -// -// end: -// Py_XDECREF(py_lang); -// Py_XDECREF(py_name); -// } -// -// static PyObject* -// PGF_getLanguages(PGFObject *self, void *closure) -// { -// PyObject* languages = PyDict_New(); -// if (languages == NULL) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// -// // Create an exception frame that catches all errors. -// GuExn* err = gu_new_exn(tmp_pool); -// -// PyPGFClosure clo = { { pgf_collect_langs_dict }, self, languages }; -// pgf_iter_languages(self->pgf, &clo.fn, err); -// if (!gu_ok(err)) { -// Py_DECREF(languages); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// PyObject* proxy = PyDictProxy_New(languages); -// -// Py_DECREF(languages); -// gu_pool_free(tmp_pool); -// -// return proxy; -// } - static void -pgf_collect_cats(PgfItor *fn, PgfText *key, void *value, PgfExn *err) +_collect_cats(PgfItor *fn, PgfText *key, void *value, PgfExn *err) { PgfText *name = key; PyPGFClosure *clo = (PyPGFClosure*) fn; @@ -1864,7 +101,7 @@ PGF_getCategories(PGFObject *self, void *closure) return NULL; PgfExn err; - PyPGFClosure clo = { { pgf_collect_cats }, self, categories }; + PyPGFClosure clo = { { _collect_cats }, self, categories }; pgf_iter_categories(self->db, self->revision, &clo.fn, &err); if (handleError(err) != PGF_EXN_NONE) { Py_DECREF(categories); @@ -1937,7 +174,7 @@ PGF_getStartCat(PGFObject *self, void *closure) } static void -pgf_collect_funs(PgfItor *fn, PgfText *key, void *value, PgfExn *err) +_collect_funs(PgfItor *fn, PgfText *key, void *value, PgfExn *err) { PgfText *name = key; PyPGFClosure *clo = (PyPGFClosure*) fn; @@ -1963,7 +200,7 @@ PGF_getFunctions(PGFObject *self, void *closure) return NULL; PgfExn err; - PyPGFClosure clo = { { pgf_collect_funs }, self, functions }; + PyPGFClosure clo = { { _collect_funs }, self, functions }; pgf_iter_functions(self->db, self->revision, &clo.fn, &err); if (handleError(err) != PGF_EXN_NONE) { Py_DECREF(functions); @@ -1991,7 +228,7 @@ PGF_functionsByCat(PGFObject *self, PyObject *args) } PgfExn err; - PyPGFClosure clo = { { pgf_collect_funs }, self, functions }; + PyPGFClosure clo = { { _collect_funs }, self, functions }; pgf_iter_functions_by_cat(self->db, self->revision, catname, &clo.fn, &err); PyMem_Free(catname); if (handleError(err) != PGF_EXN_NONE) { @@ -2050,312 +287,11 @@ PGF_functionIsConstructor(PGFObject *self, PyObject *args) return PyBool_FromLong(isCon); } -// static IterObject* -// PGF_generateAll(PGFObject* self, PyObject *args, PyObject *keywds) -// { -// static char *kwlist[] = {"cat", "n", NULL}; -// -// PyObject* start = NULL; -// int max_count = -1; -// if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, -// &start, &max_count)) -// return NULL; -// -// IterObject* pyres = (IterObject*) -// pgf_IterType.tp_alloc(&pgf_IterType, 0); -// if (pyres == NULL) { -// return NULL; -// } -// -// pyres->source = (PyObject*) self; -// Py_INCREF(self); -// -// GuPool* out_pool = gu_new_pool(); -// -// PyObject* py_pool = PyPool_New(out_pool); -// pyres->container = PyTuple_Pack(2, pyres->source, py_pool); -// Py_DECREF(py_pool); -// -// pyres->pool = gu_new_pool(); -// pyres->max_count = max_count; -// pyres->counter = 0; -// pyres->fetch = Iter_fetch_expr; -// -// GuExn* err = gu_exn(pyres->pool); -// -// PgfType* type = pgf_type_from_object(start, pyres->pool); -// if (type == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// pyres->res = -// pgf_generate_all(self->pgf, type, err, pyres->pool, out_pool); -// if (pyres->res == NULL) { -// Py_DECREF(pyres); -// return NULL; -// } -// -// return pyres; -// } -// -// static ExprObject* -// PGF_compute(PGFObject* self, PyObject *args) -// { -// ExprObject* py_expr = NULL; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &py_expr)) -// return NULL; -// -// ExprObject* py_expr_res = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0); -// if (py_expr_res == NULL) -// return NULL; -// -// GuPool* tmp_pool = gu_new_pool(); -// GuExn* err = gu_new_exn(tmp_pool); -// -// py_expr_res->pool = gu_new_pool(); -// py_expr_res->expr = pgf_compute(self->pgf, py_expr->expr, err, -// tmp_pool, py_expr_res->pool); -// py_expr_res->master = (PyObject*) self; -// Py_INCREF(py_expr_res->master); -// -// if (!gu_ok(err)) { -// GuString msg = (GuString) gu_exn_caught_data(err); -// PyErr_SetString(PGFError, msg); -// -// Py_DECREF(py_expr_res); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// return py_expr_res; -// } -// -// static ExprObject* -// PGF_checkExpr(PGFObject* self, PyObject *args) -// { -// ExprObject* py_expr = NULL; -// TypeObject* py_type = NULL; -// if (!PyArg_ParseTuple(args, "O!O!", &pgf_ExprType, &py_expr, &pgf_TypeType, &py_type)) -// return NULL; -// -// ExprObject* new_pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0); -// if (new_pyexpr == NULL) -// return NULL; -// -// new_pyexpr->pool = gu_new_pool(); -// new_pyexpr->expr = py_expr->expr; -// new_pyexpr->master = NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* exn = gu_new_exn(tmp_pool); -// -// pgf_check_expr(self->pgf, &new_pyexpr->expr, py_type->type, -// exn, new_pyexpr->pool); -// if (!gu_ok(exn)) { -// if (gu_exn_caught(exn, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(PGFError, msg); -// } else if (gu_exn_caught(exn, PgfTypeError)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(TypeError, msg); -// } -// -// Py_DECREF(new_pyexpr); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// return new_pyexpr; -// } -// -// static PyObject* -// PGF_inferExpr(PGFObject* self, PyObject *args) -// { -// ExprObject* py_expr = NULL; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &py_expr)) -// return NULL; -// -// ExprObject* new_pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0); -// if (new_pyexpr == NULL) -// return NULL; -// -// new_pyexpr->pool = gu_new_pool(); -// new_pyexpr->expr = py_expr->expr; -// new_pyexpr->master = NULL; -// -// TypeObject* new_pytype = (TypeObject*) pgf_TypeType.tp_alloc(&pgf_TypeType, 0); -// if (new_pytype == NULL) { -// Py_DECREF(new_pyexpr); -// return NULL; -// } -// -// new_pytype->pool = NULL; -// new_pytype->type = NULL; -// new_pytype->master = (PyObject*) new_pyexpr; -// Py_INCREF(new_pyexpr); -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* exn = gu_new_exn(tmp_pool); -// -// new_pytype->type = -// pgf_infer_expr(self->pgf, &new_pyexpr->expr, -// exn, new_pyexpr->pool); -// if (!gu_ok(exn)) { -// if (gu_exn_caught(exn, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(PGFError, msg); -// } else if (gu_exn_caught(exn, PgfTypeError)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(TypeError, msg); -// } -// -// Py_DECREF(new_pyexpr); -// Py_DECREF(new_pytype); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// PyObject* res = -// Py_BuildValue("OO", new_pyexpr, new_pytype); -// -// Py_DECREF(new_pyexpr); -// Py_DECREF(new_pytype); -// -// return res; -// } -// -// static TypeObject* -// PGF_checkType(PGFObject* self, PyObject *args) -// { -// TypeObject* py_type = NULL; -// if (!PyArg_ParseTuple(args, "O!", &pgf_TypeType, &py_type)) -// return NULL; -// -// TypeObject* new_pytype = (TypeObject*) pgf_TypeType.tp_alloc(&pgf_TypeType, 0); -// if (new_pytype == NULL) { -// return NULL; -// } -// -// new_pytype->pool = gu_new_pool(); -// new_pytype->type = py_type->type; -// new_pytype->master = NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* exn = gu_new_exn(tmp_pool); -// -// pgf_check_type(self->pgf, &new_pytype->type, -// exn, new_pytype->pool); -// if (!gu_ok(exn)) { -// if (gu_exn_caught(exn, PgfExn)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(PGFError, msg); -// } else if (gu_exn_caught(exn, PgfTypeError)) { -// GuString msg = (GuString) gu_exn_caught_data(exn); -// PyErr_SetString(TypeError, msg); -// } -// -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// return new_pytype; -// } -// -// static PyObject* -// PGF_graphvizAbstractTree(PGFObject* self, PyObject *args) { -// ExprObject* pyexpr; -// if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &pyexpr)) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// GuExn* err = gu_new_exn(tmp_pool); -// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool); -// GuOut* out = gu_string_buf_out(sbuf); -// -// pgf_graphviz_abstract_tree(self->pgf, pyexpr->expr, pgf_default_graphviz_options, out, err); -// if (!gu_ok(err)) { -// PyErr_SetString(PGFError, "The abstract tree cannot be visualized"); -// return NULL; -// } -// -// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf), -// gu_string_buf_length(sbuf)); -// -// gu_pool_free(tmp_pool); -// return pystr; -// } -// -// static void -// pgf_embed_funs(GuMapItor* fn, const void* key, void* value, GuExn* err) -// { -// PyPGFClosure* clo = (PyPGFClosure*) fn; -// -// PgfCId name = (PgfCId) key; -// -// ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0); -// if (pyexpr == NULL) { -// gu_raise(err, PgfExn); -// return; -// } -// -// pyexpr->master = (PyObject*) clo->grammar; -// pyexpr->expr = pgf_fun_get_ep(value)->expr; -// -// Py_INCREF(pyexpr->master); -// -// if (PyModule_AddObject((PyObject*) clo->collection, name, (PyObject*) pyexpr) != 0) { -// Py_DECREF(pyexpr); -// gu_raise(err, PgfExn); -// } -// } -// -// static PyObject* -// PGF_embed(PGFObject* self, PyObject *args) -// { -// PgfCId modname; -// if (!PyArg_ParseTuple(args, "s", &modname)) -// return NULL; -// -// PyObject *m = PyImport_AddModule(modname); -// if (m == NULL) -// return NULL; -// -// GuPool* tmp_pool = gu_local_pool(); -// -// // Create an exception frame that catches all errors. -// GuExn* err = gu_new_exn(tmp_pool); -// -// PyPGFClosure clo = { { pgf_embed_funs }, self, m }; -// pgf_iter_functions(self->pgf, &clo.fn, err); -// if (!gu_ok(err)) { -// Py_DECREF(m); -// gu_pool_free(tmp_pool); -// return NULL; -// } -// -// gu_pool_free(tmp_pool); -// -// Py_INCREF(m); -// return m; -// } - static PyGetSetDef PGF_getseters[] = { {"abstractName", (getter)PGF_getAbstractName, NULL, "the abstract syntax name", NULL}, - // {"languages", - // (getter)PGF_getLanguages, NULL, - // "a map containing all concrete languages in the grammar", - // NULL}, {"categories", (getter)PGF_getCategories, NULL, "a list containing all categories in the grammar", @@ -2393,30 +329,6 @@ static PyMethodDef PGF_methods[] = { "Create new transaction" }, - // {"generateAll", (PyCFunction)PGF_generateAll, METH_VARARGS | METH_KEYWORDS, - // "Generates abstract syntax trees of given category in decreasing probability order" - // }, - // {"compute", (PyCFunction)PGF_compute, METH_VARARGS, - // "Computes the normal form of an abstract syntax tree" - // }, - // {"checkExpr", (PyCFunction)PGF_checkExpr, METH_VARARGS, - // "Type checks an abstract syntax expression and returns the updated expression" - // }, - // {"inferExpr", (PyCFunction)PGF_inferExpr, METH_VARARGS, - // "Type checks an abstract syntax expression and returns the updated expression" - // }, - // {"checkType", (PyCFunction)PGF_checkType, METH_VARARGS, - // "Type checks an abstract syntax type and returns the updated type" - // }, - // {"graphvizAbstractTree", (PyCFunction)PGF_graphvizAbstractTree, METH_VARARGS, - // "Renders an abstract syntax tree in a Graphviz format" - // }, - // {"embed", (PyCFunction)PGF_embed, METH_VARARGS, - // "embed(mod_name) creates a Python module with name mod_name, which " - // "contains one Python object for every abstract function in the grammar. " - // "The module can be imported to make it easier to construct abstract " - // "syntax trees." - // }, {NULL} /* Sentinel */ }; @@ -2463,6 +375,7 @@ static PyTypeObject pgf_PGFType = { }; // ---------------------------------------------------------------------------- +// pgf: the module static PGFObject * pgf_readPGF(PyObject *self, PyObject *args) @@ -2762,18 +675,6 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_TransactionType) < 0) return MOD_ERROR_VAL; - // if (PyType_Ready(&pgf_ConcrType) < 0) - // return MOD_ERROR_VAL; - // - // if (PyType_Ready(&pgf_IterType) < 0) - // return MOD_ERROR_VAL; - // - // if (PyType_Ready(&pgf_BracketType) < 0) - // return MOD_ERROR_VAL; - // - // if (PyType_Ready(&pgf_BINDType) < 0) - // return MOD_ERROR_VAL; - if (PyType_Ready(&pgf_ExprType) < 0) return MOD_ERROR_VAL; @@ -2812,34 +713,12 @@ MOD_INIT(pgf) PyModule_AddObject(m, "PGFError", PGFError); Py_INCREF(PGFError); - // PyObject *dict = PyDict_New(); - // PyDict_SetItemString(dict, "token", PyString_FromStringAndSize("", 0)); - // ParseError = PyErr_NewException("pgf.ParseError", NULL, dict); - // PyModule_AddObject(m, "ParseError", ParseError); - // Py_INCREF(ParseError); - - // TypeError = PyErr_NewException("pgf.TypeError", NULL, NULL); - // PyModule_AddObject(m, "TypeError", TypeError); - // Py_INCREF(TypeError); - PyModule_AddObject(m, "PGF", (PyObject *) &pgf_PGFType); Py_INCREF(&pgf_PGFType); PyModule_AddObject(m, "Transaction", (PyObject *) &pgf_TransactionType); Py_INCREF(&pgf_TransactionType); - // PyModule_AddObject(m, "Concr", (PyObject *) &pgf_ConcrType); - // Py_INCREF(&pgf_ConcrType); - // - // PyModule_AddObject(m, "Iter", (PyObject *) &pgf_IterType); - // Py_INCREF(&pgf_IterType); - // - // PyModule_AddObject(m, "Bracket", (PyObject *) &pgf_BracketType); - // Py_INCREF(&pgf_BracketType); - // - // PyModule_AddObject(m, "BIND", (PyObject *) &pgf_BINDType); - // Py_INCREF(&pgf_BINDType); - PyModule_AddObject(m, "Expr", (PyObject *) &pgf_ExprType); Py_INCREF(&pgf_ExprType); diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py index d9c34f0f2..6e7d52a37 100644 --- a/src/runtime/python/tests/test_transactions.py +++ b/src/runtime/python/tests/test_transactions.py @@ -18,7 +18,7 @@ def gr2(gr1): @pytest.fixture(scope="module") def gr3(gr1): - with gr1.newTransaction() as t: + with gr1.newTransaction("bar_branch") as t: t.createFunction("bar", ty, 0, prob), # t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) return gr1 diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index f4baaed99..3f3734d5f 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -11,10 +11,22 @@ TransactionObject * PGF_newTransaction(PGFObject *self, PyObject *args) { PgfText *name = NULL; - // PgfText *name = PyUnicode_AsPgfText(PyUnicode_FromString("transient")); + const char *s = NULL; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "|s#", &s, &size)) + return NULL; + + if (s != NULL) { + name = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(name->text, s, size+1); + name->size = size; + } PgfExn err; PgfRevision rev = pgf_clone_revision(self->db, self->revision, name, &err); + if (name != NULL) { + PyMem_Free(name); + } if (handleError(err) != PGF_EXN_NONE) { return NULL; } @@ -26,7 +38,7 @@ PGF_newTransaction(PGFObject *self, PyObject *args) return trans; } -PyObject * +static PyObject * Transaction_commit(TransactionObject *self, PyObject *args) { PgfExn err; @@ -40,7 +52,7 @@ Transaction_commit(TransactionObject *self, PyObject *args) Py_RETURN_TRUE; } -PyObject * +static PyObject * Transaction_createFunction(TransactionObject *self, PyObject *args) { const char *s; @@ -65,7 +77,7 @@ Transaction_createFunction(TransactionObject *self, PyObject *args) Py_RETURN_NONE; } -PyObject * +static PyObject * Transaction_dropFunction(TransactionObject *self, PyObject *args) { const char *s; @@ -87,7 +99,7 @@ Transaction_dropFunction(TransactionObject *self, PyObject *args) Py_RETURN_NONE; } -PyObject * +static PyObject * Transaction_createCategory(TransactionObject *self, PyObject *args) { const char *s; @@ -113,7 +125,7 @@ Transaction_createCategory(TransactionObject *self, PyObject *args) Py_RETURN_NONE; } -PyObject * +static PyObject * Transaction_dropCategory(TransactionObject *self, PyObject *args) { const char *s; @@ -135,8 +147,6 @@ Transaction_dropCategory(TransactionObject *self, PyObject *args) Py_RETURN_NONE; } -// ---------------------------------------------------------------------------- - static PyObject * Transaction_enter(TransactionObject *self, PyObject *Py_UNUSED(ignored)) { diff --git a/src/runtime/python/transactions.h b/src/runtime/python/transactions.h index 18083915f..d72835425 100644 --- a/src/runtime/python/transactions.h +++ b/src/runtime/python/transactions.h @@ -12,24 +12,9 @@ typedef struct { PgfRevision revision; // transient branch } TransactionObject; -extern PyTypeObject pgf_TransactionType; +PyTypeObject pgf_TransactionType; TransactionObject * PGF_newTransaction(PGFObject *self, PyObject *args); -PyObject * -Transaction_commit(TransactionObject *self, PyObject *args); - -PyObject * -Transaction_createFunction(TransactionObject *self, PyObject *args); - -PyObject * -Transaction_dropFunction(TransactionObject *self, PyObject *args); - -PyObject * -Transaction_createCategory(TransactionObject *self, PyObject *args); - -PyObject * -Transaction_dropCategory(TransactionObject *self, PyObject *args); - #endif // PYPGF_TRANSACTIONS_H_ From 4af807c982a5b857e69639a0b2eedabe9258dddd Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 21 Sep 2021 23:34:03 +0200 Subject: [PATCH 5/6] Fix createCategory. Add functionProbability. --- src/runtime/python/ffi.c | 6 ++-- src/runtime/python/pypgf.c | 25 ++++++++++++++++ src/runtime/python/tests/test_transactions.py | 30 +++++++++++-------- src/runtime/python/transactions.c | 15 ++++++++-- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/runtime/python/ffi.c b/src/runtime/python/ffi.c index 2315b5537..944a615b9 100644 --- a/src/runtime/python/ffi.c +++ b/src/runtime/python/ffi.c @@ -323,7 +323,8 @@ match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty) TypeObject *type = (TypeObject *)ty; Py_ssize_t n_hypos = PyList_Size(type->hypos); - PgfTypeHypo *hypos = alloca(sizeof(PgfTypeHypo)*n_hypos); + PgfTypeHypo hypos[n_hypos]; + // PgfTypeHypo *hypos = alloca(sizeof(PgfTypeHypo)*n_hypos); for (Py_ssize_t i = 0; i < n_hypos; i++) { PyObject *hytup = (PyObject *)PyList_GetItem(type->hypos, i); hypos[i].bind_type = PyLong_AsLong(PyTuple_GetItem(hytup, 0)); @@ -338,7 +339,8 @@ match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty) } Py_ssize_t n_exprs = PyList_Size(type->exprs); - PgfExpr *exprs = alloca(sizeof(PgfExpr)*n_exprs); + PgfExpr exprs[n_exprs]; + // PgfExpr *exprs = alloca(sizeof(PgfExpr)*n_exprs); for (Py_ssize_t i = 0; i < n_exprs; i++) { exprs[i] = (PgfExpr)PyList_GetItem(type->exprs, i); Py_INCREF(exprs[i]); diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index cc5337886..10fb5653d 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -287,6 +287,28 @@ PGF_functionIsConstructor(PGFObject *self, PyObject *args) return PyBool_FromLong(isCon); } +static PyObject * +PGF_functionProbability(PGFObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &s, &size)) + return NULL; + + PgfText *funname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(funname->text, s, size+1); + funname->size = size; + + PgfExn err; + prob_t prob = pgf_function_prob(self->db, self->revision, funname, &err); + PyMem_Free(funname); + if (handleError(err) != PGF_EXN_NONE) { + return NULL; + } + + return PyFloat_FromDouble((double)prob); +} + static PyGetSetDef PGF_getseters[] = { {"abstractName", (getter)PGF_getAbstractName, NULL, @@ -324,6 +346,9 @@ static PyMethodDef PGF_methods[] = { {"functionIsConstructor", (PyCFunction)PGF_functionIsConstructor, METH_VARARGS, "Checks whether a function is a constructor" }, + {"functionProbability", (PyCFunction)PGF_functionProbability, METH_VARARGS, + "Returns the probability of a function" + }, {"newTransaction", (PyCFunction)PGF_newTransaction, METH_VARARGS, "Create new transaction" diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py index 6e7d52a37..c2932fc90 100644 --- a/src/runtime/python/tests/test_transactions.py +++ b/src/runtime/python/tests/test_transactions.py @@ -1,8 +1,9 @@ import pytest from pgf import * +import math ty = readType("(N -> N) -> P (s z)") -prob = 3.142 +prob = math.pi @pytest.fixture(scope="module") def gr1(): @@ -12,7 +13,7 @@ def gr1(): def gr2(gr1): t = gr1.newTransaction() t.createFunction("foo", ty, 0, prob), - # t.createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) + t.createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) assert t.commit() return gr1 @@ -20,7 +21,7 @@ def gr2(gr1): def gr3(gr1): with gr1.newTransaction("bar_branch") as t: t.createFunction("bar", ty, 0, prob), - # t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) + t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) return gr1 # gr1 @@ -35,26 +36,29 @@ def test_original_function_type(gr1): with pytest.raises(KeyError): gr1.functionType("foo") -# def test_original_function_prob(gr1): -# with pytest.raises(KeyError): -# gr1.functionProbability("foo") +def test_original_function_prob(gr1): + # with pytest.raises(KeyError): + # gr1.functionProbability("foo") + assert gr1.functionProbability("foo") == float('inf') # gr2 def test_extended_functions(gr2): assert gr2.functions == ["c", "foo", "ind", "s", "z"] -# def test_extended_categories(gr2): -# assert gr2.categories == ["Float","Int","N","P","Q","S","String"] -# -# def test_extended_category_context(gr2): -# assert gr2.categoryContext("Q") == [(BIND_TYPE_EXPLICIT, "x", ty)] +def test_extended_categories(gr2): + assert gr2.categories == ["Float","Int","N","P","Q","S","String"] + +def test_extended_category_context(gr2): + assert gr2.categoryContext("Q") == [(BIND_TYPE_EXPLICIT, "x", ty)] def test_extended_function_type(gr2): assert gr2.functionType("foo") == ty -# def test_extended_function_prob(gr2): -# assert gr2.functionProbability("foo") == prob +def test_extended_function_prob(gr2): + # TODO: can't we get higher precision? + # assert gr2.functionProbability("foo") == prob + assert math.isclose(gr2.functionProbability("foo"), prob, rel_tol=1e-06) # gr3 diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index 3f3734d5f..b6c5db408 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -104,16 +104,25 @@ Transaction_createCategory(TransactionObject *self, PyObject *args) { const char *s; Py_ssize_t size; + PyObject *hypos; float prob = 0.0; - if (!PyArg_ParseTuple(args, "s#f", &s, &size, prob)) + if (!PyArg_ParseTuple(args, "s#O!f", &s, &size, &PyList_Type, &hypos, prob)) return NULL; PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); memcpy(catname->text, s, size+1); catname->size = size; - Py_ssize_t n_hypos = 0; - PgfTypeHypo *context = NULL; + Py_ssize_t n_hypos = PyList_Size(hypos); + PgfTypeHypo context[n_hypos]; + // PgfTypeHypo *context = alloca(sizeof(PgfTypeHypo)*n_hypos); + for (Py_ssize_t i = 0; i < n_hypos; i++) { + PyObject *hytup = (PyObject *)PyList_GetItem(hypos, i); + context[i].bind_type = PyLong_AsLong(PyTuple_GetItem(hytup, 0)); + context[i].cid = PyUnicode_AsPgfText(PyTuple_GetItem(hytup, 1)); + context[i].type = (PgfType) PyTuple_GetItem(hytup, 2); + Py_INCREF(context[i].type); + } PgfExn err; pgf_create_category(self->pgf->db, self->revision, catname, n_hypos, context, prob, &marshaller, &err); From 60c9ab4c53955ee58bbb9c32fe6fd128407c00f3 Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 21 Sep 2021 23:54:55 +0200 Subject: [PATCH 6/6] Fix handlers for 'with' syntax in Transaction object --- src/runtime/python/pypgf.c | 2 ++ src/runtime/python/tests/test_transactions.py | 14 ++++++++------ src/runtime/python/transactions.c | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 10fb5653d..6f2d7d7cd 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -330,6 +330,8 @@ static PyGetSetDef PGF_getseters[] = { }; static PyMemberDef PGF_members[] = { + // {"revision", T_PYSSIZET, offsetof(PGFObject, revision), READONLY, + // "the revision number of this PGF"}, {NULL} /* Sentinel */ }; diff --git a/src/runtime/python/tests/test_transactions.py b/src/runtime/python/tests/test_transactions.py index c2932fc90..20cf806ad 100644 --- a/src/runtime/python/tests/test_transactions.py +++ b/src/runtime/python/tests/test_transactions.py @@ -18,7 +18,9 @@ def gr2(gr1): return gr1 @pytest.fixture(scope="module") -def gr3(gr1): +def gr3(): + # TODO how to avoid reloading from file? + gr1 = readPGF("../haskell/tests/basic.pgf") with gr1.newTransaction("bar_branch") as t: t.createFunction("bar", ty, 0, prob), t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob) @@ -62,8 +64,8 @@ def test_extended_function_prob(gr2): # gr3 -# def test_branched_functions(gr3): -# assert gr3.functions == ["bar", "c", "ind", "s", "z"] -# -# def test_branched_function_type(gr3): -# assert gr3.functionType("bar") == ty +def test_branched_functions(gr3): + assert gr3.functions == ["bar", "c", "ind", "s", "z"] + +def test_branched_function_type(gr3): + assert gr3.functionType("bar") == ty diff --git a/src/runtime/python/transactions.c b/src/runtime/python/transactions.c index b6c5db408..62c0d2960 100644 --- a/src/runtime/python/transactions.c +++ b/src/runtime/python/transactions.c @@ -47,6 +47,7 @@ Transaction_commit(TransactionObject *self, PyObject *args) return NULL; } + pgf_free_revision(self->pgf->db, self->pgf->revision); self->pgf->revision = self->revision; Py_RETURN_TRUE; @@ -156,10 +157,10 @@ Transaction_dropCategory(TransactionObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +static TransactionObject * Transaction_enter(TransactionObject *self, PyObject *Py_UNUSED(ignored)) { - Py_RETURN_TRUE; + return self; } static PyObject *