forked from GitHub/gf-core
Working readType, functionType, unmarshaller for types (except exprs) in Python bindings
This commit is contained in:
28
src/runtime/python/compat.h
Normal file
28
src/runtime/python/compat.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PYPGF_COMPAT_H_
|
||||||
|
#define PYPGF_COMPAT_H_
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
// #define PyIntObject PyLongObject
|
||||||
|
// #define PyInt_Type PyLong_Type
|
||||||
|
// #define PyInt_Check(op) PyLong_Check(op)
|
||||||
|
// #define PyInt_CheckExact(op) PyLong_CheckExact(op)
|
||||||
|
// #define PyInt_FromString PyLong_FromString
|
||||||
|
// #define PyInt_FromUnicode PyLong_FromUnicode
|
||||||
|
// #define PyInt_FromLong PyLong_FromLong
|
||||||
|
// #define PyInt_FromSize_t PyLong_FromSize_t
|
||||||
|
// #define PyInt_FromSsize_t PyLong_FromSsize_t
|
||||||
|
// #define PyInt_AsLong PyLong_AsLong
|
||||||
|
// #define PyInt_AS_LONG PyLong_AS_LONG
|
||||||
|
// #define PyInt_AsSsize_t PyLong_AsSsize_t
|
||||||
|
// #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
|
||||||
|
// #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
|
||||||
|
|
||||||
|
#define PyStringObject PyUnicodeObject
|
||||||
|
// #define PyString_Check PyUnicode_Check
|
||||||
|
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
||||||
|
// #define PyString_FromFormat PyUnicode_FromFormat
|
||||||
|
// #define PyString_Concat(ps,s) {PyObject* tmp = *(ps); *(ps) = PyUnicode_Concat(tmp,s); Py_DECREF(tmp);}
|
||||||
|
#define PyString_Compare PyUnicode_Compare
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // PYPGF_COMPAT_H_
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "expr.h"
|
#include "./expr.h"
|
||||||
|
|
||||||
// static ExprObject*
|
// static ExprObject*
|
||||||
// Expr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
// Expr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
@@ -665,36 +665,28 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
static TypeObject*
|
// static TypeObject*
|
||||||
Type_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
// Type_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
// {
|
||||||
TypeObject* self = (TypeObject *)type->tp_alloc(type, 0);
|
// TypeObject* self = (TypeObject *)type->tp_alloc(type, 0);
|
||||||
if (self != NULL) {
|
// if (self != NULL) {
|
||||||
self->master = NULL;
|
// self->hypos = NULL;
|
||||||
// self->pool = NULL;
|
// self->cat = NULL;
|
||||||
// self->type = NULL;
|
// self->exprs = NULL;
|
||||||
self->cat = NULL;
|
// }
|
||||||
}
|
//
|
||||||
|
// return self;
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
Type_dealloc(TypeObject* self)
|
|
||||||
{
|
|
||||||
if (self->master != NULL) {
|
|
||||||
Py_DECREF(self->master);
|
|
||||||
}
|
|
||||||
// if (self->pool != NULL) {
|
|
||||||
// gu_pool_free(self->pool);
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
// static void
|
||||||
}
|
// Type_dealloc(TypeObject *self)
|
||||||
|
// {
|
||||||
|
// Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
|
// }
|
||||||
|
|
||||||
static int
|
// static int
|
||||||
Type_init(TypeObject *self, PyObject *args, PyObject *kwds)
|
// Type_init(TypeObject *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
// {
|
||||||
// PyObject* py_hypos;
|
// PyObject* py_hypos;
|
||||||
// const char* catname_s;
|
// const char* catname_s;
|
||||||
// PyObject* py_exprs;
|
// PyObject* py_exprs;
|
||||||
@@ -813,9 +805,9 @@ Type_init(TypeObject *self, PyObject *args, PyObject *kwds)
|
|||||||
//
|
//
|
||||||
// self->type->exprs[i] = ((ExprObject*) obj)->expr;
|
// self->type->exprs[i] = ((ExprObject*) obj)->expr;
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Type_repr(TypeObject *self)
|
Type_repr(TypeObject *self)
|
||||||
@@ -835,29 +827,43 @@ Type_repr(TypeObject *self)
|
|||||||
// return pystr;
|
// return pystr;
|
||||||
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Type_repr: not implemented");
|
PyErr_SetString(PyExc_TypeError, "Type_repr: not implemented");
|
||||||
return NULL;
|
Py_RETURN_NOTIMPLEMENTED;
|
||||||
}
|
|
||||||
|
|
||||||
bool pgfTextEqual(PgfText *t1, PgfText *t2) {
|
|
||||||
if (t1->size != t2->size) return false;
|
|
||||||
for (size_t i = 0; i < t1->size; i++) {
|
|
||||||
if (t1->text[i] != t2->text[i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Type_richcompare(TypeObject *t1, TypeObject *t2, int op)
|
Type_richcompare(TypeObject *t1, TypeObject *t2, int op)
|
||||||
{
|
{
|
||||||
bool cmp = pgfTextEqual(t1->cat, t2->cat);
|
bool same = false;
|
||||||
|
if (PyString_Compare(t1->cat, t2->cat) != 0) goto done;
|
||||||
|
|
||||||
|
if (PyList_Size(t1->hypos) != PyList_Size(t2->hypos)) goto done;
|
||||||
|
for (Py_ssize_t n = 0; n < PyList_Size(t1->hypos); n++) {
|
||||||
|
PyObject *h1 = PyList_GetItem(t1->hypos, n);
|
||||||
|
PyObject *h2 = PyList_GetItem(t2->hypos, n);
|
||||||
|
if (PyTuple_GetItem(h1, 0) != PyTuple_GetItem(h2, 0)) goto done;
|
||||||
|
if (PyString_Compare(PyTuple_GetItem(h1, 1), PyTuple_GetItem(h2, 1)) != 0) goto done;
|
||||||
|
TypeObject *ht1 = (TypeObject *)PyTuple_GetItem(h1, 2);
|
||||||
|
TypeObject *ht2 = (TypeObject *)PyTuple_GetItem(h2, 2);
|
||||||
|
if (Type_richcompare(ht1, ht2, Py_EQ) != Py_True) goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyList_Size(t1->exprs) != PyList_Size(t2->exprs)) goto done;
|
||||||
|
// for (Py_ssize_t n = 0; n < PyList_Size(t1->exprs); n++) {
|
||||||
|
// ExprObject *e1 = PyList_GetItem(t1->exprs, n);
|
||||||
|
// ExprObject *e2 = PyList_GetItem(t2->exprs, n);
|
||||||
|
// if (Expr_richcompare(e1, e2, Py_EQ) != Py_True) goto done; // TODO
|
||||||
|
// }
|
||||||
|
|
||||||
|
same = true;
|
||||||
|
done:
|
||||||
|
|
||||||
if (op == Py_EQ) {
|
if (op == Py_EQ) {
|
||||||
if (cmp) Py_RETURN_TRUE; else Py_RETURN_FALSE;
|
if (same) Py_RETURN_TRUE; else Py_RETURN_FALSE;
|
||||||
} else if (op == Py_NE) {
|
} else if (op == Py_NE) {
|
||||||
if (cmp) Py_RETURN_FALSE; else Py_RETURN_TRUE;
|
if (same) Py_RETURN_FALSE; else Py_RETURN_TRUE;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError, "comparison operation not supported");
|
PyErr_SetString(PyExc_TypeError, "comparison operation not supported");
|
||||||
return NULL;
|
Py_RETURN_NOTIMPLEMENTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,7 +1050,7 @@ PyTypeObject pgf_TypeType = {
|
|||||||
"pgf.Type", /*tp_name*/
|
"pgf.Type", /*tp_name*/
|
||||||
sizeof(TypeObject), /*tp_basicsize*/
|
sizeof(TypeObject), /*tp_basicsize*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
(destructor) Type_dealloc, /*tp_dealloc*/
|
0, //(destructor) Type_dealloc, /*tp_dealloc*/
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
0, /*tp_getattr*/
|
0, /*tp_getattr*/
|
||||||
0, /*tp_setattr*/
|
0, /*tp_setattr*/
|
||||||
@@ -1075,7 +1081,7 @@ PyTypeObject pgf_TypeType = {
|
|||||||
0, /*tp_descr_get */
|
0, /*tp_descr_get */
|
||||||
0, /*tp_descr_set */
|
0, /*tp_descr_set */
|
||||||
0, /*tp_dictoffset */
|
0, /*tp_dictoffset */
|
||||||
(initproc) Type_init, /*tp_init */
|
0, //(initproc) Type_init, /*tp_init */
|
||||||
0, /*tp_alloc */
|
0, /*tp_alloc */
|
||||||
(newfunc) Type_new, /*tp_new */
|
0, //(newfunc) Type_new, /*tp_new */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,12 +6,13 @@
|
|||||||
|
|
||||||
#include <pgf/pgf.h>
|
#include <pgf/pgf.h>
|
||||||
|
|
||||||
|
#include "./compat.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject* master;
|
PyObject *hypos; // PyListObject of PyTupleObject: (bind_type: int, cid: string, type: TypeObject)
|
||||||
// GuPool* pool;
|
PyObject *cat; // PyStringObject
|
||||||
// PgfType* type;
|
PyObject *exprs; // PyListObject of ExprObject
|
||||||
PgfText *cat;
|
|
||||||
} TypeObject;
|
} TypeObject;
|
||||||
|
|
||||||
extern PyTypeObject pgf_TypeType;
|
extern PyTypeObject pgf_TypeType;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// #define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
// #include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
#include <pgf/pgf.h>
|
#include <pgf/pgf.h>
|
||||||
|
|
||||||
|
#include "./compat.h"
|
||||||
#include "./expr.h"
|
#include "./expr.h"
|
||||||
|
|
||||||
/* The PgfUnmarshaller structure tells the runtime how to create
|
/* The PgfUnmarshaller structure tells the runtime how to create
|
||||||
@@ -71,12 +73,22 @@ PgfLiteral lstr(PgfUnmarshaller *this, PgfText *v)
|
|||||||
|
|
||||||
PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs)
|
PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs)
|
||||||
{
|
{
|
||||||
PgfText *catname = (PgfText*) malloc(sizeof(PgfText)+cat->size+1);
|
|
||||||
memcpy(catname->text, cat->text, cat->size+1);
|
|
||||||
catname->size = cat->size;
|
|
||||||
|
|
||||||
TypeObject *pytype = (TypeObject *)pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
|
TypeObject *pytype = (TypeObject *)pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
|
||||||
pytype->cat = catname;
|
|
||||||
|
pytype->hypos = PyList_New(0);
|
||||||
|
for (int i = 0; i < n_hypos; i++) {
|
||||||
|
PgfTypeHypo *hypo = hypos + i;
|
||||||
|
PyObject *tup = PyTuple_New(3);
|
||||||
|
PyTuple_SetItem(tup, 0, PyLong_FromLong(hypo->bind_type == PGF_BIND_TYPE_EXPLICIT ? 0 : 1)); // TODO
|
||||||
|
PyTuple_SetItem(tup, 1, PyString_FromStringAndSize(hypo->cid->text, hypo->cid->size));
|
||||||
|
PyTuple_SetItem(tup, 2, (PyObject *)hypo->type);
|
||||||
|
Py_INCREF(hypo->type);
|
||||||
|
PyList_Append(pytype->hypos, tup);
|
||||||
|
}
|
||||||
|
|
||||||
|
pytype->cat = PyString_FromStringAndSize(cat->text, cat->size);
|
||||||
|
|
||||||
|
pytype->exprs = PyList_New(0);
|
||||||
return (PgfType) pytype;
|
return (PgfType) pytype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,33 +3,10 @@
|
|||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
#include <pgf/pgf.h>
|
#include <pgf/pgf.h>
|
||||||
|
#include "./compat.h"
|
||||||
#include "./expr.h"
|
#include "./expr.h"
|
||||||
#include "./marshaller.h"
|
#include "./marshaller.h"
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
#define PyIntObject PyLongObject
|
|
||||||
#define PyInt_Type PyLong_Type
|
|
||||||
#define PyInt_Check(op) PyLong_Check(op)
|
|
||||||
#define PyInt_CheckExact(op) PyLong_CheckExact(op)
|
|
||||||
#define PyInt_FromString PyLong_FromString
|
|
||||||
#define PyInt_FromUnicode PyLong_FromUnicode
|
|
||||||
#define PyInt_FromLong PyLong_FromLong
|
|
||||||
#define PyInt_FromSize_t PyLong_FromSize_t
|
|
||||||
#define PyInt_FromSsize_t PyLong_FromSsize_t
|
|
||||||
#define PyInt_AsLong PyLong_AsLong
|
|
||||||
#define PyInt_AS_LONG PyLong_AS_LONG
|
|
||||||
#define PyInt_AsSsize_t PyLong_AsSsize_t
|
|
||||||
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
|
|
||||||
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
#define PyString_Check PyUnicode_Check
|
|
||||||
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
|
||||||
#define PyString_FromFormat PyUnicode_FromFormat
|
|
||||||
#define PyString_Concat(ps,s) {PyObject* tmp = *(ps); *(ps) = PyUnicode_Concat(tmp,s); Py_DECREF(tmp);}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static PyObject *PGFError;
|
static PyObject *PGFError;
|
||||||
|
|
||||||
// static PyObject* ParseError;
|
// static PyObject* ParseError;
|
||||||
@@ -1996,19 +1973,11 @@ PGF_functionType(PGFObject* self, PyObject *args)
|
|||||||
funname->size = size;
|
funname->size = size;
|
||||||
|
|
||||||
PgfType type = pgf_function_type(self->pgf, funname, &unmarshaller);
|
PgfType type = pgf_function_type(self->pgf, funname, &unmarshaller);
|
||||||
// if (type == NULL) {
|
if (type == 0) {
|
||||||
// PyErr_Format(PyExc_KeyError, "Function '%s' is not defined", funname->text);
|
PyErr_Format(PyExc_KeyError, "Function '%s' is not defined", funname->text);
|
||||||
// return NULL;
|
return NULL;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// TypeObject* pytype = (TypeObject*) pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
|
|
||||||
// if (pytype == NULL)
|
|
||||||
// return NULL;
|
|
||||||
// // pytype->pool = NULL;
|
|
||||||
// pytype->type = &type;
|
|
||||||
// pytype->master = (PyObject*) self;
|
|
||||||
// Py_XINCREF(self);
|
|
||||||
// return pytype;
|
|
||||||
return (TypeObject *)type;
|
return (TypeObject *)type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2543,15 +2512,6 @@ pgf_readType(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeObject* pytype = (TypeObject*) pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
|
|
||||||
// if (pytype == NULL)
|
|
||||||
// return NULL;
|
|
||||||
// // pytype->pool = NULL;
|
|
||||||
// pytype->type = &type;
|
|
||||||
// pytype->master = (PyObject*) self;
|
|
||||||
// Py_XINCREF(self);
|
|
||||||
// return pytype;
|
|
||||||
|
|
||||||
return (TypeObject *)type;
|
return (TypeObject *)type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ def test_readType_equality_1():
|
|||||||
def test_readType_equality_2():
|
def test_readType_equality_2():
|
||||||
assert pgf.readType("A -> B") == pgf.readType("A->B")
|
assert pgf.readType("A -> B") == pgf.readType("A->B")
|
||||||
|
|
||||||
|
def test_readType_equality_3():
|
||||||
|
assert pgf.readType("A -> B -> C") == pgf.readType("A->B -> C")
|
||||||
|
|
||||||
def test_readType_inequality_1():
|
def test_readType_inequality_1():
|
||||||
assert pgf.readType("A") != pgf.readType("B")
|
assert pgf.readType("A") != pgf.readType("B")
|
||||||
|
|
||||||
@@ -109,6 +112,13 @@ def test_functionType_2(PGF):
|
|||||||
def test_functionType_3(PGF):
|
def test_functionType_3(PGF):
|
||||||
assert PGF.functionType("c") == pgf.readType("N -> S")
|
assert PGF.functionType("c") == pgf.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")
|
||||||
|
|
||||||
def test_startCat(PGF):
|
def test_startCat(PGF):
|
||||||
with pytest.raises(pgf.PGFError):
|
with pytest.raises(pgf.PGFError):
|
||||||
PGF.startCat()
|
PGF.startCat()
|
||||||
|
|||||||
Reference in New Issue
Block a user