Work in progress with marshalling in Python bindings, trying to get Type_str to work without segfaulting

This commit is contained in:
John J. Camilleri
2021-09-06 23:49:53 +02:00
parent b7cddf206b
commit 5b96ede199
4 changed files with 78 additions and 25 deletions

View File

@@ -814,7 +814,7 @@
static PyObject *
Type_str(TypeObject *self)
{
PgfText *s = pgf_print_type((PgfType) &self, NULL, 0, &marshaller);
PgfText *s = pgf_print_type((PgfType) &self, NULL, 1, &marshaller);
return PyString_FromStringAndSize(s->text, s->size);
}

View File

@@ -15,46 +15,58 @@
PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body)
{
PyErr_SetString(PyExc_NotImplementedError, "eabs not implemented");
return 0;
}
PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg)
{
PyErr_SetString(PyExc_NotImplementedError, "eapp not implemented");
return 0;
}
PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit)
{
PyErr_SetString(PyExc_NotImplementedError, "elit not implemented");
return 0;
}
PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta)
{
PyErr_SetString(PyExc_NotImplementedError, "emeta not implemented");
return 0;
}
PgfExpr efun(PgfUnmarshaller *this, PgfText *name)
{
PyErr_SetString(PyExc_NotImplementedError, "efun not implemented");
return 0;
}
PgfExpr evar(PgfUnmarshaller *this, int index)
{
PyErr_SetString(PyExc_NotImplementedError, "evar not implemented");
return 0;
}
PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ)
{
PyErr_SetString(PyExc_NotImplementedError, "etyped not implemented");
return 0;
}
PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr)
{
PyErr_SetString(PyExc_NotImplementedError, "eimplarg not implemented");
return 0;
}
PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v)
{
if (size > 1) {
PyErr_SetString(PyExc_NotImplementedError, "multi-part integers not implemented"); // TODO
return 0;
}
PyObject *i = PyLong_FromUnsignedLong(*v);
return (PgfLiteral) i;
}
@@ -89,6 +101,11 @@ PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *ca
pytype->cat = PyString_FromStringAndSize(cat->text, cat->size);
pytype->exprs = PyList_New(0);
for (int i = 0; i < n_exprs; i++) {
// TODO
// PgfExpr *expr = exprs + i;
}
return (PgfType) pytype;
}
@@ -119,37 +136,67 @@ PgfUnmarshaller unmarshaller = { &unmarshallerVtbl };
// ----------------------------------------------------------------------------
static PgfText *
PyString_AsPgfText(PyObject *pystr)
{
if (!PyString_Check(pystr)) {
PyErr_SetString(PyExc_TypeError, "input to PyString_AsPgfText is not a string");
return NULL;
}
size_t size = PyUnicode_GetLength(pystr);
PgfText *ptext = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
memcpy(ptext->text, pystr, size+1);
ptext->size = size;
// Py_INCREF(ptext);
return ptext;
}
// ----------------------------------------------------------------------------
object match_lit(PgfUnmarshaller *u, PgfLiteral lit)
{
if (PyString_Check(lit)) {
// PgfText t = {
// PyUnicode_GetLength((PyObject*) lit),
// lit,
// };
// return lstr(u, &lit);
return 0;
}
else if (PyLong_Check(lit)) {
PyObject *pyobj = (PyObject *)lit;
return lint(u, 1, (uintmax_t *)lit);
if (PyLong_Check(pyobj)) {
uintmax_t i = PyLong_AsUnsignedLong(pyobj);
size_t size = 1; // TODO
return u->vtbl->lint(NULL, size, &i);
}
else if (PyFloat_Check(lit)) {
return lflt(u, *(double *)lit);
else if (PyFloat_Check(pyobj)) {
double d = PyFloat_AsDouble(pyobj);
return u->vtbl->lflt(NULL, d);
}
else if (PyString_Check(pyobj)) {
PgfText *t = PyString_AsPgfText(pyobj);
return u->vtbl->lstr(NULL, t);
}
else {
PyErr_SetString(PyExc_TypeError, "Unable to match on literal");
PyErr_SetString(PyExc_TypeError, "unable to match on literal");
return 0;
}
}
object match_expr(PgfUnmarshaller *u, PgfExpr expr)
{
PyErr_SetString(PyExc_NotImplementedError, "match_expr not implemented");
return 0;
}
object match_type(PgfUnmarshaller *u, PgfType ty)
{
return 0;
TypeObject *type = (TypeObject *)ty;
PySys_WriteStdout(">%s<\n", PyUnicode_AS_DATA(type->cat));
int n_hypos = 0; //PyList_Size(type->hypos);
PgfTypeHypo *hypos = NULL; // TODO
PgfText *cat = PyString_AsPgfText(type->cat);
int n_exprs = 0; //PyList_Size(type->exprs);
PgfExpr *exprs = NULL; // TODO
return u->vtbl->dtyp(NULL, n_hypos, hypos, cat, n_exprs, exprs);
}
static PgfMarshallerVtbl marshallerVtbl =

View File

@@ -1880,7 +1880,7 @@ PGF_getStartCat(PGFObject *self, void *closure)
{
PgfType type = pgf_start_cat(self->pgf, &unmarshaller);
if (type == 0) {
PyErr_SetString(PGFError, "The start category cannot be found");
PyErr_SetString(PGFError, "start category cannot be found");
return NULL;
}
@@ -1924,19 +1924,19 @@ PGF_getFunctions(PGFObject *self, void *closure)
return functions;
}
static PyObject*
PGF_functionsByCat(PGFObject* self, PyObject *args)
static PyObject *
PGF_functionsByCat(PGFObject *self, PyObject *args)
{
const char* s;
const char *s;
Py_ssize_t size;
if (!PyArg_ParseTuple(args, "s#", &s, &size))
return NULL;
PgfText* catname = (PgfText*) alloca(sizeof(PgfText)+size+1);
PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
memcpy(catname->text, s, size+1);
catname->size = size;
PyObject* functions = PyList_New(0);
PyObject *functions = PyList_New(0);
if (functions == NULL) {
return NULL;
}
@@ -1944,6 +1944,7 @@ PGF_functionsByCat(PGFObject* self, PyObject *args)
PgfExn err;
PyPGFClosure clo = { { pgf_collect_funs }, self, functions };
pgf_iter_functions_by_cat(self->pgf, catname, &clo.fn, &err);
PyMem_Free(catname);
if (err.type != PGF_EXN_NONE) {
Py_DECREF(functions);
return NULL;
@@ -1960,13 +1961,14 @@ PGF_functionType(PGFObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s#", &s, &size))
return NULL;
PgfText *funname = (PgfText *)alloca(sizeof(PgfText)+size+1);
PgfText *funname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
memcpy(funname->text, s, size+1);
funname->size = size;
PgfType type = pgf_function_type(self->pgf, funname, &unmarshaller);
PyMem_Free(funname);
if (type == 0) {
PyErr_Format(PyExc_KeyError, "Function '%s' is not defined", funname->text);
PyErr_Format(PyExc_KeyError, "function '%s' is not defined", s);
return NULL;
}
@@ -2494,13 +2496,14 @@ pgf_readType(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s#", &s, &size))
return NULL;
PgfText *input = (PgfText *)alloca(sizeof(PgfText)+size+1);
PgfText *input = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
memcpy(input->text, s, size+1);
input->size = size;
PgfType type = pgf_read_type(input, &unmarshaller);
PyMem_Free(input);
if (type == 0) {
PyErr_SetString(PGFError, "The type cannot be parsed");
PyErr_SetString(PGFError, "type cannot be parsed");
return NULL;
}

View File

@@ -103,6 +103,9 @@ def test_readType_inequality_1():
def test_readType_inequality_2():
assert pgf.readType("A -> B") != pgf.readType("B->B")
def test_Type_str_1():
assert str(pgf.readType("A-> B")) == "A -> B"
def test_functionType_1(PGF):
assert PGF.functionType("z") == pgf.readType("N")