mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
Merge branch 'majestic' of github.com:GrammaticalFramework/gf-core into majestic
This commit is contained in:
@@ -21,10 +21,10 @@ main = do
|
||||
,TestCase (assertBool "type of z" (eqJust (readType "N") (functionType gr "z")))
|
||||
,TestCase (assertBool "type of s" (eqJust (readType "N->N") (functionType gr "s")))
|
||||
,TestCase (assertBool "type of c" (eqJust (readType "N->S") (functionType gr "c")))
|
||||
,TestCase (assertEqual "category context 1" [] (categoryContext gr "N"))
|
||||
,TestCase (assertEqual "category context 2" [] (categoryContext gr "S"))
|
||||
,TestCase (assertEqual "category context 3" [(Explicit,"_",DTyp [] "N" [])] (categoryContext gr "P"))
|
||||
,TestCase (assertEqual "category context 4" [] (categoryContext gr "X")) -- no such category
|
||||
,TestCase (assertEqual "category context 1" (Just []) (categoryContext gr "N"))
|
||||
,TestCase (assertEqual "category context 2" (Just []) (categoryContext gr "S"))
|
||||
,TestCase (assertEqual "category context 3" (Just [(Explicit,"_",DTyp [] "N" [])]) (categoryContext gr "P"))
|
||||
,TestCase (assertEqual "category context 4" Nothing (categoryContext gr "X")) -- no such category
|
||||
,TestCase (assertEqual "function is constructor 1" True (functionIsConstructor gr "s"))
|
||||
,TestCase (assertEqual "function is constructor 2" True (functionIsConstructor gr "z"))
|
||||
,TestCase (assertEqual "function is constructor 3" True (functionIsConstructor gr "c"))
|
||||
|
||||
@@ -28,16 +28,16 @@ main = do
|
||||
,TestCase (assertEqual "original categories" ["Float","Int","N","P","S","String"] (categories gr1))
|
||||
,TestCase (assertEqual "extended categories" ["Float","Int","N","P","Q","S","String"] (categories gr2))
|
||||
,TestCase (assertEqual "branched categories" ["Float","Int","N","P","R","S","String"] (categories gr3))
|
||||
,TestCase (assertEqual "Q context" [(Explicit,"x",ty)] (categoryContext gr2 "Q"))
|
||||
,TestCase (assertEqual "R context" [(Explicit,"x",ty)] (categoryContext gr3 "R"))
|
||||
,TestCase (assertEqual "Q context" (Just [(Explicit,"x",ty)]) (categoryContext gr2 "Q"))
|
||||
,TestCase (assertEqual "R context" (Just [(Explicit,"x",ty)]) (categoryContext gr3 "R"))
|
||||
,TestCase (assertEqual "reduced functions" ["c","s","z"] (functions gr6))
|
||||
,TestCase (assertEqual "reduced categories" ["Float","Int","N","P","String"] (categories gr6))
|
||||
,TestCase (assertEqual "old function type" Nothing (functionType gr1 "foo"))
|
||||
,TestCase (assertEqual "new function type" (Just ty) (functionType gr2 "foo"))
|
||||
,TestCase (assertEqual "old function prob" (-log 0) (functionProb gr1 "foo"))
|
||||
,TestCase (assertEqual "new function prob" pi (functionProb gr2 "foo"))
|
||||
,TestCase (assertEqual "old function prob" (-log 0) (functionProbability gr1 "foo"))
|
||||
,TestCase (assertEqual "new function prob" pi (functionProbability gr2 "foo"))
|
||||
]
|
||||
|
||||
|
||||
performMajorGC
|
||||
|
||||
if (errors c == 0) && (failures c == 0)
|
||||
|
||||
@@ -242,10 +242,10 @@ ExprMeta_init(ExprMetaObject *self, PyObject *args, PyObject *kwds)
|
||||
return -1;
|
||||
}
|
||||
if (lit == NULL) {
|
||||
self->index = PyLong_FromLong(0);
|
||||
self->id = PyLong_FromLong(0);
|
||||
return 0;
|
||||
} else if (PyLong_Check(lit)) {
|
||||
self->index = lit;
|
||||
self->id = lit;
|
||||
return 0;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument in ExprMeta_init");
|
||||
@@ -257,7 +257,7 @@ 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;
|
||||
if (PyObject_RichCompareBool(t1->id, t2->id, Py_EQ) != 1) goto done;
|
||||
|
||||
same = true;
|
||||
done:
|
||||
@@ -317,6 +317,96 @@ PyTypeObject pgf_ExprMetaType = {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static ExprVarObject *
|
||||
ExprVar_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
ExprVarObject* self = (ExprVarObject *)subtype->tp_alloc(subtype, 0);
|
||||
return self;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprVar_init(ExprVarObject *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 ExprVar_init");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
ExprVar_richcompare(ExprVarObject *t1, ExprVarObject *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_ExprVarType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
"pgf.ExprVar", /*tp_name*/
|
||||
sizeof(ExprVarObject), /*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*/
|
||||
"variable", /*tp_doc*/
|
||||
0, /*tp_traverse */
|
||||
0, /*tp_clear */
|
||||
(richcmpfunc) ExprVar_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) ExprVar_init, /*tp_init */
|
||||
0, /*tp_alloc */
|
||||
(newfunc) ExprVar_new, /*tp_new */
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static PyObject *
|
||||
Type_str(TypeObject *self)
|
||||
{
|
||||
|
||||
@@ -28,13 +28,20 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *index;
|
||||
PyObject *id;
|
||||
} ExprMetaObject;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *index;
|
||||
} ExprVarObject;
|
||||
|
||||
extern PyTypeObject pgf_ExprType;
|
||||
|
||||
extern PyTypeObject pgf_ExprLitType;
|
||||
|
||||
extern PyTypeObject pgf_ExprMetaType;
|
||||
|
||||
extern PyTypeObject pgf_ExprVarType;
|
||||
|
||||
#endif // PYPGF_EXPR_H_
|
||||
|
||||
@@ -38,7 +38,7 @@ PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit)
|
||||
PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta)
|
||||
{
|
||||
ExprMetaObject *pyexpr = (ExprMetaObject *)pgf_ExprMetaType.tp_alloc(&pgf_ExprMetaType, 0);
|
||||
pyexpr->index = PyLong_FromLong(meta);
|
||||
pyexpr->id = PyLong_FromLong(meta);
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,9 @@ PgfExpr efun(PgfUnmarshaller *this, PgfText *name)
|
||||
|
||||
PgfExpr evar(PgfUnmarshaller *this, int index)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "evar not implemented");
|
||||
return 0;
|
||||
ExprVarObject *pyexpr = (ExprVarObject *)pgf_ExprVarType.tp_alloc(&pgf_ExprVarType, 0);
|
||||
pyexpr->index = PyLong_FromLong(index);
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ)
|
||||
@@ -153,7 +154,7 @@ PgfUnmarshaller unmarshaller = { &unmarshallerVtbl };
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static PgfText *
|
||||
PgfText *
|
||||
PyUnicode_AsPgfText(PyObject *pystr)
|
||||
{
|
||||
if (!PyUnicode_Check(pystr)) {
|
||||
@@ -165,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;
|
||||
@@ -221,14 +222,21 @@ object match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit)
|
||||
}
|
||||
}
|
||||
|
||||
object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr ex)
|
||||
object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr)
|
||||
{
|
||||
ExprObject *expr = (ExprObject *)ex;
|
||||
PyObject *pyobj = (PyObject *)expr;
|
||||
|
||||
if (expr->ob_base.ob_type == &pgf_ExprLitType) { // use PyObject_IsInstance ?
|
||||
ExprLitObject *elit= (ExprLitObject *)expr;
|
||||
if (PyObject_TypeCheck(pyobj, &pgf_ExprLitType)) {
|
||||
ExprLitObject *elit = (ExprLitObject *)expr;
|
||||
return this->vtbl->match_lit(this, u, (PgfLiteral) elit->value);
|
||||
} else if (PyObject_TypeCheck(pyobj, &pgf_ExprMetaType)) {
|
||||
ExprMetaObject *emeta = (ExprMetaObject *)expr;
|
||||
return u->vtbl->emeta(u, (PgfMetaId) PyLong_AsLong(emeta->id));
|
||||
} else if (PyObject_TypeCheck(pyobj, &pgf_ExprVarType)) {
|
||||
ExprVarObject *evar = (ExprVarObject *)expr;
|
||||
return u->vtbl->evar(u, PyLong_AsLong(evar->index));
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "unable to match on expression");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
|
||||
PgfText *PyUnicode_AsPgfText(PyObject *pystr);
|
||||
|
||||
extern PgfUnmarshaller unmarshaller;
|
||||
|
||||
extern PgfMarshaller marshaller;
|
||||
|
||||
@@ -1917,6 +1917,10 @@ PGF_categoryContext(PGFObject *self, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hypos == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *contexts = PyList_New(n_hypos);
|
||||
if (contexts == NULL) {
|
||||
return NULL;
|
||||
@@ -2537,7 +2541,7 @@ const char *fpath;
|
||||
return py_pgf;
|
||||
}
|
||||
|
||||
static ExprObject*
|
||||
static ExprObject *
|
||||
pgf_readExpr(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *s;
|
||||
@@ -2559,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)
|
||||
{
|
||||
@@ -2590,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 */
|
||||
@@ -2636,6 +2672,9 @@ MOD_INIT(pgf)
|
||||
if (PyType_Ready(&pgf_ExprMetaType) < 0)
|
||||
return MOD_ERROR_VAL;
|
||||
|
||||
if (PyType_Ready(&pgf_ExprVarType) < 0)
|
||||
return MOD_ERROR_VAL;
|
||||
|
||||
if (PyType_Ready(&pgf_TypeType) < 0)
|
||||
return MOD_ERROR_VAL;
|
||||
|
||||
@@ -2670,6 +2709,9 @@ MOD_INIT(pgf)
|
||||
PyModule_AddObject(m, "ExprMeta", (PyObject *) &pgf_ExprMetaType);
|
||||
Py_INCREF(&pgf_ExprMetaType);
|
||||
|
||||
PyModule_AddObject(m, "ExprVar", (PyObject *) &pgf_ExprVarType);
|
||||
Py_INCREF(&pgf_ExprVarType);
|
||||
|
||||
PyModule_AddObject(m, "Type", (PyObject *) &pgf_TypeType);
|
||||
Py_INCREF(&pgf_TypeType);
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ def test_categoryContext_3(PGF):
|
||||
assert tup[2] == pgf.readType("N")
|
||||
|
||||
def test_categoryContext_4(PGF):
|
||||
assert PGF.categoryContext("X") == []
|
||||
assert PGF.categoryContext("X") == None
|
||||
|
||||
def test_functionIsConstructor_1(PGF):
|
||||
assert PGF.functionIsConstructor("s") == True
|
||||
@@ -222,10 +222,30 @@ 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)
|
||||
|
||||
# def test_readExpr_evar_equality_2():
|
||||
# assert pgf.readExpr("#42") == pgf.ExprVar(42)
|
||||
|
||||
def test_readExpr_evar_str_1():
|
||||
assert str(pgf.ExprVar(0)) == "#0"
|
||||
|
||||
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
|
||||
|
||||
@@ -247,6 +267,12 @@ def test_readExpr_emeta_1():
|
||||
def test_readExpr_emeta_2():
|
||||
assert pgf.readExpr("?42") == pgf.ExprMeta(42)
|
||||
|
||||
def test_readExpr_emeta_str_1():
|
||||
assert str(pgf.readExpr("?")) == "?"
|
||||
|
||||
def test_readExpr_emeta_str_2():
|
||||
assert str(pgf.readExpr("?42")) == "?42"
|
||||
|
||||
# expressions: typed expressions
|
||||
|
||||
# ,TestCase (assertEqual "show expression 18" "<z : N>" (showExpr [] (ETyped (EFun "z") (DTyp [] "N" []))))
|
||||
|
||||
Reference in New Issue
Block a user