From be5751060a57b8e0ee95c2f7d2f4ae3471cd450f Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Tue, 14 Sep 2021 00:18:45 +0200 Subject: [PATCH] Add showExpr and tests for it using variable expressions --- src/runtime/python/marshaller.c | 4 ++-- src/runtime/python/marshaller.h | 2 ++ src/runtime/python/pypgf.c | 34 +++++++++++++++++++++++++++++++- src/runtime/python/test_suite.py | 17 +++++++++++----- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/marshaller.c index 257fd8e9a..e2dab89fd 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/marshaller.c @@ -154,7 +154,7 @@ PgfUnmarshaller unmarshaller = { &unmarshallerVtbl }; // ---------------------------------------------------------------------------- -static PgfText * +PgfText * PyUnicode_AsPgfText(PyObject *pystr) { if (!PyUnicode_Check(pystr)) { @@ -166,7 +166,7 @@ PyUnicode_AsPgfText(PyObject *pystr) } Py_ssize_t size; - const char * enc = PyUnicode_AsUTF8AndSize(pystr, &size); + const char *enc = PyUnicode_AsUTF8AndSize(pystr, &size); PgfText *ptext = malloc(sizeof(PgfText)+size+1); memcpy(ptext->text, enc, size+1); ptext->size = size; diff --git a/src/runtime/python/marshaller.h b/src/runtime/python/marshaller.h index 71793ec2c..bec013fe8 100644 --- a/src/runtime/python/marshaller.h +++ b/src/runtime/python/marshaller.h @@ -6,6 +6,8 @@ #include +PgfText *PyUnicode_AsPgfText(PyObject *pystr); + extern PgfUnmarshaller unmarshaller; extern PgfMarshaller marshaller; diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index 4f2e7765f..6b4bff183 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -2541,7 +2541,7 @@ const char *fpath; return py_pgf; } -static ExprObject* +static ExprObject * pgf_readExpr(PyObject *self, PyObject *args) { const char *s; @@ -2563,6 +2563,36 @@ pgf_readExpr(PyObject *self, PyObject *args) return (ExprObject *)expr; } +static PyObject * +pgf_showExpr(PyObject *self, PyObject *args) +{ + PyObject *pylist; + PyObject *pyexpr; + if (!PyArg_ParseTuple(args, "O!O!", &PyList_Type, &pylist, &pgf_ExprType, &pyexpr)) + return NULL; + + PgfPrintContext *ctxt = NULL; + for (Py_ssize_t i = PyList_Size(pylist); i > 0 ; i--) { + PyObject *item = PyList_GetItem(pylist, i-1); + if (!PyUnicode_Check(item)) { + PyErr_SetString(PyExc_TypeError, "invalid variable argument in showExpr"); + return NULL; + } + PgfText *input = PyUnicode_AsPgfText(item); + + // TODO a better way to copy into this->name? + PgfPrintContext *this = (PgfPrintContext *)PyMem_Malloc(sizeof(PgfPrintContext *) + sizeof(PgfText) + input->size + 1); + this->next = ctxt; + memcpy(&this->name, input, sizeof(PgfText) + input->size + 1); + ctxt = this; + } + + PgfText *s = pgf_print_expr((PgfExpr) pyexpr, ctxt, 0, &marshaller); + PyObject *str = PyUnicode_FromStringAndSize(s->text, s->size); + free(s); + return str; +} + static TypeObject * pgf_readType(PyObject *self, PyObject *args) { @@ -2594,6 +2624,8 @@ static PyMethodDef module_methods[] = { "Reads an NGF file into memory"}, {"readExpr", (void*)pgf_readExpr, METH_VARARGS, "Parses a string as an abstract tree"}, + {"showExpr", (void*)pgf_showExpr, METH_VARARGS, + "Renders an expression as a string"}, {"readType", (void*)pgf_readType, METH_VARARGS, "Parses a string as an abstract type"}, {NULL, NULL, 0, NULL} /* Sentinel */ diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/test_suite.py index d0699ecee..b3fb45a59 100644 --- a/src/runtime/python/test_suite.py +++ b/src/runtime/python/test_suite.py @@ -222,11 +222,6 @@ def test_readExpr_lstr_str(): # expressions: variables - # ,TestCase (assertEqual "show expression 4" "x" (showExpr ["x"] (EVar 0))) - # ,TestCase (assertEqual "show expression 5" "#1" (showExpr ["x"] (EVar 1))) - # ,TestCase (assertEqual "show expression 6" "z" (showExpr ["z","y","x"] (EVar 0))) - # ,TestCase (assertEqual "show expression 7" "y" (showExpr ["z","y","x"] (EVar 1))) - # def test_readExpr_evar_equality_1(): # assert pgf.readExpr("#0") == pgf.ExprVar() # assert pgf.readExpr("#0") == pgf.ExprVar(0) @@ -240,6 +235,18 @@ def test_readExpr_evar_str_1(): def test_readExpr_evar_str_2(): assert str(pgf.ExprVar(42)) == "#42" +def test_showExpr_evar_1(): + assert pgf.showExpr(["x"], pgf.ExprVar(0)) == "x" + +def test_showExpr_evar_2(): + assert pgf.showExpr(["x"], pgf.ExprVar(1)) == "#1" + +def test_showExpr_evar_3(): + assert pgf.showExpr(["z", "y", "x"], pgf.ExprVar(0)) == "z" + +def test_showExpr_evar_4(): + assert pgf.showExpr(["z", "y", "x"], pgf.ExprVar(1)) == "y" + # expressions: lambda abstractions # ,TestCase (assertEqual "show expression 8" "\\w->w" (showExpr ["z","y","x"] (EAbs Explicit "w" (EVar 0))))