1
0
forked from GitHub/gf-core
Files
gf-core/src/runtime/python/expr.c

1088 lines
34 KiB
C

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stdbool.h>
#include "./expr.h"
// static ExprObject*
// Expr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// {
// ExprObject* self = (ExprObject *)type->tp_alloc(type, 0);
// if (self != NULL) {
// self->master = NULL;
// self->pool = NULL;
// self->expr = gu_null_variant;
// }
//
// return self;
// }
//
// static void
// Expr_dealloc(ExprObject* 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 PyObject*
// Expr_getattro(ExprObject *self, PyObject *attr_name);
//
// static int
// Expr_initMeta(ExprObject *self);
//
// static int
// Expr_initLiteral(ExprObject *self, PyObject *lit);
//
// static int
// Expr_initApp(ExprObject *self, const char* fname, PyObject *args);
//
// static ExprObject*
// Expr_call(ExprObject* e, PyObject* args, PyObject* kw);
//
// static PyObject*
// Expr_unpack(ExprObject* self, PyObject *args);
//
// static PyObject*
// Expr_visit(ExprObject* self, PyObject *args);
//
// static PyObject*
// Expr_reduce_ex(ExprObject* self, PyObject *args);
//
// static int
// Expr_init(ExprObject *self, PyObject *args, PyObject *kwds)
// {
// Py_ssize_t tuple_size = PyTuple_Size(args);
//
// if (tuple_size == 0) {
// return Expr_initMeta(self);
// } else if (tuple_size == 1) {
// PyObject* lit = NULL;
// if (!PyArg_ParseTuple(args, "O", &lit))
// return -1;
// return Expr_initLiteral(self, lit);
// } else if (tuple_size == 2) {
// const char* fname;
// PyObject* list = NULL;
// if (!PyArg_ParseTuple(args, "sO!", &fname, &PyList_Type, &list))
// return -1;
// return Expr_initApp(self, fname, list);
// } else {
// PyErr_Format(PyExc_TypeError, "function takes 0, 1 or 2 arguments (%d given)", (int) tuple_size);
// return -1;
// }
//
// return 0;
// }
//
// static PyObject *
// Expr_repr(ExprObject *self)
// {
// GuPool* tmp_pool = gu_local_pool();
//
// GuExn* err = gu_exn(tmp_pool);
// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
// GuOut* out = gu_string_buf_out(sbuf);
//
// pgf_print_expr(self->expr, NULL, 0, out, err);
//
// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf),
// gu_string_buf_length(sbuf));
//
// gu_pool_free(tmp_pool);
// return pystr;
// }
//
// static PyObject *
// Expr_richcompare(ExprObject *e1, ExprObject *e2, int op)
// {
// bool cmp = pgf_expr_eq(e1->expr,e2->expr);
//
// if (op == Py_EQ) {
// if (cmp) Py_RETURN_TRUE; else Py_RETURN_FALSE;
// } else if (op == Py_NE) {
// if (cmp) Py_RETURN_FALSE; else Py_RETURN_TRUE;
// } else {
// PyErr_SetString(PyExc_TypeError, "the operation is not supported");
// return NULL;
// }
// }
//
// static long
// Expr_hash(ExprObject *e)
// {
// return (long) pgf_expr_hash(0, e->expr);
// }
//
// static PyMethodDef Expr_methods[] = {
// {"unpack", (PyCFunction)Expr_unpack, METH_VARARGS,
// "Decomposes an expression into its components"
// },
// {"visit", (PyCFunction)Expr_visit, METH_VARARGS,
// "Implementation of the visitor pattern for abstract syntax trees. "
// "If e is an expression equal to f a1 .. an then "
// "e.visit(self) calls method self.on_f(a1,..an). "
// "If the method doesn't exist then the method self.default(e) "
// "is called."
// },
// {"__reduce_ex__", (PyCFunction)Expr_reduce_ex, METH_VARARGS,
// "This method allows for transparent pickling/unpickling of expressions."
// },
// {NULL} /* Sentinel */
// };
//
// static PyGetSetDef Expr_getseters[] = {
// {"fun",
// NULL, NULL,
// "this is the function in a function application",
// NULL},
// {"arg",
// NULL, NULL,
// "this is the argument in a function application",
// NULL},
// {"val",
// NULL, NULL,
// "this is the value of a literal",
// NULL},
// {"id",
// NULL, NULL,
// "this is the id of a meta variable",
// NULL},
// {"name",
// NULL, NULL,
// "this is the name of a function",
// NULL},
// {"index",
// NULL, NULL,
// "this is the de Bruijn index of a variable",
// NULL},
// {NULL} /* Sentinel */
// };
//
// static PyTypeObject pgf_ExprType = {
// PyVarObject_HEAD_INIT(NULL, 0)
// //0, /*ob_size*/
// "pgf.Expr", /*tp_name*/
// sizeof(ExprObject), /*tp_basicsize*/
// 0, /*tp_itemsize*/
// (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*/
// (hashfunc) Expr_hash, /*tp_hash */
// (ternaryfunc) Expr_call, /*tp_call*/
// (reprfunc) Expr_repr, /*tp_str*/
// (getattrofunc) Expr_getattro,/*tp_getattro*/
// 0, /*tp_setattro*/
// 0, /*tp_as_buffer*/
// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
// "abstract syntax tree", /*tp_doc*/
// 0, /*tp_traverse */
// 0, /*tp_clear */
// (richcmpfunc) Expr_richcompare, /*tp_richcompare */
// 0, /*tp_weaklistoffset */
// 0, /*tp_iter */
// 0, /*tp_iternext */
// Expr_methods, /*tp_methods */
// 0, /*tp_members */
// Expr_getseters, /*tp_getset */
// 0, /*tp_base */
// 0, /*tp_dict */
// 0, /*tp_descr_get */
// 0, /*tp_descr_set */
// 0, /*tp_dictoffset */
// (initproc)Expr_init, /*tp_init */
// 0, /*tp_alloc */
// (newfunc) Expr_new, /*tp_new */
// };
//
// static int
// Expr_initMeta(ExprObject *self)
// {
// self->master = NULL;
// self->pool = gu_new_pool();
// PgfExprMeta* e =
// gu_new_variant(PGF_EXPR_META,
// PgfExprMeta,
// &self->expr, self->pool);
// e->id = 0;
// return 0;
// }
//
// static int
// Expr_initLiteral(ExprObject *self, PyObject *lit)
// {
// self->master = NULL;
// self->pool = gu_new_pool();
// PgfExprLit* e =
// gu_new_variant(PGF_EXPR_LIT,
// PgfExprLit,
// &self->expr, self->pool);
// e->lit = gu_null_variant;
//
// if (PyString_Check(lit)) {
// char* s;
// Py_ssize_t len;
//
// #if PY_MAJOR_VERSION >= 3
// PyObject* bytes = PyUnicode_AsUTF8String(lit);
// if (bytes == NULL)
// return -1;
// if (PyBytes_AsStringAndSize(bytes,&s,&len) < 0)
// return -1;
// #else
// if (PyString_AsStringAndSize(lit,&s,&len) < 0)
// return -1;
// #endif
//
// PgfLiteralStr* slit =
// gu_new_flex_variant(PGF_LITERAL_STR,
// PgfLiteralStr,
// val, len+1,
// &e->lit, self->pool);
// memcpy(slit->val, s, len+1);
//
// #if PY_MAJOR_VERSION >= 3
// Py_DECREF(bytes);
// #endif
// } else if (PyInt_Check(lit)) {
// PgfLiteralInt* ilit =
// gu_new_variant(PGF_LITERAL_INT,
// PgfLiteralInt,
// &e->lit, self->pool);
// ilit->val = PyInt_AsLong(lit);
// } else if (PyFloat_Check(lit)) {
// PgfLiteralFlt* flit =
// gu_new_variant(PGF_LITERAL_FLT,
// PgfLiteralFlt,
// &e->lit, self->pool);
// flit->val = PyFloat_AsDouble(lit);
// } else {
// PyErr_SetString(PyExc_TypeError, "the literal must be a string, an integer, or a float");
// return -1;
// }
// return 0;
// }
//
// static int
// Expr_initApp(ExprObject *self, const char* fname, PyObject *args)
// {
// Py_ssize_t n_args = PyList_Size(args);
//
// self->master = PyTuple_New(n_args);
// if (self->master == NULL)
// return -1;
//
// self->pool = gu_new_pool();
// PgfExprFun* e =
// gu_new_flex_variant(PGF_EXPR_FUN,
// PgfExprFun,
// fun, strlen(fname)+1,
// &self->expr, self->pool);
// strcpy(e->fun, fname);
//
// for (Py_ssize_t i = 0; i < n_args; i++) {
// PyObject* obj = PyList_GetItem(args, i);
// if (obj->ob_type != &pgf_ExprType) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the list must be expressions");
// return -1;
// }
//
// PyTuple_SetItem(self->master, i, obj);
// Py_INCREF(obj);
//
// PgfExpr fun = self->expr;
// PgfExpr arg = ((ExprObject*) obj)->expr;
//
// PgfExprApp* e =
// gu_new_variant(PGF_EXPR_APP,
// PgfExprApp,
// &self->expr, self->pool);
// e->fun = fun;
// e->arg = arg;
// }
//
// return 0;
// }
//
// static ExprObject*
// Expr_call(ExprObject* self, PyObject* args, PyObject* kw)
// {
// ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (pyexpr == NULL)
// return NULL;
//
// size_t n_args = PyTuple_Size(args);
//
// pyexpr->master = PyTuple_New(n_args+1);
// if (pyexpr->master == NULL) {
// Py_DECREF(pyexpr);
// return NULL;
// }
//
// PyTuple_SetItem(pyexpr->master, 0, (PyObject*) self);
// Py_INCREF(self);
//
// pyexpr->pool = gu_new_pool();
// pyexpr->expr = self->expr;
//
// for (Py_ssize_t i = 0; i < n_args; i++) {
// PyObject* obj = PyTuple_GetItem(args, i);
// if (obj->ob_type != &pgf_ExprType) {
// PyErr_SetString(PyExc_TypeError, "the arguments must be expressions");
// return NULL;
// }
//
// PyTuple_SetItem(pyexpr->master, i+1, obj);
// Py_INCREF(obj);
//
// PgfExpr fun = pyexpr->expr;
// PgfExpr arg = ((ExprObject*) obj)->expr;
//
// PgfExprApp* e =
// gu_new_variant(PGF_EXPR_APP,
// PgfExprApp,
// &pyexpr->expr, pyexpr->pool);
// e->fun = fun;
// e->arg = arg;
// }
//
// return pyexpr;
// }
//
// static PyObject*
// Expr_unpack(ExprObject* self, PyObject *fargs)
// {
// PgfExpr expr = self->expr;
// PyObject* args = PyList_New(0);
//
// for (;;) {
// GuVariantInfo i = gu_variant_open(expr);
// switch (i.tag) {
// case PGF_EXPR_ABS: {
// PgfExprAbs* eabs = i.data;
//
// ExprObject* py_body = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (py_body == NULL) {
// Py_DECREF(args);
// return NULL;
// }
// py_body->pool = NULL;
// py_body->master = (self->master) ? self->master : (PyObject*) self;
// py_body->expr = eabs->body;
// Py_INCREF(py_body->master);
//
// PyObject* py_bindtype =
// (eabs->bind_type == PGF_BIND_TYPE_EXPLICIT) ? Py_True
// : Py_False;
// PyObject* py_var = PyString_FromString(eabs->id);
// PyObject* res =
// Py_BuildValue("OOOO", py_bindtype, py_var, py_body, args);
// Py_DECREF(py_var);
// Py_DECREF(py_body);
// Py_DECREF(args);
// return res;
// }
// case PGF_EXPR_APP: {
// PgfExprApp* eapp = i.data;
//
// ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (pyexpr == NULL) {
// Py_DECREF(args);
// return NULL;
// }
// pyexpr->pool = NULL;
// pyexpr->master = (self->master) ? self->master : (PyObject*) self;
// pyexpr->expr = eapp->arg;
// Py_INCREF(pyexpr->master);
//
// if (PyList_Insert(args, 0, (PyObject*) pyexpr) == -1) {
// Py_DECREF(args);
// return NULL;
// }
//
// Py_DECREF((PyObject*) pyexpr);
//
// expr = eapp->fun;
// break;
// }
// case PGF_EXPR_LIT: {
// PgfExprLit* elit = i.data;
//
// Py_DECREF(args);
//
// GuVariantInfo i = gu_variant_open(elit->lit);
// switch (i.tag) {
// case PGF_LITERAL_STR: {
// PgfLiteralStr* lstr = i.data;
// return PyString_FromString(lstr->val);
// }
// case PGF_LITERAL_INT: {
// PgfLiteralInt* lint = i.data;
// return PyInt_FromLong(lint->val);
// }
// case PGF_LITERAL_FLT: {
// PgfLiteralFlt* lflt = i.data;
// return PyFloat_FromDouble(lflt->val);
// }
// default:
// gu_impossible();
// return NULL;
// }
// }
// case PGF_EXPR_META: {
// PyObject* res = Py_BuildValue("OO", Py_None, args);
// Py_DECREF(args);
// return res;
// }
// case PGF_EXPR_FUN: {
// PgfExprFun* efun = i.data;
// PyObject* fun = PyString_FromString(efun->fun);
// PyObject* res = Py_BuildValue("OO", fun, args);
// Py_DECREF(fun);
// Py_DECREF(args);
// return res;
// }
// case PGF_EXPR_VAR: {
// PgfExprVar* evar = i.data;
// PyObject* res = Py_BuildValue("iO", evar->var, args);
// Py_DECREF(args);
// return res;
// }
// case PGF_EXPR_TYPED: {
// PgfExprTyped* etyped = i.data;
// expr = etyped->expr;
// break;
// }
// case PGF_EXPR_IMPL_ARG: {
// PgfExprImplArg* eimpl = i.data;
// expr = eimpl->expr;
// break;
// }
// default:
// gu_impossible();
// return NULL;
// }
// }
// return NULL;
// }
//
// static PyObject*
// Expr_visit(ExprObject* self, PyObject *args)
// {
// PyObject* py_visitor = NULL;
// PgfExpr expr = self->expr;
// if (!PyArg_ParseTuple(args, "O", &py_visitor))
// return NULL;
//
// GuPool* tmp_pool = gu_local_pool();
//
// PgfApplication* app = pgf_expr_unapply(expr, tmp_pool);
// if (app != NULL) {
// char* method_name = gu_malloc(tmp_pool, strlen(app->fun)+4);
// strcpy(method_name, "on_");
// strcat(method_name, app->fun);
//
// if (PyObject_HasAttrString(py_visitor, method_name)) {
// PyObject* method_args = PyTuple_New(app->n_args);
// if (method_args == NULL) {
// gu_pool_free(tmp_pool);
// return NULL;
// }
//
// for (size_t i = 0; i < app->n_args; i++) {
// ExprObject* pyarg = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (pyarg == NULL) {
// Py_DECREF(args);
// gu_pool_free(tmp_pool);
// return NULL;
// }
// pyarg->pool = NULL;
// pyarg->master = (self->master) ? self->master : (PyObject*) self;
// pyarg->expr = app->args[i];
// Py_INCREF(pyarg->master);
//
// if (PyTuple_SetItem(method_args, i, (PyObject*) pyarg) == -1) {
// Py_DECREF(args);
// gu_pool_free(tmp_pool);
// return NULL;
// }
// }
//
// PyObject* method =
// PyObject_GetAttrString(py_visitor, method_name);
// if (method == NULL) {
// Py_DECREF(args);
// gu_pool_free(tmp_pool);
// return NULL;
// }
//
// gu_pool_free(tmp_pool);
//
// return PyObject_CallObject(method, method_args);
// }
// }
//
// gu_pool_free(tmp_pool);
//
// return PyObject_CallMethod(py_visitor, "default", "O", self);
// }
//
// static PyObject*
// Expr_reduce_ex(ExprObject* self, PyObject *args)
// {
// int protocol;
// if (!PyArg_ParseTuple(args, "i", &protocol))
// return NULL;
//
// PyObject* myModule = PyImport_ImportModule("pgf");
// if (myModule == NULL)
// return NULL;
// PyObject* py_readExpr = PyObject_GetAttrString(myModule, "readExpr");
// Py_DECREF(myModule);
// if (py_readExpr == NULL)
// return NULL;
//
// PyObject* py_str = Expr_repr(self);
// if (py_str == NULL) {
// Py_DECREF(py_readExpr);
// return NULL;
// }
//
// PyObject* py_tuple =
// Py_BuildValue("O(O)", py_readExpr, py_str);
//
// Py_DECREF(py_str);
// Py_DECREF(py_readExpr);
//
// return py_tuple;
// }
//
// static PyObject*
// Expr_getattro(ExprObject *self, PyObject *attr_name) {
// #if PY_MAJOR_VERSION >= 3
// #define IS_ATTR(attr) (PyUnicode_CompareWithASCIIString(attr_name,attr) == 0)
// #else
// const char* name = PyString_AsString(attr_name);
// #define IS_ATTR(attr) (strcmp(name, attr) == 0)
// #endif
//
// PgfExpr expr = self->expr;
//
// redo:;
// GuVariantInfo i = gu_variant_open(expr);
// switch (i.tag) {
// case PGF_EXPR_APP: {
// PgfExprApp* eapp = i.data;
//
// ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (pyexpr == NULL)
// return NULL;
// pyexpr->pool = NULL;
// pyexpr->master = (self->master) ? self->master : (PyObject*) self;
// pyexpr->expr = gu_null_variant;
// Py_INCREF(pyexpr->master);
//
// if (IS_ATTR("fun")) {
// pyexpr->expr = eapp->fun;
// return ((PyObject*) pyexpr);
// } else if (IS_ATTR("arg")) {
// pyexpr->expr = eapp->arg;
// return ((PyObject*) pyexpr);
// } else {
// Py_DECREF(pyexpr);
// }
// break;
// }
// case PGF_EXPR_LIT: {
// PgfExprLit* elit = i.data;
//
// if (IS_ATTR("val")) {
// GuVariantInfo i = gu_variant_open(elit->lit);
// switch (i.tag) {
// case PGF_LITERAL_INT: {
// PgfLiteralInt* lint = i.data;
// return PyInt_FromLong(lint->val);
// }
// case PGF_LITERAL_FLT: {
// PgfLiteralFlt* lflt = i.data;
// return PyFloat_FromDouble(lflt->val);
// }
// case PGF_LITERAL_STR: {
// PgfLiteralStr* lstr = i.data;
// return PyString_FromString(lstr->val);
// }
// }
// }
// break;
// }
// case PGF_EXPR_META: {
// PgfExprMeta* emeta = i.data;
// if (IS_ATTR("id"))
// return PyInt_FromLong(emeta->id);
// break;
// }
// case PGF_EXPR_FUN: {
// PgfExprFun* efun = i.data;
// if (IS_ATTR("name")) {
// return PyString_FromString(efun->fun);
// }
// break;
// }
// case PGF_EXPR_VAR: {
// PgfExprVar* evar = i.data;
// if (IS_ATTR("index")) {
// return PyInt_FromLong(evar->var);
// }
// break;
// }
// case PGF_EXPR_TYPED: {
// PgfExprTyped* etyped = i.data;
// expr = etyped->expr;
// goto redo;
// }
// case PGF_EXPR_IMPL_ARG: {
// PgfExprImplArg* eimpl = i.data;
// expr = eimpl->expr;
// goto redo;
// }
// default:
// gu_impossible();
// }
//
// return PyObject_GenericGetAttr((PyObject*)self, attr_name);
// }
// ----------------------------------------------------------------------------
// static TypeObject*
// Type_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// {
// TypeObject* self = (TypeObject *)type->tp_alloc(type, 0);
// if (self != NULL) {
// self->hypos = NULL;
// self->cat = NULL;
// self->exprs = NULL;
// }
//
// return self;
// }
// static void
// Type_dealloc(TypeObject *self)
// {
// Py_TYPE(self)->tp_free((PyObject*)self);
// }
// static int
// Type_init(TypeObject *self, PyObject *args, PyObject *kwds)
// {
// PyObject* py_hypos;
// const char* catname_s;
// PyObject* py_exprs;
// size_t n_exprs;
// size_t n_hypos;
//
// if (PyTuple_Size(args) == 1) {
// py_hypos = NULL;
// py_exprs = NULL;
// n_exprs = 0;
// n_hypos = 0;
// if (!PyArg_ParseTuple(args, "s", &catname_s))
// return -1;
// } else {
// if (!PyArg_ParseTuple(args, "O!sO!",
// &PyList_Type, &py_hypos,
// &catname_s,
// &PyList_Type, &py_exprs))
// return -1;
//
// n_exprs = PyList_Size(py_exprs);
// n_hypos = PyList_Size(py_hypos);
// }
//
// self->pool = gu_new_pool();
// self->master =
// (n_exprs+n_hypos > 0) ? PyTuple_New(n_exprs+n_hypos) : NULL;
//
// self->type = gu_new_flex(self->pool, PgfType, exprs, n_exprs);
//
// self->type->hypos =
// gu_new_seq(PgfHypo, n_hypos, self->pool);
//
// for (size_t i = 0; i < n_hypos; i++) {
// PyObject* obj = PyList_GetItem(py_hypos, i);
// PyObject* py_bindtype;
// PgfCId cid;
// PyObject* py_type;
//
// if (Py_TYPE(obj) == &pgf_TypeType) {
// py_bindtype = Py_True;
// cid = "_";
// py_type = obj;
// } else {
// if (!PyTuple_Check(obj) ||
// PyTuple_GET_SIZE(obj) != 3) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the first list must be triples of (boolean,string,pgf.Type)");
// return -1;
// }
//
// py_bindtype = PyTuple_GetItem(obj, 0);
// if (!PyBool_Check(py_bindtype)) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the first list must be triples of (boolean,string,pgf.Type)");
// return -1;
// }
//
// PyObject* py_var = PyTuple_GetItem(obj, 1);
// if (!PyString_Check(py_var)) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the first list must be triples of (boolean,string,pgf.Type)");
// return -1;
// }
//
// {
// char* s;
// Py_ssize_t len;
//
// #if PY_MAJOR_VERSION >= 3
// PyObject* bytes = PyUnicode_AsUTF8String(py_var);
// if (bytes == NULL)
// return -1;
// if (PyBytes_AsStringAndSize(bytes,&s,&len) < 0)
// return -1;
// #else
// if (PyString_AsStringAndSize(py_var,&s,&len) < 0)
// return -1;
// #endif
//
// cid = gu_malloc(self->pool, len+1);
// memcpy((char*)cid, s, len+1);
//
// #if PY_MAJOR_VERSION >= 3
// Py_DECREF(bytes);
// #endif
// }
//
// py_type = PyTuple_GetItem(obj, 2);
// if (Py_TYPE(py_type) != &pgf_TypeType) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the first list must be triples of (boolean,string,pgf.Type)");
// return -1;
// }
// }
//
// PgfHypo* hypo = gu_seq_index(self->type->hypos, PgfHypo, i);
// hypo->bind_type =
// (py_bindtype == Py_True) ? PGF_BIND_TYPE_EXPLICIT
// : PGF_BIND_TYPE_IMPLICIT;
// hypo->cid = cid;
// hypo->type = ((TypeObject*) py_type)->type;
//
// PyTuple_SetItem(self->master, i, py_type);
// Py_INCREF(py_type);
// }
//
// self->type->cid = gu_string_copy(catname_s, self->pool);
//
// self->type->n_exprs = n_exprs;
// for (Py_ssize_t i = 0; i < n_exprs; i++) {
// PyObject* obj = PyList_GetItem(py_exprs, i);
// if (Py_TYPE(obj) != &pgf_ExprType) {
// PyErr_SetString(PyExc_TypeError, "the arguments in the second list must be expressions");
// return -1;
// }
//
// PyTuple_SetItem(self->master, n_hypos+i, obj);
// Py_INCREF(obj);
//
// self->type->exprs[i] = ((ExprObject*) obj)->expr;
// }
//
// return 0;
// }
static PyObject *
Type_repr(TypeObject *self)
{
// GuPool* tmp_pool = gu_local_pool();
//
// GuExn* err = gu_exn(tmp_pool);
// GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
// GuOut* out = gu_string_buf_out(sbuf);
//
// pgf_print_type(self->type, NULL, 0, out, err);
//
// PyObject* pystr = PyString_FromStringAndSize(gu_string_buf_data(sbuf),
// gu_string_buf_length(sbuf));
//
// gu_pool_free(tmp_pool);
// return pystr;
PyErr_SetString(PyExc_TypeError, "Type_repr: not implemented");
Py_RETURN_NOTIMPLEMENTED;
}
static PyObject *
Type_richcompare(TypeObject *t1, TypeObject *t2, int op)
{
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 (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*
// Type_getHypos(TypeObject *self, void *closure)
// {
// PgfType* type = self->type;
//
// PyObject* py_hypos = PyList_New(0);
// if (py_hypos == NULL)
// return NULL;
//
// size_t n_hypos = gu_seq_length(type->hypos);
// for (size_t i = 0; i < n_hypos; i++) {
// PgfHypo* hypo = gu_seq_index(type->hypos, PgfHypo, i);
//
// PyObject* py_bindtype =
// (hypo->bind_type == PGF_BIND_TYPE_EXPLICIT) ? Py_True
// : Py_False;
//
// PyObject* py_var = PyString_FromString(hypo->cid);
// if (py_var == NULL)
// goto fail;
//
// TypeObject* py_type = (TypeObject*) pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
// if (py_type == NULL) {
// Py_DECREF(py_var);
// goto fail;
// }
//
// py_type->pool = NULL;
// py_type->master = (PyObject*) self;
// py_type->type = hypo->type;
// Py_INCREF(self);
//
// PyObject* py_hypo =
// Py_BuildValue("OOO", py_bindtype, py_var, py_type);
// Py_DECREF(py_var);
// Py_DECREF(py_type);
//
// if (py_hypo == NULL)
// goto fail;
//
// if (PyList_Append(py_hypos, (PyObject*) py_hypo) == -1)
// goto fail;
//
// Py_DECREF(py_hypo);
// }
//
// return py_hypos;
//
// fail:
// Py_DECREF(py_hypos);
// return NULL;
// }
//
// static PyObject*
// Type_getCat(TypeObject *self, void *closure)
// {
// return PyString_FromString(self->type->cid);
// }
//
// static PyObject*
// Type_getExprs(TypeObject *self, void *closure)
// {
// PgfType* type = self->type;
//
// PyObject* py_exprs = PyList_New(0);
// if (py_exprs == NULL)
// return NULL;
//
// for (size_t i = 0; i < type->n_exprs; i++) {
// ExprObject* py_expr =
// (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
// if (py_expr == NULL)
// goto fail;
// py_expr->pool = NULL;
// py_expr->master = (PyObject*) self;
// py_expr->expr = type->exprs[i];
// Py_INCREF(py_expr->master);
//
// if (PyList_Append(py_exprs, (PyObject*) py_expr) == -1)
// goto fail;
//
// Py_DECREF((PyObject*) py_expr);
// }
//
// return py_exprs;
//
// fail:
// Py_DECREF(py_exprs);
// return NULL;
// }
//
// static PyObject*
// Type_unpack(TypeObject* self, PyObject *fargs)
// {
// PyObject* res = NULL;
// PyObject* py_hypos = NULL;
// PyObject* py_cat = NULL;
// PyObject* py_exprs = NULL;
//
// py_hypos = Type_getHypos(self, NULL);
// if (py_hypos == NULL)
// goto fail;
//
// py_cat = Type_getCat(self, NULL);
// if (py_cat == NULL)
// goto fail;
//
// py_exprs = Type_getExprs(self, NULL);
// if (py_exprs == NULL)
// goto fail;
//
// res = Py_BuildValue("OOO", py_hypos, py_cat, py_exprs);
//
// fail:
// Py_XDECREF(py_hypos);
// Py_XDECREF(py_cat);
// Py_XDECREF(py_exprs);
// return res;
// }
//
// static PyObject*
// Type_reduce_ex(TypeObject* self, PyObject *args)
// {
// int protocol;
// if (!PyArg_ParseTuple(args, "i", &protocol))
// return NULL;
//
// PyObject* myModule = PyImport_ImportModule("pgf");
// if (myModule == NULL)
// return NULL;
// PyObject* py_readType = PyObject_GetAttrString(myModule, "readType");
// Py_DECREF(myModule);
// if (py_readType == NULL)
// return NULL;
//
// PyObject* py_str = Type_repr(self);
// if (py_str == NULL) {
// Py_DECREF(py_readType);
// return NULL;
// }
//
// PyObject* py_tuple =
// Py_BuildValue("O(O)", py_readType, py_str);
//
// Py_DECREF(py_str);
// Py_DECREF(py_readType);
//
// return py_tuple;
// }
//
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_repr, /*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 */
};