summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrasimir <krasimir@chalmers.se>2015-09-30 08:35:09 +0000
committerkrasimir <krasimir@chalmers.se>2015-09-30 08:35:09 +0000
commit5faa99e89dd039757d062a803351592755cde80e (patch)
treeb2ddc8b424e289d20e78632044ae9346d1245b34
parentbd421aff7b4c7ba7b9efbb568bf7746c68b1cad3 (diff)
added bracketedLinearizeAll in Python
-rw-r--r--src/runtime/python/pypgf.c97
1 files changed, 97 insertions, 0 deletions
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
@@ -1961,6 +1961,100 @@ Concr_bracketedLinearize(ConcrObject* self, PyObject *args)
}
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)
{
PgfCId id;
@@ -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"
},