diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index 23bc4977f..134f2bff4 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -814,7 +814,7 @@ static PyObject * Type_str(TypeObject *self) { - PgfText *s = pgf_print_type((PgfType) &self, NULL, 0, &marshaller); + PgfText *s = pgf_print_type((PgfType) &self, NULL, 1, &marshaller); return PyString_FromStringAndSize(s->text, s->size); } diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/marshaller.c index c45917f7b..a4bdc4889 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/marshaller.c @@ -15,46 +15,58 @@ PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body) { + PyErr_SetString(PyExc_NotImplementedError, "eabs not implemented"); return 0; } PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg) { + PyErr_SetString(PyExc_NotImplementedError, "eapp not implemented"); return 0; } PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit) { + PyErr_SetString(PyExc_NotImplementedError, "elit not implemented"); return 0; } PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta) { + PyErr_SetString(PyExc_NotImplementedError, "emeta not implemented"); return 0; } PgfExpr efun(PgfUnmarshaller *this, PgfText *name) { + PyErr_SetString(PyExc_NotImplementedError, "efun not implemented"); return 0; } PgfExpr evar(PgfUnmarshaller *this, int index) { + PyErr_SetString(PyExc_NotImplementedError, "evar not implemented"); return 0; } PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ) { + PyErr_SetString(PyExc_NotImplementedError, "etyped not implemented"); return 0; } PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr) { + PyErr_SetString(PyExc_NotImplementedError, "eimplarg not implemented"); return 0; } PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v) { + if (size > 1) { + PyErr_SetString(PyExc_NotImplementedError, "multi-part integers not implemented"); // TODO + return 0; + } PyObject *i = PyLong_FromUnsignedLong(*v); return (PgfLiteral) i; } @@ -89,6 +101,11 @@ PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *ca pytype->cat = PyString_FromStringAndSize(cat->text, cat->size); pytype->exprs = PyList_New(0); + for (int i = 0; i < n_exprs; i++) { + // TODO + // PgfExpr *expr = exprs + i; + } + return (PgfType) pytype; } @@ -119,37 +136,67 @@ PgfUnmarshaller unmarshaller = { &unmarshallerVtbl }; // ---------------------------------------------------------------------------- +static PgfText * +PyString_AsPgfText(PyObject *pystr) +{ + if (!PyString_Check(pystr)) { + PyErr_SetString(PyExc_TypeError, "input to PyString_AsPgfText is not a string"); + return NULL; + } + size_t size = PyUnicode_GetLength(pystr); + PgfText *ptext = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); + memcpy(ptext->text, pystr, size+1); + ptext->size = size; + // Py_INCREF(ptext); + return ptext; +} + +// ---------------------------------------------------------------------------- + object match_lit(PgfUnmarshaller *u, PgfLiteral lit) { - if (PyString_Check(lit)) { - // PgfText t = { - // PyUnicode_GetLength((PyObject*) lit), - // lit, - // }; - // return lstr(u, &lit); - return 0; - } - else if (PyLong_Check(lit)) { + PyObject *pyobj = (PyObject *)lit; - return lint(u, 1, (uintmax_t *)lit); + if (PyLong_Check(pyobj)) { + uintmax_t i = PyLong_AsUnsignedLong(pyobj); + size_t size = 1; // TODO + return u->vtbl->lint(NULL, size, &i); } - else if (PyFloat_Check(lit)) { - return lflt(u, *(double *)lit); + else if (PyFloat_Check(pyobj)) { + double d = PyFloat_AsDouble(pyobj); + return u->vtbl->lflt(NULL, d); + } + else if (PyString_Check(pyobj)) { + PgfText *t = PyString_AsPgfText(pyobj); + return u->vtbl->lstr(NULL, t); } else { - PyErr_SetString(PyExc_TypeError, "Unable to match on literal"); + PyErr_SetString(PyExc_TypeError, "unable to match on literal"); return 0; } } object match_expr(PgfUnmarshaller *u, PgfExpr expr) { + PyErr_SetString(PyExc_NotImplementedError, "match_expr not implemented"); return 0; } object match_type(PgfUnmarshaller *u, PgfType ty) { - return 0; + TypeObject *type = (TypeObject *)ty; + + PySys_WriteStdout(">%s<\n", PyUnicode_AS_DATA(type->cat)); + + int n_hypos = 0; //PyList_Size(type->hypos); + PgfTypeHypo *hypos = NULL; // TODO + + PgfText *cat = PyString_AsPgfText(type->cat); + + int n_exprs = 0; //PyList_Size(type->exprs); + PgfExpr *exprs = NULL; // TODO + + return u->vtbl->dtyp(NULL, n_hypos, hypos, cat, n_exprs, exprs); } static PgfMarshallerVtbl marshallerVtbl = diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 3bebd250d..e8903d871 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -1881,7 +1881,7 @@ PGF_getStartCat(PGFObject *self, void *closure) { PgfType type = pgf_start_cat(self->db, self->revision, &unmarshaller); if (type == 0) { - PyErr_SetString(PGFError, "The start category cannot be found"); + PyErr_SetString(PGFError, "start category cannot be found"); return NULL; } @@ -1925,19 +1925,19 @@ PGF_getFunctions(PGFObject *self, void *closure) return functions; } -static PyObject* -PGF_functionsByCat(PGFObject* self, PyObject *args) +static PyObject * +PGF_functionsByCat(PGFObject *self, PyObject *args) { - const char* s; + const char *s; Py_ssize_t size; if (!PyArg_ParseTuple(args, "s#", &s, &size)) return NULL; - PgfText* catname = (PgfText*) alloca(sizeof(PgfText)+size+1); + PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); memcpy(catname->text, s, size+1); catname->size = size; - PyObject* functions = PyList_New(0); + PyObject *functions = PyList_New(0); if (functions == NULL) { return NULL; } @@ -1945,6 +1945,7 @@ PGF_functionsByCat(PGFObject* self, PyObject *args) PgfExn err; PyPGFClosure clo = { { pgf_collect_funs }, self, functions }; pgf_iter_functions_by_cat(self->db, self->revision, catname, &clo.fn, &err); + PyMem_Free(catname); if (err.type != PGF_EXN_NONE) { Py_DECREF(functions); return NULL; @@ -1961,13 +1962,14 @@ PGF_functionType(PGFObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s#", &s, &size)) return NULL; - PgfText *funname = (PgfText *)alloca(sizeof(PgfText)+size+1); + PgfText *funname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); memcpy(funname->text, s, size+1); funname->size = size; PgfType type = pgf_function_type(self->db, self->revision, funname, &unmarshaller); + PyMem_Free(funname); if (type == 0) { - PyErr_Format(PyExc_KeyError, "Function '%s' is not defined", funname->text); + PyErr_Format(PyExc_KeyError, "function '%s' is not defined", s); return NULL; } @@ -2495,13 +2497,14 @@ pgf_readType(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s#", &s, &size)) return NULL; - PgfText *input = (PgfText *)alloca(sizeof(PgfText)+size+1); + PgfText *input = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1); memcpy(input->text, s, size+1); input->size = size; PgfType type = pgf_read_type(input, &unmarshaller); + PyMem_Free(input); if (type == 0) { - PyErr_SetString(PGFError, "The type cannot be parsed"); + PyErr_SetString(PGFError, "type cannot be parsed"); return NULL; } diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/test_suite.py index 62f84a57b..d8df7b4ca 100644 --- a/src/runtime/python/test_suite.py +++ b/src/runtime/python/test_suite.py @@ -103,6 +103,9 @@ def test_readType_inequality_1(): def test_readType_inequality_2(): assert pgf.readType("A -> B") != pgf.readType("B->B") +def test_Type_str_1(): + assert str(pgf.readType("A-> B")) == "A -> B" + def test_functionType_1(PGF): assert PGF.functionType("z") == pgf.readType("N")