diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index 7d6229296..f3a52446a 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -6,6 +6,126 @@ #include "./expr.h" #include "./marshaller.h" +// ---------------------------------------------------------------------------- + +static PyObject * +Type_str(TypeObject *self) +{ + PgfText *s = pgf_print_type((PgfType) self, NULL, 0, &marshaller); + PyObject *str = PyUnicode_FromStringAndSize(s->text, s->size); + free(s); + return str; +} + +// static +PyObject * +Type_richcompare(TypeObject *t1, TypeObject *t2, int op) +{ + bool same = false; + if (PyUnicode_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 (PyUnicode_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 = (ExprObject *)PyList_GetItem(t1->exprs, n); + ExprObject *e2 = (ExprObject *)PyList_GetItem(t2->exprs, n); + if (Expr_richcompare(e1, e2, Py_EQ) != Py_True) goto done; + } + + 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 PyMethodDef Type_methods[] = { +// {"unpack", (PyCFunction)Type_unpack, METH_VARARGS, +// "Decomposes a type into its components" +// }, +// {"__reduce_ex__", (PyCFunction)Type_reduce_ex, METH_VARARGS, +// "This method allows for transparent pickling/unpickling of types." +// }, + {NULL} /* Sentinel */ +}; + +static PyGetSetDef Type_getseters[] = { +// {"hypos", +// (getter)Type_getHypos, NULL, +// "this is the list of hypotheses in the type signature", +// NULL}, +// {"cat", +// (getter)Type_getCat, NULL, +// "this is the name of the category", +// NULL}, +// {"exprs", +// (getter)Type_getExprs, NULL, +// "this is the list of indices for the category", +// NULL}, + {NULL} /* Sentinel */ +}; + +/* static */ +PyTypeObject pgf_TypeType = { + PyVarObject_HEAD_INIT(NULL, 0) + //0, /*ob_size*/ + "pgf.Type", /*tp_name*/ + sizeof(TypeObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, //(destructor) Type_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, /*tp_hash */ + 0, /*tp_call*/ + (reprfunc) Type_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "abstract syntax type", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + (richcmpfunc) Type_richcompare, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + Type_methods, /*tp_methods */ + 0, /*tp_members */ + Type_getseters, /*tp_getset */ + 0, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + 0, //(initproc) Type_init, /*tp_init */ + 0, /*tp_alloc */ + 0, //(newfunc) Type_new, /*tp_new */ +}; + +// ---------------------------------------------------------------------------- + static PyObject * Expr_str(ExprObject *self) { @@ -15,25 +135,26 @@ Expr_str(ExprObject *self) return str; } -// static PyObject * -// Expr_richcompare(ExprObject *e1, ExprObject *e2, 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 +PyObject * +Expr_richcompare(ExprObject *e1, ExprObject *e2, 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 PyMethodDef Expr_methods[] = { // {"unpack", (PyCFunction)Expr_unpack, METH_VARARGS, @@ -106,7 +227,7 @@ PyTypeObject pgf_ExprType = { "abstract syntax tree", /*tp_doc*/ 0, /*tp_traverse */ 0, /*tp_clear */ - 0, //(richcmpfunc) Expr_richcompare, /*tp_richcompare */ + (richcmpfunc) Expr_richcompare, /*tp_richcompare */ 0, /*tp_weaklistoffset */ 0, /*tp_iter */ 0, /*tp_iternext */ @@ -125,29 +246,35 @@ PyTypeObject pgf_ExprType = { // ---------------------------------------------------------------------------- -static ExprFunObject * -ExprFun_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +static ExprAbsObject * +ExprAbs_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { - ExprFunObject* self = (ExprFunObject *)subtype->tp_alloc(subtype, 0); + ExprAbsObject* self = (ExprAbsObject *)subtype->tp_alloc(subtype, 0); return self; } static int -ExprFun_init(ExprFunObject *self, PyObject *args, PyObject *kwds) +ExprAbs_init(ExprAbsObject *self, PyObject *args, PyObject *kwds) { - PyObject* lit = NULL; - if (!PyArg_ParseTuple(args, "U", &lit)) { + PyObject* bindType = NULL; + PyObject* var = NULL; + ExprObject* expr = NULL; + if (!PyArg_ParseTuple(args, "O!UO!", &PyLong_Type, &bindType, &var, &pgf_ExprType, &expr)) { return -1; } - self->name = lit; + self->bindType = bindType; + self->var = var; + self->expr = expr; return 0; } static PyObject * -ExprFun_richcompare(ExprFunObject *t1, ExprFunObject *t2, int op) +ExprAbs_richcompare(ExprAbsObject *e1, ExprAbsObject *e2, int op) { bool same = false; - if (PyUnicode_Compare(t1->name, t2->name) != 0) goto done; + if (PyObject_RichCompare(e1->bindType, e2->bindType, Py_EQ) != Py_True) goto done; + if (PyUnicode_Compare(e1->var, e2->var) != 0) goto done; + if (Expr_richcompare(e1->expr, e2->expr, Py_EQ) != Py_True) goto done; same = true; done: @@ -163,11 +290,11 @@ done: } /* static */ -PyTypeObject pgf_ExprFunType = { +PyTypeObject pgf_ExprAbsType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ - "pgf.ExprFun", /*tp_name*/ - sizeof(ExprFunObject), /*tp_basicsize*/ + "pgf.ExprAbs", /*tp_name*/ + sizeof(ExprAbsObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, //(destructor)Expr_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ @@ -185,10 +312,10 @@ PyTypeObject pgf_ExprFunType = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "function or data constructor", /*tp_doc*/ + "lambda abstraction", /*tp_doc*/ 0, /*tp_traverse */ 0, /*tp_clear */ - (richcmpfunc) ExprFun_richcompare, /*tp_richcompare */ + (richcmpfunc) ExprAbs_richcompare, /*tp_richcompare */ 0, /*tp_weaklistoffset */ 0, /*tp_iter */ 0, /*tp_iternext */ @@ -200,9 +327,9 @@ PyTypeObject pgf_ExprFunType = { 0, /*tp_descr_get */ 0, /*tp_descr_set */ 0, /*tp_dictoffset */ - (initproc) ExprFun_init, /*tp_init */ + (initproc) ExprAbs_init, /*tp_init */ 0, /*tp_alloc */ - (newfunc) ExprFun_new, /*tp_new */ + (newfunc) ExprAbs_new, /*tp_new */ }; // ---------------------------------------------------------------------------- @@ -229,14 +356,14 @@ ExprApp_init(ExprAppObject *self, PyObject *args, PyObject *kwds) } static PyObject * -ExprApp_richcompare(ExprAppObject *t1, ExprAppObject *t2, int op) +ExprApp_richcompare(ExprAppObject *e1, ExprAppObject *e2, int op) { bool same = false; - - // TODO + if (Expr_richcompare(e1->e1, e2->e1, Py_EQ) != Py_True) goto done; + if (Expr_richcompare(e1->e2, e2->e2, Py_EQ) != Py_True) goto done; same = true; -// done: +done: if (op == Py_EQ) { if (same) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -317,21 +444,21 @@ ExprLit_init(ExprLitObject *self, PyObject *args, PyObject *kwds) } static PyObject * -ExprLit_richcompare(ExprLitObject *t1, ExprLitObject *t2, int op) +ExprLit_richcompare(ExprLitObject *e1, ExprLitObject *e2, int op) { bool same = false; - if (PyLong_Check(t1->value)) { - if (!PyLong_Check(t2->value)) goto done; + if (PyLong_Check(e1->value)) { + if (!PyLong_Check(e2->value)) goto done; int o1, o2; - int l1 = PyLong_AsLongAndOverflow(t1->value, &o1); - int l2 = PyLong_AsLongAndOverflow(t2->value, &o2); + int l1 = PyLong_AsLongAndOverflow(e1->value, &o1); + int l2 = PyLong_AsLongAndOverflow(e2->value, &o2); if (!(l1 == l2 && o1 == o2)) goto done; - } else if (PyFloat_Check(t1->value)) { - if (!PyFloat_Check(t2->value)) goto done; - if (PyFloat_AsDouble(t1->value) != PyFloat_AsDouble(t2->value)) goto done; - } else if (PyUnicode_Check(t1->value)) { - if (!PyUnicode_Check(t2->value)) goto done; - if (PyUnicode_Compare(t1->value, t2->value) != 0) goto done; + } else if (PyFloat_Check(e1->value)) { + if (!PyFloat_Check(e2->value)) goto done; + if (PyFloat_AsDouble(e1->value) != PyFloat_AsDouble(e2->value)) goto done; + } else if (PyUnicode_Check(e1->value)) { + if (!PyUnicode_Check(e2->value)) goto done; + if (PyUnicode_Compare(e1->value, e2->value) != 0) goto done; } else { PyErr_SetString(PyExc_TypeError, "unknown literal type"); return NULL; @@ -422,10 +549,10 @@ ExprMeta_init(ExprMetaObject *self, PyObject *args, PyObject *kwds) } static PyObject * -ExprMeta_richcompare(ExprMetaObject *t1, ExprMetaObject *t2, int op) +ExprMeta_richcompare(ExprMetaObject *e1, ExprMetaObject *e2, int op) { bool same = false; - if (PyObject_RichCompareBool(t1->id, t2->id, Py_EQ) != 1) goto done; + if (PyObject_RichCompare(e1->id, e2->id, Py_EQ) != Py_True) goto done; same = true; done: @@ -485,6 +612,88 @@ PyTypeObject pgf_ExprMetaType = { // ---------------------------------------------------------------------------- +static ExprFunObject * +ExprFun_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + ExprFunObject* self = (ExprFunObject *)subtype->tp_alloc(subtype, 0); + return self; +} + +static int +ExprFun_init(ExprFunObject *self, PyObject *args, PyObject *kwds) +{ + PyObject* lit = NULL; + if (!PyArg_ParseTuple(args, "U", &lit)) { + return -1; + } + self->name = lit; + return 0; +} + +static PyObject * +ExprFun_richcompare(ExprFunObject *e1, ExprFunObject *e2, int op) +{ + bool same = false; + if (PyUnicode_Compare(e1->name, e2->name) != 0) goto done; + + 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_ExprFunType = { + PyVarObject_HEAD_INIT(NULL, 0) + //0, /*ob_size*/ + "pgf.ExprFun", /*tp_name*/ + sizeof(ExprFunObject), /*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*/ + "function or data constructor", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + (richcmpfunc) ExprFun_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) ExprFun_init, /*tp_init */ + 0, /*tp_alloc */ + (newfunc) ExprFun_new, /*tp_new */ +}; + +// ---------------------------------------------------------------------------- + static ExprVarObject * ExprVar_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { @@ -512,10 +721,10 @@ ExprVar_init(ExprVarObject *self, PyObject *args, PyObject *kwds) } static PyObject * -ExprVar_richcompare(ExprVarObject *t1, ExprVarObject *t2, int op) +ExprVar_richcompare(ExprVarObject *e1, ExprVarObject *e2, int op) { bool same = false; - if (PyObject_RichCompareBool(t1->index, t2->index, Py_EQ) != 1) goto done; + if (PyObject_RichCompare(e1->index, e2->index, Py_EQ) != Py_True) goto done; same = true; done: @@ -575,38 +784,32 @@ PyTypeObject pgf_ExprVarType = { // ---------------------------------------------------------------------------- -static PyObject * -Type_str(TypeObject *self) +static ExprTypedObject * +ExprTyped_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { - PgfText *s = pgf_print_type((PgfType) self, NULL, 0, &marshaller); - PyObject *str = PyUnicode_FromStringAndSize(s->text, s->size); - free(s); - return str; + ExprTypedObject* self = (ExprTypedObject *)subtype->tp_alloc(subtype, 0); + return self; +} + +static int +ExprTyped_init(ExprTypedObject *self, PyObject *args, PyObject *kwds) +{ + ExprObject* expr; + TypeObject* type; + if (!PyArg_ParseTuple(args, "O!O!", &pgf_ExprType, &expr, &pgf_TypeType, &type)) { + return -1; + } + self->expr = expr; + self->type = type; + return 0; } static PyObject * -Type_richcompare(TypeObject *t1, TypeObject *t2, int op) +ExprTyped_richcompare(ExprTypedObject *e1, ExprTypedObject *e2, int op) { bool same = false; - if (PyUnicode_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 (PyUnicode_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 - // } + if (Expr_richcompare(e1->expr, e2->expr, Py_EQ) != Py_True) goto done; + if (Type_richcompare(e1->type, e2->type, Py_EQ) != Py_True) goto done; same = true; done: @@ -621,40 +824,14 @@ done: } } -static PyMethodDef Type_methods[] = { -// {"unpack", (PyCFunction)Type_unpack, METH_VARARGS, -// "Decomposes a type into its components" -// }, -// {"__reduce_ex__", (PyCFunction)Type_reduce_ex, METH_VARARGS, -// "This method allows for transparent pickling/unpickling of types." -// }, - {NULL} /* Sentinel */ -}; - -static PyGetSetDef Type_getseters[] = { -// {"hypos", -// (getter)Type_getHypos, NULL, -// "this is the list of hypotheses in the type signature", -// NULL}, -// {"cat", -// (getter)Type_getCat, NULL, -// "this is the name of the category", -// NULL}, -// {"exprs", -// (getter)Type_getExprs, NULL, -// "this is the list of indices for the category", -// NULL}, - {NULL} /* Sentinel */ -}; - /* static */ -PyTypeObject pgf_TypeType = { +PyTypeObject pgf_ExprTypedType = { PyVarObject_HEAD_INIT(NULL, 0) //0, /*ob_size*/ - "pgf.Type", /*tp_name*/ - sizeof(TypeObject), /*tp_basicsize*/ + "pgf.ExprTyped", /*tp_name*/ + sizeof(ExprTypedObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - 0, //(destructor) Type_dealloc, /*tp_dealloc*/ + 0, //(destructor)Expr_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -663,29 +840,111 @@ PyTypeObject pgf_TypeType = { 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - (reprfunc) Type_str, /*tp_str*/ - 0, /*tp_getattro*/ + 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*/ - "abstract syntax type", /*tp_doc*/ - 0, /*tp_traverse */ - 0, /*tp_clear */ - (richcmpfunc) Type_richcompare, /*tp_richcompare */ - 0, /*tp_weaklistoffset */ - 0, /*tp_iter */ - 0, /*tp_iternext */ - Type_methods, /*tp_methods */ + "expression with local type signature", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + (richcmpfunc) ExprTyped_richcompare, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + 0, //Expr_methods, /*tp_methods */ 0, /*tp_members */ - Type_getseters, /*tp_getset */ - 0, /*tp_base */ + 0, //Expr_getseters, /*tp_getset */ + &pgf_ExprType, /*tp_base */ 0, /*tp_dict */ 0, /*tp_descr_get */ 0, /*tp_descr_set */ 0, /*tp_dictoffset */ - 0, //(initproc) Type_init, /*tp_init */ + (initproc) ExprTyped_init, /*tp_init */ 0, /*tp_alloc */ - 0, //(newfunc) Type_new, /*tp_new */ + (newfunc) ExprTyped_new, /*tp_new */ +}; + +// ---------------------------------------------------------------------------- + +static ExprImplArgObject * +ExprImplArg_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + ExprImplArgObject* self = (ExprImplArgObject *)subtype->tp_alloc(subtype, 0); + return self; +} + +static int +ExprImplArg_init(ExprImplArgObject *self, PyObject *args, PyObject *kwds) +{ + ExprObject* expr; + if (!PyArg_ParseTuple(args, "O!", &pgf_ExprType, &expr)) { + return -1; + } + self->expr = expr; + return 0; +} + +static PyObject * +ExprImplArg_richcompare(ExprImplArgObject *e1, ExprImplArgObject *e2, int op) +{ + bool same = false; + if (Expr_richcompare(e1->expr, e2->expr, Py_EQ) != Py_True) goto done; + + 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_ExprImplArgType = { + PyVarObject_HEAD_INIT(NULL, 0) + //0, /*ob_size*/ + "pgf.ExprImplArg", /*tp_name*/ + sizeof(ExprImplArgObject), /*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*/ + "implicit argument in expression", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + (richcmpfunc) ExprImplArg_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) ExprImplArg_init, /*tp_init */ + 0, /*tp_alloc */ + (newfunc) ExprImplArg_new, /*tp_new */ }; diff --git a/src/runtime/python/expr.h b/src/runtime/python/expr.h index 04576a0a1..e062516b1 100644 --- a/src/runtime/python/expr.h +++ b/src/runtime/python/expr.h @@ -23,8 +23,10 @@ typedef struct { typedef struct { PyObject_HEAD - PyObject *name; // PyUnicodeObject -} ExprFunObject; + PyObject *bindType; // PyLongObject + PyObject *var; // PyUnicodeObject + ExprObject *expr; +} ExprAbsObject; typedef struct { PyObject_HEAD @@ -42,21 +44,35 @@ typedef struct { PyObject *id; // PyLongObject } ExprMetaObject; +typedef struct { + PyObject_HEAD + PyObject *name; // PyUnicodeObject +} ExprFunObject; + typedef struct { PyObject_HEAD PyObject *index; // PyLongObject } ExprVarObject; +typedef struct { + PyObject_HEAD + ExprObject *expr; + TypeObject *type; +} ExprTypedObject; + +typedef struct { + PyObject_HEAD + ExprObject *expr; +} ExprImplArgObject; + extern PyTypeObject pgf_ExprType; - -extern PyTypeObject pgf_ExprFunType; - +extern PyTypeObject pgf_ExprAbsType; extern PyTypeObject pgf_ExprAppType; - extern PyTypeObject pgf_ExprLitType; - extern PyTypeObject pgf_ExprMetaType; - +extern PyTypeObject pgf_ExprFunType; extern PyTypeObject pgf_ExprVarType; +extern PyTypeObject pgf_ExprTypedType; +extern PyTypeObject pgf_ExprImplArgType; #endif // PYPGF_EXPR_H_ diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/marshaller.c index 7dcb4bd63..4d847bf45 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/marshaller.c @@ -45,8 +45,12 @@ PyUnicode_FromPgfText(PgfText *text) PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body) { - PyErr_SetString(PyExc_NotImplementedError, "eabs not implemented"); - return 0; + ExprAbsObject *pyexpr = (ExprAbsObject *)pgf_ExprAbsType.tp_alloc(&pgf_ExprAbsType, 0); + pyexpr->bindType = PyLong_FromLong(btype); + pyexpr->var = PyUnicode_FromPgfText(name); + pyexpr->expr = (ExprObject *)body; + // Py_INCREF(body); + return (PgfExpr) pyexpr; } PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg) @@ -93,14 +97,20 @@ PgfExpr evar(PgfUnmarshaller *this, int index) PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ) { - PyErr_SetString(PyExc_NotImplementedError, "etyped not implemented"); - return 0; + ExprTypedObject *pyexpr = (ExprTypedObject *)pgf_ExprTypedType.tp_alloc(&pgf_ExprTypedType, 0); + pyexpr->expr = (ExprObject *)expr; + pyexpr->type = (TypeObject *)typ; + // Py_INCREF(expr); + // Py_INCREF(typ); + return (PgfExpr) pyexpr; } PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr) { - PyErr_SetString(PyExc_NotImplementedError, "eimplarg not implemented"); - return 0; + ExprImplArgObject *pyexpr = (ExprImplArgObject *)pgf_ExprImplArgType.tp_alloc(&pgf_ExprImplArgType, 0); + pyexpr->expr = (ExprObject *)expr; + // Py_INCREF(expr); + return (PgfExpr) pyexpr; } PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v) @@ -241,13 +251,13 @@ 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)); + if (PyObject_TypeCheck(pyobj, &pgf_ExprAbsType)) { + ExprAbsObject *eabs = (ExprAbsObject *)expr; + return u->vtbl->eabs(u, PyLong_AsLong(eabs->bindType), PyUnicode_AsPgfText(eabs->var), (PgfExpr) eabs->expr); } else if (PyObject_TypeCheck(pyobj, &pgf_ExprAppType)) { ExprAppObject *eapp = (ExprAppObject *)expr; - return u->vtbl->eapp(u, (PgfExpr) eapp->e1, (PgfExpr) eapp->e2); // TODO check + return u->vtbl->eapp(u, (PgfExpr) eapp->e1, (PgfExpr) eapp->e2); } else if (PyObject_TypeCheck(pyobj, &pgf_ExprLitType)) { ExprLitObject *elit = (ExprLitObject *)expr; @@ -257,9 +267,21 @@ object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr) ExprMetaObject *emeta = (ExprMetaObject *)expr; return u->vtbl->emeta(u, (PgfMetaId) PyLong_AsLong(emeta->id)); } else + 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_ExprVarType)) { ExprVarObject *evar = (ExprVarObject *)expr; return u->vtbl->evar(u, PyLong_AsLong(evar->index)); + } else + if (PyObject_TypeCheck(pyobj, &pgf_ExprTypedType)) { + ExprTypedObject *etyped = (ExprTypedObject *)expr; + return u->vtbl->etyped(u, (PgfExpr) etyped->expr, (PgfType) etyped->type); + } else + if (PyObject_TypeCheck(pyobj, &pgf_ExprImplArgType)) { + ExprImplArgObject *eimplarg = (ExprImplArgObject *)expr; + return u->vtbl->eimplarg(u, (PgfExpr) eimplarg->expr); } else { PyErr_SetString(PyExc_TypeError, "unable to match on expression"); return 0; diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 335d7fc1a..bbba72906 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -2666,7 +2666,7 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_ExprType) < 0) return MOD_ERROR_VAL; - if (PyType_Ready(&pgf_ExprFunType) < 0) + if (PyType_Ready(&pgf_ExprAbsType) < 0) return MOD_ERROR_VAL; if (PyType_Ready(&pgf_ExprAppType) < 0) @@ -2678,9 +2678,18 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_ExprMetaType) < 0) return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_ExprFunType) < 0) + return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_ExprVarType) < 0) return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_ExprTypedType) < 0) + return MOD_ERROR_VAL; + + if (PyType_Ready(&pgf_ExprImplArgType) < 0) + return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_TypeType) < 0) return MOD_ERROR_VAL; @@ -2709,8 +2718,8 @@ MOD_INIT(pgf) PyModule_AddObject(m, "Expr", (PyObject *) &pgf_ExprType); Py_INCREF(&pgf_ExprType); - PyModule_AddObject(m, "ExprFun", (PyObject *) &pgf_ExprFunType); - Py_INCREF(&pgf_ExprFunType); + PyModule_AddObject(m, "ExprAbs", (PyObject *) &pgf_ExprAbsType); + Py_INCREF(&pgf_ExprAbsType); PyModule_AddObject(m, "ExprApp", (PyObject *) &pgf_ExprAppType); Py_INCREF(&pgf_ExprAppType); @@ -2721,9 +2730,18 @@ MOD_INIT(pgf) PyModule_AddObject(m, "ExprMeta", (PyObject *) &pgf_ExprMetaType); Py_INCREF(&pgf_ExprMetaType); + PyModule_AddObject(m, "ExprFun", (PyObject *) &pgf_ExprFunType); + Py_INCREF(&pgf_ExprFunType); + PyModule_AddObject(m, "ExprVar", (PyObject *) &pgf_ExprVarType); Py_INCREF(&pgf_ExprVarType); + PyModule_AddObject(m, "ExprTyped", (PyObject *) &pgf_ExprTypedType); + Py_INCREF(&pgf_ExprTypedType); + + PyModule_AddObject(m, "ExprImplArg", (PyObject *) &pgf_ExprImplArgType); + Py_INCREF(&pgf_ExprImplArgType); + PyModule_AddObject(m, "Type", (PyObject *) &pgf_TypeType); Py_INCREF(&pgf_TypeType); diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/test_suite.py index 0e47ceae4..eb27e6490 100644 --- a/src/runtime/python/test_suite.py +++ b/src/runtime/python/test_suite.py @@ -220,24 +220,39 @@ def test_readExpr_efun_equality_1(): assert pgf.readExpr("f") == pgf.ExprFun("f") def test_readExpr_efun_equality_2(): - assert pgf.readExpr("f x y") == pgf.ExprApp( + assert \ + pgf.readExpr("f x y") == \ pgf.ExprApp( - pgf.ExprFun("f"), - pgf.ExprFun("x") - ), - pgf.ExprFun("y") - ) + 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"), + assert \ + pgf.readExpr("f (g x)") == \ pgf.ExprApp( - pgf.ExprFun("g"), - pgf.ExprFun("x") + 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")))))) +def test_readExpr_efun_equality_4(): + assert \ + pgf.readExpr("f {g x}") == \ + pgf.ExprApp( + pgf.ExprFun("f"), + pgf.ExprImplArg( + pgf.ExprApp( + pgf.ExprFun("g"), + pgf.ExprFun("x") + ) + ) + ) # expressions: variables @@ -294,4 +309,10 @@ def test_readExpr_emeta_str_2(): # expressions: typed expressions +def test_readExpr_emeta_equality(): + assert pgf.readExpr("") == pgf.ExprTyped(pgf.ExprFun("z"), pgf.readType("N")) + +def test_readExpr_emeta_str(): + assert str(pgf.readExpr("")) == "" + # ,TestCase (assertEqual "show expression 18" "" (showExpr [] (ETyped (EFun "z") (DTyp [] "N" []))))