diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index 889d85d2c..7d6229296 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -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) { diff --git a/src/runtime/python/expr.h b/src/runtime/python/expr.h index b1bab6940..04576a0a1 100644 --- a/src/runtime/python/expr.h +++ b/src/runtime/python/expr.h @@ -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; diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/marshaller.c index fa183bd2f..7dcb4bd63 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/marshaller.c @@ -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 { diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 9126e9ad5..335d7fc1a 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -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); diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/test_suite.py index dab835551..0e47ceae4 100644 --- a/src/runtime/python/test_suite.py +++ b/src/runtime/python/test_suite.py @@ -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