Refactor modules in Python bindings. Start work on grammar-update functions, but without transactions.

This commit is contained in:
John J. Camilleri
2021-09-20 23:42:50 +02:00
parent e41feae82a
commit 7dba3465d0
10 changed files with 243 additions and 35 deletions

View File

@@ -4,7 +4,7 @@
#include <pgf/pgf.h>
#include "./expr.h"
#include "./marshaller.h"
#include "./ffi.h"
// ----------------------------------------------------------------------------

View File

@@ -5,7 +5,25 @@
#include <pgf/pgf.h>
#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;
}
// ----------------------------------------------------------------------------

View File

@@ -6,6 +6,15 @@
#include <pgf/pgf.h>
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);

View File

@@ -4,35 +4,13 @@
#include <pgf/pgf.h>
#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)
{

View File

@@ -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,

View File

@@ -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"]

View File

@@ -0,0 +1,102 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
// #include <stdbool.h>
#include <pgf/pgf.h>
#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;
}

View File

@@ -0,0 +1,38 @@
#ifndef PYPGF_TRANSACTIONS_H_
#define PYPGF_TRANSACTIONS_H_
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <pgf/pgf.h>
// 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_