From c5ce2fd4b77d182f3f66ae51256833133ef6631f Mon Sep 17 00:00:00 2001 From: "John J. Camilleri" Date: Mon, 13 Sep 2021 16:18:32 +0200 Subject: [PATCH] Add ExprMeta type, with two basic tests --- src/runtime/python/expr.c | 92 +++++++++++++++++++++++++++++++- src/runtime/python/expr.h | 7 +++ src/runtime/python/marshaller.c | 5 +- src/runtime/python/pypgf.c | 8 ++- src/runtime/python/test_suite.py | 73 +++++++++++++++++++------ 5 files changed, 164 insertions(+), 21 deletions(-) diff --git a/src/runtime/python/expr.c b/src/runtime/python/expr.c index 35d1fadf9..dcd5b16e7 100644 --- a/src/runtime/python/expr.c +++ b/src/runtime/python/expr.c @@ -215,7 +215,7 @@ PyTypeObject pgf_ExprLitType = { 0, //Expr_methods, /*tp_methods */ 0, /*tp_members */ 0, //Expr_getseters, /*tp_getset */ - &pgf_ExprType, /*tp_base */ + &pgf_ExprType, /*tp_base */ 0, /*tp_dict */ 0, /*tp_descr_get */ 0, /*tp_descr_set */ @@ -227,6 +227,96 @@ PyTypeObject pgf_ExprLitType = { // ---------------------------------------------------------------------------- +static ExprMetaObject * +ExprMeta_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + ExprMetaObject* self = (ExprMetaObject *)subtype->tp_alloc(subtype, 0); + return self; +} + +static int +ExprMeta_init(ExprMetaObject *self, PyObject *args, PyObject *kwds) +{ + PyObject* lit = NULL; + if (!PyArg_ParseTuple(args, "|O", &lit)) { + return -1; + } + if (lit == NULL) { + self->index = PyLong_FromLong(0); + return 0; + } else if (PyLong_Check(lit)) { + self->index = lit; + return 0; + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument in ExprMeta_init"); + return -1; + } +} + +static PyObject * +ExprMeta_richcompare(ExprMetaObject *t1, ExprMetaObject *t2, int op) +{ + bool same = false; + if (PyObject_RichCompareBool(t1->index, t2->index, Py_EQ) != 1) goto done; + + 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 */ +PyTypeObject pgf_ExprMetaType = { + PyVarObject_HEAD_INIT(NULL, 0) + //0, /*ob_size*/ + "pgf.ExprMeta", /*tp_name*/ + sizeof(ExprMetaObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, //(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*/ + 0, //(hashfunc) Expr_hash, /*tp_hash */ + 0, //(ternaryfunc) Expr_call, /*tp_call*/ + 0, //(reprfunc) Expr_str, /*tp_str*/ + 0, //(getattrofunc) Expr_getattro,/*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "meta variable", /*tp_doc*/ + 0, /*tp_traverse */ + 0, /*tp_clear */ + (richcmpfunc) ExprMeta_richcompare, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + 0, //Expr_methods, /*tp_methods */ + 0, /*tp_members */ + 0, //Expr_getseters, /*tp_getset */ + &pgf_ExprType, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + (initproc) ExprMeta_init, /*tp_init */ + 0, /*tp_alloc */ + (newfunc) ExprMeta_new, /*tp_new */ +}; + +// ---------------------------------------------------------------------------- + static PyObject * Type_str(TypeObject *self) { diff --git a/src/runtime/python/expr.h b/src/runtime/python/expr.h index fd28638a7..e1e2562de 100644 --- a/src/runtime/python/expr.h +++ b/src/runtime/python/expr.h @@ -26,8 +26,15 @@ typedef struct { PyObject *value; } ExprLitObject; +typedef struct { + PyObject_HEAD + PyObject *index; +} ExprMetaObject; + extern PyTypeObject pgf_ExprType; extern PyTypeObject pgf_ExprLitType; +extern PyTypeObject pgf_ExprMetaType; + #endif // PYPGF_EXPR_H_ diff --git a/src/runtime/python/marshaller.c b/src/runtime/python/marshaller.c index 32a43095f..ee1702712 100644 --- a/src/runtime/python/marshaller.c +++ b/src/runtime/python/marshaller.c @@ -37,8 +37,9 @@ PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit) PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta) { - PyErr_SetString(PyExc_NotImplementedError, "emeta not implemented"); - return 0; + ExprMetaObject *pyexpr = (ExprMetaObject *)pgf_ExprMetaType.tp_alloc(&pgf_ExprMetaType, 0); + pyexpr->index = PyLong_FromLong(meta); + return (PgfExpr) pyexpr; } PgfExpr efun(PgfUnmarshaller *this, PgfText *name) diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index c019d9d27..438e51bfe 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -2633,6 +2633,9 @@ MOD_INIT(pgf) if (PyType_Ready(&pgf_ExprLitType) < 0) return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_ExprMetaType) < 0) + return MOD_ERROR_VAL; + if (PyType_Ready(&pgf_TypeType) < 0) return MOD_ERROR_VAL; @@ -2662,7 +2665,10 @@ MOD_INIT(pgf) Py_INCREF(&pgf_ExprType); PyModule_AddObject(m, "ExprLit", (PyObject *) &pgf_ExprLitType); - Py_INCREF(&pgf_ExprType); + Py_INCREF(&pgf_ExprLitType); + + PyModule_AddObject(m, "ExprMeta", (PyObject *) &pgf_ExprMetaType); + Py_INCREF(&pgf_ExprMetaType); PyModule_AddObject(m, "Type", (PyObject *) &pgf_TypeType); Py_INCREF(&pgf_TypeType); diff --git a/src/runtime/python/test_suite.py b/src/runtime/python/test_suite.py index 4f7c8fc18..bbb170879 100644 --- a/src/runtime/python/test_suite.py +++ b/src/runtime/python/test_suite.py @@ -161,53 +161,92 @@ def test_readExpr_invalid(): with pytest.raises(pgf.PGFError): pgf.readExpr("->") -def test_readExpr_equality_int(): +# expressions: literals + +def test_readExpr_lint_equality(): assert pgf.readExpr("123") == pgf.ExprLit(123) -def test_readExpr_equality_int_neg(): +def test_readExpr_lint_equality_neg(): assert pgf.readExpr("-123") == pgf.ExprLit(-123) -def test_readExpr_equality_int_big(): +def test_readExpr_lint_equality_big2(): assert pgf.readExpr("774763251095801167872") == pgf.ExprLit(774763251095801167872) -def test_readExpr_equality_int_big_neg(): +def test_readExpr_lint_equality_big2_neg(): assert pgf.readExpr("-774763251095801167872") == pgf.ExprLit(-774763251095801167872) -def test_readExpr_inequality_int(): +def test_readExpr_lint_inequality(): assert pgf.readExpr("123") != pgf.ExprLit(456) -def test_readExpr_equality_float(): +def test_readExpr_lflt_equality(): assert pgf.readExpr("3.142") == pgf.ExprLit(3.142) -def test_readExpr_inequality_float(): +def test_readExpr_lflt_inequality(): assert pgf.readExpr("3.142") != pgf.ExprLit(3) -def test_readExpr_equality_string(): +def test_readExpr_lstr_equality(): assert pgf.readExpr("\"abc\"") == pgf.ExprLit("abc") -def test_readExpr_inequality_string(): +def test_readExpr_lstr_inequality(): assert pgf.readExpr("\"abc\"") != pgf.ExprLit("def") -def test_readExpr_str_int(): +def test_readExpr_lint_str(): assert str(pgf.readExpr("123")) == "123" -def test_readExpr_str_int_neg(): +def test_readExpr_lint_str_neg(): assert str(pgf.readExpr("-123")) == "-123" -def test_readExpr_str_int_big_2(): +def test_readExpr_lint_str_big2(): assert str(pgf.readExpr("774763251095801167872")) == "774763251095801167872" -def test_readExpr_str_int_big_3(): +def test_readExpr_lint_str_big3(): assert str(pgf.readExpr("7747632510958011678729003251095801167999")) == "7747632510958011678729003251095801167999" -def test_readExpr_str_int_big_2_neg(): +def test_readExpr_lint_str_big2_neg(): assert str(pgf.readExpr("-774763251095801167872")) == "-774763251095801167872" -def test_readExpr_str_int_big_3_neg(): +def test_readExpr_lint_str_big3_neg(): assert str(pgf.readExpr("-7747632510958011678729003251095801167999")) == "-7747632510958011678729003251095801167999" -def test_readExpr_str_float(): +def test_readExpr_lflt_str(): assert str(pgf.readExpr("3.142")) == "3.142" -def test_readExpr_str_string(): +def test_readExpr_lstr_str(): assert str(pgf.readExpr("\"açġħ\"")) == "\"açġħ\"" + +# expressions: functions + + # ,TestCase (assertEqual "show expression 1" "f x y" (showExpr [] (EApp (EApp (EFun "f") (EFun "x")) (EFun "y")))) + # ,TestCase (assertEqual "show expression 2" "f (g x)" (showExpr [] (EApp (EFun "f") (EApp (EFun "g") (EFun "x"))))) + # ,TestCase (assertEqual "show expression 3" "f {g x}" (showExpr [] (EApp (EFun "f") (EImplArg (EApp (EFun "g") (EFun "x")))))) + +# 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))) + +# expressions: lambda abstractions + + # ,TestCase (assertEqual "show expression 8" "\\w->w" (showExpr ["z","y","x"] (EAbs Explicit "w" (EVar 0)))) + # ,TestCase (assertEqual "show expression 9" "\\v,w->z" (showExpr ["z","y","x"] (EAbs Explicit "v" (EAbs Explicit "w" (EVar 2))))) + # ,TestCase (assertEqual "show expression 10" "\\v,{w}->z" (showExpr ["z","y","x"] (EAbs Explicit "v" (EAbs Implicit "w" (EVar 2))))) + # ,TestCase (assertEqual "show expression 11" "\\v,{w},z->z" (showExpr ["y","x"] (EAbs Explicit "v" (EAbs Implicit "w" (EAbs Explicit "z" (EVar 0)))))) + # ,TestCase (assertEqual "show expression 12" "\\v,{w,z}->v" (showExpr ["y","x"] (EAbs Explicit "v" (EAbs Implicit "w" (EAbs Implicit "z" (EVar 2)))))) + # ,TestCase (assertEqual "show expression 13" "\\v,{w,z},t->v" (showExpr ["y","x"] (EAbs Explicit "v" (EAbs Implicit "w" (EAbs Implicit "z" (EAbs Explicit "t" (EVar 3))))))) + # ,TestCase (assertEqual "show expression 14" "\\u,v,{w,z},t->v" (showExpr ["y","x"] (EAbs Explicit "u" (EAbs Explicit "v" (EAbs Implicit "w" (EAbs Implicit "z" (EAbs Explicit "t" (EVar 3)))))))) + # ,TestCase (assertEqual "show expression 15" "f (\\x->x)" (showExpr [] (EApp (EFun "f") (EAbs Explicit "x" (EVar 0))))) + +# expressions: meta variables + +def test_readExpr_emeta_1(): + assert pgf.readExpr("?") == pgf.ExprMeta() + assert pgf.readExpr("?") == pgf.ExprMeta(0) + +def test_readExpr_emeta_2(): + assert pgf.readExpr("?42") == pgf.ExprMeta(42) + +# expressions: typed expressions + + # ,TestCase (assertEqual "show expression 18" "" (showExpr [] (ETyped (EFun "z") (DTyp [] "N" []))))