From 5faa99e89dd039757d062a803351592755cde80e Mon Sep 17 00:00:00 2001 From: krasimir Date: Wed, 30 Sep 2015 08:35:09 +0000 Subject: [PATCH] added bracketedLinearizeAll in Python --- src/runtime/python/pypgf.c | 97 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index bf58fd6c7..1ea4974e4 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -1960,6 +1960,100 @@ Concr_bracketedLinearize(ConcrObject* self, PyObject *args) return list; } +static PyObject* +Iter_fetch_bracketedLinearization(IterObject* self) +{ + GuPool* tmp_pool = gu_local_pool(); + GuExn* err = gu_exn(tmp_pool); + +restart:; + + PgfCncTree ctree = gu_next(self->res, PgfCncTree, tmp_pool); + if (gu_variant_is_null(ctree)) { + gu_pool_free(tmp_pool); + return NULL; + } + + PyObject* list = PyList_New(0); + ctree = pgf_lzr_wrap_linref(ctree, tmp_pool); + + ConcrObject* pyconcr = (ConcrObject*) self->container; + + PgfBracketLznState state; + state.funcs = &pgf_bracket_lin_funcs; + state.stack = gu_new_buf(PyObject*, tmp_pool); + state.list = list; + pgf_lzr_linearize(pyconcr->concr, ctree, 0, &state.funcs, tmp_pool); + + if (!gu_ok(err)) { + if (gu_exn_caught(err, PgfLinNonExist)) { + // encountered nonExist. Unfortunately there + // might be some output printed already. The + // right solution should be to use GuStringBuf. + gu_exn_clear(err); + goto restart; + } + else if (gu_exn_caught(err, PgfExn)) { + GuString msg = (GuString) gu_exn_caught_data(err); + PyErr_SetString(PGFError, msg); + gu_pool_free(tmp_pool); + return NULL; + } else { + PyErr_SetString(PGFError, "The abstract tree cannot be linearized"); + gu_pool_free(tmp_pool); + return NULL; + } + } + + gu_pool_free(tmp_pool); + return list; +} + +static PyObject* +Concr_bracketedLinearizeAll(ConcrObject* self, PyObject *args, PyObject *keywds) +{ + static char *kwlist[] = {"expression", "n", NULL}; + ExprObject* pyexpr = NULL; + int max_count = -1; + + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|i", kwlist, + &pgf_ExprType, &pyexpr, &max_count)) + return NULL; + + GuPool* pool = gu_new_pool(); + GuExn* err = gu_exn(pool); + + GuEnum* cts = + pgf_lzr_concretize(self->concr, pyexpr->expr, err, pool); + if (!gu_ok(err)) { + if (gu_exn_caught(err, PgfExn)) { + GuString msg = (GuString) gu_exn_caught_data(err); + PyErr_SetString(PGFError, msg); + } else { + PyErr_SetString(PGFError, "The abstract tree cannot be concretized"); + } + return NULL; + } + + IterObject* pyres = (IterObject*) pgf_IterType.tp_alloc(&pgf_IterType, 0); + if (pyres == NULL) { + gu_pool_free(pool); + return NULL; + } + + pyres->source = (PyObject*)pyexpr; + Py_INCREF(pyres->source); + pyres->container = (PyObject*)self; + Py_INCREF(pyres->container); + pyres->pool = pool; + pyres->max_count = max_count; + pyres->counter = 0; + pyres->fetch = Iter_fetch_bracketedLinearization; + pyres->res = cts; + + return (PyObject*)pyres; +} + static PyObject* Concr_hasLinearization(ConcrObject* self, PyObject *args) { @@ -2232,6 +2326,9 @@ static PyMethodDef Concr_methods[] = { {"bracketedLinearize", (PyCFunction)Concr_bracketedLinearize, METH_VARARGS, "Takes an abstract tree and linearizes it to a bracketed string" }, + {"bracketedLinearizeAll", (PyCFunction)Concr_bracketedLinearizeAll, METH_VARARGS | METH_KEYWORDS, + "Takes an abstract tree and linearizes all variants into bracketed strings" + }, {"hasLinearization", (PyCFunction)Concr_hasLinearization, METH_VARARGS, "hasLinearization(f) returns true if the function f has linearization in the concrete syntax" },