Add ExprApp to Python bindings

This commit is contained in:
John J. Camilleri
2021-09-14 15:28:39 +02:00
parent 6ebb8e5fda
commit fd61a6c0d3
5 changed files with 140 additions and 10 deletions

View File

@@ -139,7 +139,7 @@ ExprFun_init(ExprFunObject *self, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTuple(args, "U", &lit)) {
return -1;
}
self->fun = lit;
self->name = lit;
return 0;
}
@@ -147,7 +147,7 @@ static PyObject *
ExprFun_richcompare(ExprFunObject *t1, ExprFunObject *t2, int op)
{
bool same = false;
if (PyUnicode_Compare(t1->fun, t2->fun) != 0) goto done;
if (PyUnicode_Compare(t1->name, t2->name) != 0) goto done;
same = true;
done:
@@ -207,6 +207,92 @@ PyTypeObject pgf_ExprFunType = {
// ----------------------------------------------------------------------------
static ExprAppObject *
ExprApp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
ExprAppObject* self = (ExprAppObject *)subtype->tp_alloc(subtype, 0);
return self;
}
static int
ExprApp_init(ExprAppObject *self, PyObject *args, PyObject *kwds)
{
PyObject* e1 = NULL;
PyObject* e2 = NULL;
if (!PyArg_ParseTuple(args, "O!O!", &pgf_ExprType, &e1, &pgf_ExprType, &e2)) {
return -1;
}
self->e1 = (ExprObject *)e1;
self->e2 = (ExprObject *)e2;
return 0;
}
static PyObject *
ExprApp_richcompare(ExprAppObject *t1, ExprAppObject *t2, int op)
{
bool same = false;
// TODO
same = true;
// done:
if (op == Py_EQ) {
if (same) Py_RETURN_TRUE; else Py_RETURN_FALSE;
} else if (op == Py_NE) {
if (same) Py_RETURN_FALSE; else Py_RETURN_TRUE;
} else {
PyErr_SetString(PyExc_TypeError, "comparison operation not supported");
Py_RETURN_NOTIMPLEMENTED;
}
}
/* static */
PyTypeObject pgf_ExprAppType = {
PyVarObject_HEAD_INIT(NULL, 0)
//0, /*ob_size*/
"pgf.ExprApp", /*tp_name*/
sizeof(ExprAppObject), /*tp_basicsize*/
0, /*tp_itemsize*/
0, //(destructor)Expr_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, //(hashfunc) Expr_hash, /*tp_hash */
0, //(ternaryfunc) Expr_call, /*tp_call*/
0, //(reprfunc) Expr_str, /*tp_str*/
0, //(getattrofunc) Expr_getattro,/*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"application", /*tp_doc*/
0, /*tp_traverse */
0, /*tp_clear */
(richcmpfunc) ExprApp_richcompare, /*tp_richcompare */
0, /*tp_weaklistoffset */
0, /*tp_iter */
0, /*tp_iternext */
0, //Expr_methods, /*tp_methods */
0, /*tp_members */
0, //Expr_getseters, /*tp_getset */
&pgf_ExprType, /*tp_base */
0, /*tp_dict */
0, /*tp_descr_get */
0, /*tp_descr_set */
0, /*tp_dictoffset */
(initproc) ExprApp_init, /*tp_init */
0, /*tp_alloc */
(newfunc) ExprApp_new, /*tp_new */
};
// ----------------------------------------------------------------------------
static ExprLitObject *
ExprLit_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{

View File

@@ -23,9 +23,15 @@ typedef struct {
typedef struct {
PyObject_HEAD
PyObject *fun; // PyUnicodeObject
PyObject *name; // PyUnicodeObject
} ExprFunObject;
typedef struct {
PyObject_HEAD
ExprObject *e1; // ExprObject
ExprObject *e2; // ExprObject
} ExprAppObject;
typedef struct {
PyObject_HEAD
PyObject *value; // PyLongObject | PyFloatObject | PyUnicodeObject
@@ -45,6 +51,8 @@ extern PyTypeObject pgf_ExprType;
extern PyTypeObject pgf_ExprFunType;
extern PyTypeObject pgf_ExprAppType;
extern PyTypeObject pgf_ExprLitType;
extern PyTypeObject pgf_ExprMetaType;

View File

@@ -51,8 +51,12 @@ PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr bo
PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg)
{
PyErr_SetString(PyExc_NotImplementedError, "eapp not implemented");
return 0;
ExprAppObject *pyexpr = (ExprAppObject *)pgf_ExprAppType.tp_alloc(&pgf_ExprAppType, 0);
pyexpr->e1 = (ExprObject *)fun;
pyexpr->e2 = (ExprObject *)arg;
// Py_INCREF(fun);
// Py_INCREF(arg);
return (PgfExpr) pyexpr;
}
PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit)
@@ -75,7 +79,7 @@ PgfExpr efun(PgfUnmarshaller *this, PgfText *name)
{
ExprFunObject *pyexpr = (ExprFunObject *)pgf_ExprFunType.tp_alloc(&pgf_ExprFunType, 0);
PyObject *pyobj = PyUnicode_FromPgfText(name);
pyexpr->fun = pyobj;
pyexpr->name = pyobj;
Py_INCREF(pyobj);
return (PgfExpr) pyexpr;
}
@@ -237,13 +241,23 @@ object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr)
{
PyObject *pyobj = (PyObject *)expr;
if (PyObject_TypeCheck(pyobj, &pgf_ExprFunType)) {
ExprFunObject *efun = (ExprFunObject *)expr;
return u->vtbl->efun(u, PyUnicode_AsPgfText(efun->name));
} else
if (PyObject_TypeCheck(pyobj, &pgf_ExprAppType)) {
ExprAppObject *eapp = (ExprAppObject *)expr;
return u->vtbl->eapp(u, (PgfExpr) eapp->e1, (PgfExpr) eapp->e2); // TODO check
} else
if (PyObject_TypeCheck(pyobj, &pgf_ExprLitType)) {
ExprLitObject *elit = (ExprLitObject *)expr;
return this->vtbl->match_lit(this, u, (PgfLiteral) elit->value);
} else if (PyObject_TypeCheck(pyobj, &pgf_ExprMetaType)) {
} else
if (PyObject_TypeCheck(pyobj, &pgf_ExprMetaType)) {
ExprMetaObject *emeta = (ExprMetaObject *)expr;
return u->vtbl->emeta(u, (PgfMetaId) PyLong_AsLong(emeta->id));
} else if (PyObject_TypeCheck(pyobj, &pgf_ExprVarType)) {
} else
if (PyObject_TypeCheck(pyobj, &pgf_ExprVarType)) {
ExprVarObject *evar = (ExprVarObject *)expr;
return u->vtbl->evar(u, PyLong_AsLong(evar->index));
} else {

View File

@@ -2669,6 +2669,9 @@ MOD_INIT(pgf)
if (PyType_Ready(&pgf_ExprFunType) < 0)
return MOD_ERROR_VAL;
if (PyType_Ready(&pgf_ExprAppType) < 0)
return MOD_ERROR_VAL;
if (PyType_Ready(&pgf_ExprLitType) < 0)
return MOD_ERROR_VAL;
@@ -2709,6 +2712,9 @@ MOD_INIT(pgf)
PyModule_AddObject(m, "ExprFun", (PyObject *) &pgf_ExprFunType);
Py_INCREF(&pgf_ExprFunType);
PyModule_AddObject(m, "ExprApp", (PyObject *) &pgf_ExprAppType);
Py_INCREF(&pgf_ExprAppType);
PyModule_AddObject(m, "ExprLit", (PyObject *) &pgf_ExprLitType);
Py_INCREF(&pgf_ExprLitType);

View File

@@ -219,8 +219,24 @@ def test_readExpr_lstr_str():
def test_readExpr_efun_equality_1():
assert pgf.readExpr("f") == pgf.ExprFun("f")
# ,TestCase (assertEqual "show expression 1" "f x y" (showExpr [] (EApp (EApp (EFun "f") (EFun "x")) (EFun "y"))))
# ,TestCase (assertEqual "show expression 2" "f (g x)" (showExpr [] (EApp (EFun "f") (EApp (EFun "g") (EFun "x")))))
def test_readExpr_efun_equality_2():
assert pgf.readExpr("f x y") == pgf.ExprApp(
pgf.ExprApp(
pgf.ExprFun("f"),
pgf.ExprFun("x")
),
pgf.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")
)
)
# ,TestCase (assertEqual "show expression 3" "f {g x}" (showExpr [] (EApp (EFun "f") (EImplArg (EApp (EFun "g") (EFun "x"))))))
# expressions: variables