forked from GitHub/gf-core
Merge branch 'majestic' of github.com:GrammaticalFramework/gf-core into majestic
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -47,8 +47,8 @@ src/runtime/c/sg/.dirstamp
|
||||
src/runtime/c/stamp-h1
|
||||
src/runtime/java/.libs/
|
||||
src/runtime/python/build/
|
||||
src/runtime/python/__pycache__/
|
||||
src/runtime/python/.pytest_cache/
|
||||
src/runtime/python/**/__pycache__/
|
||||
src/runtime/python/**/.pytest_cache/
|
||||
.cabal-sandbox
|
||||
cabal.sandbox.config
|
||||
.stack-work
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
#include "./expr.h"
|
||||
#include "./marshaller.h"
|
||||
#include "./ffi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// types
|
||||
|
||||
static TypeObject *
|
||||
Type_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
|
||||
@@ -135,7 +136,6 @@ static PyGetSetDef Type_getseters[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_TypeType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -179,6 +179,7 @@ PyTypeObject pgf_TypeType = {
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// expressions
|
||||
|
||||
static PyObject *
|
||||
Expr_str(ExprObject *self)
|
||||
@@ -234,7 +235,6 @@ static PyGetSetDef Expr_getseters[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -327,7 +327,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprAbsType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -416,7 +415,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprAppType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -522,7 +520,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprLitType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -615,7 +612,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprMetaType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -700,7 +696,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprFunType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -793,7 +788,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprVarType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -882,7 +876,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprTypedType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
@@ -967,7 +960,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyTypeObject pgf_ExprImplArgType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
|
||||
@@ -13,7 +13,7 @@ typedef struct {
|
||||
PyObject *exprs; // PyListObject of ExprObject
|
||||
} TypeObject;
|
||||
|
||||
extern PyTypeObject pgf_TypeType;
|
||||
PyTypeObject pgf_TypeType;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
@@ -63,14 +63,14 @@ typedef struct {
|
||||
ExprObject *expr;
|
||||
} ExprImplArgObject;
|
||||
|
||||
extern PyTypeObject pgf_ExprType;
|
||||
extern PyTypeObject pgf_ExprAbsType;
|
||||
extern PyTypeObject pgf_ExprAppType;
|
||||
extern PyTypeObject pgf_ExprLitType;
|
||||
extern PyTypeObject pgf_ExprMetaType;
|
||||
extern PyTypeObject pgf_ExprFunType;
|
||||
extern PyTypeObject pgf_ExprVarType;
|
||||
extern PyTypeObject pgf_ExprTypedType;
|
||||
extern PyTypeObject pgf_ExprImplArgType;
|
||||
PyTypeObject pgf_ExprType;
|
||||
PyTypeObject pgf_ExprAbsType;
|
||||
PyTypeObject pgf_ExprAppType;
|
||||
PyTypeObject pgf_ExprLitType;
|
||||
PyTypeObject pgf_ExprMetaType;
|
||||
PyTypeObject pgf_ExprFunType;
|
||||
PyTypeObject pgf_ExprVarType;
|
||||
PyTypeObject pgf_ExprTypedType;
|
||||
PyTypeObject pgf_ExprImplArgType;
|
||||
|
||||
#endif // PYPGF_EXPR_H_
|
||||
|
||||
@@ -5,9 +5,29 @@
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
#include "./expr.h"
|
||||
#include "./marshaller.h"
|
||||
#include "./ffi.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// errors
|
||||
|
||||
PyObject *PGFError;
|
||||
|
||||
PgfExnType handleError(PgfExn err)
|
||||
{
|
||||
if (err.type == PGF_EXN_SYSTEM_ERROR) {
|
||||
errno = err.code;
|
||||
PyErr_SetFromErrnoWithFilename(PyExc_IOError, err.msg);
|
||||
} else if (err.type == PGF_EXN_PGF_ERROR) {
|
||||
PyErr_SetString(PGFError, err.msg);
|
||||
free((char*) err.msg);
|
||||
} else if (err.type == PGF_EXN_OTHER_ERROR) {
|
||||
PyErr_SetString(PGFError, "an unknown error occured");
|
||||
}
|
||||
return err.type;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// string conversions
|
||||
|
||||
PgfText *
|
||||
PyUnicode_AsPgfText(PyObject *pystr)
|
||||
@@ -35,15 +55,10 @@ PyUnicode_FromPgfText(PgfText *text)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// unmarshaller
|
||||
|
||||
/* The PgfUnmarshaller structure tells the runtime how to create
|
||||
* abstract syntax expressions and types in the heap of the host language.
|
||||
* In Python the expressions are normal objects.
|
||||
* From the point of view of the runtime, each node is a value of type object.
|
||||
* For Python that would be a PyObject pointer.
|
||||
*/
|
||||
|
||||
PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body)
|
||||
static PgfExpr
|
||||
eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr body)
|
||||
{
|
||||
ExprAbsObject *pyexpr = (ExprAbsObject *)pgf_ExprAbsType.tp_alloc(&pgf_ExprAbsType, 0);
|
||||
pyexpr->bindType = PyLong_FromLong(btype);
|
||||
@@ -53,7 +68,8 @@ PgfExpr eabs(PgfUnmarshaller *this, PgfBindType btype, PgfText *name, PgfExpr bo
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg)
|
||||
static PgfExpr
|
||||
eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg)
|
||||
{
|
||||
ExprAppObject *pyexpr = (ExprAppObject *)pgf_ExprAppType.tp_alloc(&pgf_ExprAppType, 0);
|
||||
pyexpr->e1 = (ExprObject *)fun;
|
||||
@@ -63,7 +79,8 @@ PgfExpr eapp(PgfUnmarshaller *this, PgfExpr fun, PgfExpr arg)
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit)
|
||||
static PgfExpr
|
||||
elit(PgfUnmarshaller *this, PgfLiteral lit)
|
||||
{
|
||||
ExprLitObject *pyexpr = (ExprLitObject *)pgf_ExprLitType.tp_alloc(&pgf_ExprLitType, 0);
|
||||
PyObject *pyobj = (PyObject *)lit;
|
||||
@@ -72,14 +89,16 @@ PgfExpr elit(PgfUnmarshaller *this, PgfLiteral lit)
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr emeta(PgfUnmarshaller *this, PgfMetaId meta)
|
||||
static PgfExpr
|
||||
emeta(PgfUnmarshaller *this, PgfMetaId meta)
|
||||
{
|
||||
ExprMetaObject *pyexpr = (ExprMetaObject *)pgf_ExprMetaType.tp_alloc(&pgf_ExprMetaType, 0);
|
||||
pyexpr->id = PyLong_FromLong(meta);
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr efun(PgfUnmarshaller *this, PgfText *name)
|
||||
static PgfExpr
|
||||
efun(PgfUnmarshaller *this, PgfText *name)
|
||||
{
|
||||
ExprFunObject *pyexpr = (ExprFunObject *)pgf_ExprFunType.tp_alloc(&pgf_ExprFunType, 0);
|
||||
PyObject *pyobj = PyUnicode_FromPgfText(name);
|
||||
@@ -88,14 +107,16 @@ PgfExpr efun(PgfUnmarshaller *this, PgfText *name)
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr evar(PgfUnmarshaller *this, int index)
|
||||
static PgfExpr
|
||||
evar(PgfUnmarshaller *this, int index)
|
||||
{
|
||||
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)
|
||||
static PgfExpr
|
||||
etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ)
|
||||
{
|
||||
ExprTypedObject *pyexpr = (ExprTypedObject *)pgf_ExprTypedType.tp_alloc(&pgf_ExprTypedType, 0);
|
||||
pyexpr->expr = (ExprObject *)expr;
|
||||
@@ -105,7 +126,8 @@ PgfExpr etyped(PgfUnmarshaller *this, PgfExpr expr, PgfType typ)
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr)
|
||||
static PgfExpr
|
||||
eimplarg(PgfUnmarshaller *this, PgfExpr expr)
|
||||
{
|
||||
ExprImplArgObject *pyexpr = (ExprImplArgObject *)pgf_ExprImplArgType.tp_alloc(&pgf_ExprImplArgType, 0);
|
||||
pyexpr->expr = (ExprObject *)expr;
|
||||
@@ -113,7 +135,8 @@ PgfExpr eimplarg(PgfUnmarshaller *this, PgfExpr expr)
|
||||
return (PgfExpr) pyexpr;
|
||||
}
|
||||
|
||||
PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v)
|
||||
static PgfLiteral
|
||||
lint(PgfUnmarshaller *this, size_t size, uintmax_t *v)
|
||||
{
|
||||
intmax_t *v0 = (intmax_t *)v;
|
||||
PyObject *i = PyLong_FromLong(*v0);
|
||||
@@ -137,19 +160,22 @@ PgfLiteral lint(PgfUnmarshaller *this, size_t size, uintmax_t *v)
|
||||
}
|
||||
}
|
||||
|
||||
PgfLiteral lflt(PgfUnmarshaller *this, double v)
|
||||
static PgfLiteral
|
||||
lflt(PgfUnmarshaller *this, double v)
|
||||
{
|
||||
PyObject *d = PyFloat_FromDouble(v);
|
||||
return (PgfLiteral) d;
|
||||
}
|
||||
|
||||
PgfLiteral lstr(PgfUnmarshaller *this, PgfText *v)
|
||||
static PgfLiteral
|
||||
lstr(PgfUnmarshaller *this, PgfText *v)
|
||||
{
|
||||
PyObject *s = PyUnicode_FromStringAndSize(v->text, v->size);
|
||||
return (PgfLiteral) s;
|
||||
}
|
||||
|
||||
PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs)
|
||||
static PgfType
|
||||
dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *cat, int n_exprs, PgfExpr *exprs)
|
||||
{
|
||||
TypeObject *pytype = (TypeObject *)pgf_TypeType.tp_alloc(&pgf_TypeType, 0);
|
||||
|
||||
@@ -173,7 +199,8 @@ PgfType dtyp(PgfUnmarshaller *this, int n_hypos, PgfTypeHypo *hypos, PgfText *ca
|
||||
return (PgfType) pytype;
|
||||
}
|
||||
|
||||
void free_ref(PgfUnmarshaller *this, object x)
|
||||
static void
|
||||
free_ref(PgfUnmarshaller *this, object x)
|
||||
{
|
||||
// Py_XDECREF(x);
|
||||
}
|
||||
@@ -195,12 +222,13 @@ static PgfUnmarshallerVtbl unmarshallerVtbl =
|
||||
free_ref
|
||||
};
|
||||
|
||||
/* static */
|
||||
PgfUnmarshaller unmarshaller = { &unmarshallerVtbl };
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// marshaller
|
||||
|
||||
object match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit)
|
||||
static object
|
||||
match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit)
|
||||
{
|
||||
PyObject *pyobj = (PyObject *)lit;
|
||||
|
||||
@@ -247,7 +275,8 @@ object match_lit(PgfMarshaller *this, PgfUnmarshaller *u, PgfLiteral lit)
|
||||
}
|
||||
}
|
||||
|
||||
object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr)
|
||||
static object
|
||||
match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr)
|
||||
{
|
||||
PyObject *pyobj = (PyObject *)expr;
|
||||
|
||||
@@ -288,12 +317,14 @@ object match_expr(PgfMarshaller *this, PgfUnmarshaller *u, PgfExpr expr)
|
||||
}
|
||||
}
|
||||
|
||||
object match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty)
|
||||
static object
|
||||
match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty)
|
||||
{
|
||||
TypeObject *type = (TypeObject *)ty;
|
||||
|
||||
Py_ssize_t n_hypos = PyList_Size(type->hypos);
|
||||
PgfTypeHypo *hypos = alloca(sizeof(PgfTypeHypo)*n_hypos);
|
||||
PgfTypeHypo hypos[n_hypos];
|
||||
// PgfTypeHypo *hypos = alloca(sizeof(PgfTypeHypo)*n_hypos);
|
||||
for (Py_ssize_t i = 0; i < n_hypos; i++) {
|
||||
PyObject *hytup = (PyObject *)PyList_GetItem(type->hypos, i);
|
||||
hypos[i].bind_type = PyLong_AsLong(PyTuple_GetItem(hytup, 0));
|
||||
@@ -308,7 +339,8 @@ object match_type(PgfMarshaller *this, PgfUnmarshaller *u, PgfType ty)
|
||||
}
|
||||
|
||||
Py_ssize_t n_exprs = PyList_Size(type->exprs);
|
||||
PgfExpr *exprs = alloca(sizeof(PgfExpr)*n_exprs);
|
||||
PgfExpr exprs[n_exprs];
|
||||
// PgfExpr *exprs = alloca(sizeof(PgfExpr)*n_exprs);
|
||||
for (Py_ssize_t i = 0; i < n_exprs; i++) {
|
||||
exprs[i] = (PgfExpr)PyList_GetItem(type->exprs, i);
|
||||
Py_INCREF(exprs[i]);
|
||||
@@ -335,5 +367,4 @@ static PgfMarshallerVtbl marshallerVtbl =
|
||||
match_type
|
||||
};
|
||||
|
||||
/* static */
|
||||
PgfMarshaller marshaller = { &marshallerVtbl };
|
||||
24
src/runtime/python/ffi.h
Normal file
24
src/runtime/python/ffi.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef PYPGF_FFI_H_
|
||||
#define PYPGF_FFI_H_
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PgfDB *db;
|
||||
PgfRevision revision;
|
||||
} PGFObject;
|
||||
|
||||
PyObject *PGFError;
|
||||
PgfExnType handleError(PgfExn err);
|
||||
|
||||
PgfText *PyUnicode_AsPgfText(PyObject *pystr);
|
||||
PyObject *PyUnicode_FromPgfText(PgfText *text);
|
||||
|
||||
PgfUnmarshaller unmarshaller;
|
||||
PgfMarshaller marshaller;
|
||||
|
||||
#endif // PYPGF_FFI_H_
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef PYPGF_MARSHALLER_H_
|
||||
#define PYPGF_MARSHALLER_H_
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
|
||||
PgfText *PyUnicode_AsPgfText(PyObject *pystr);
|
||||
PyObject *PyUnicode_FromPgfText(PgfText *text);
|
||||
|
||||
extern PgfUnmarshaller unmarshaller;
|
||||
extern PgfMarshaller marshaller;
|
||||
|
||||
#endif // PYPGF_MARSHALLER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,12 @@ if libraries==['']:
|
||||
|
||||
pgf_module = Extension(
|
||||
'pgf',
|
||||
sources = ['pypgf.c', 'marshaller.c', 'expr.c'],
|
||||
sources = [
|
||||
'pypgf.c',
|
||||
'expr.c',
|
||||
'ffi.c',
|
||||
'transactions.c'
|
||||
],
|
||||
extra_compile_args = ['-std=c99', '-Werror', '-Wno-error=unused-variable', '-Wno-comment'],
|
||||
include_dirs = includes,
|
||||
library_dirs = libraries,
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
import os
|
||||
import pytest
|
||||
import pgf
|
||||
|
||||
# readPGF
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def PGF():
|
||||
return pgf.readPGF("../haskell/tests/basic.pgf")
|
||||
|
||||
def test_readPGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
pgf.readPGF("../haskell/tests/abc.pgf")
|
||||
|
||||
def test_readPGF_GF():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readPGF("../haskell/tests/basic.gf")
|
||||
|
||||
def test_readPGF_NGF(NGF):
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readPGF("./basic.ngf")
|
||||
|
||||
# bootNGF
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def NGF():
|
||||
ngf = pgf.bootNGF("../haskell/tests/basic.pgf", "./basic.ngf")
|
||||
yield ngf
|
||||
os.remove("./basic.ngf")
|
||||
|
||||
def test_bootNGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
pgf.bootNGF("../haskell/tests/abc.pgf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_GF():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.bootNGF("../haskell/tests/basic.gf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_NGF(NGF):
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.bootNGF("./basic.ngf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_existing(NGF):
|
||||
with pytest.raises(FileExistsError):
|
||||
pgf.bootNGF("../haskell/tests/basic.pgf", "./basic.ngf")
|
||||
|
||||
# readNGF
|
||||
|
||||
def test_readNGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
pgf.readNGF("./abc.ngf")
|
||||
|
||||
def test_readNGF_GF():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readNGF("../haskell/tests/basic.gf")
|
||||
|
||||
def test_readNGF_PGF():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readNGF("../haskell/tests/basic.pgf")
|
||||
|
||||
def test_readNGF(NGF):
|
||||
PGF = pgf.readNGF("./basic.ngf")
|
||||
assert len(PGF.categories) > 0
|
||||
|
||||
# newNGF
|
||||
|
||||
def test_newNGF_file(NGF):
|
||||
PGF = pgf.newNGF("empty", "./empty.ngf")
|
||||
assert len(PGF.categories) == 0
|
||||
os.remove("./empty.ngf") # cleanup
|
||||
|
||||
def test_newNGF_memory(NGF):
|
||||
PGF = pgf.newNGF("empty")
|
||||
assert len(PGF.categories) == 0
|
||||
|
||||
def test_newNGF_existing(NGF):
|
||||
with pytest.raises(FileExistsError):
|
||||
pgf.newNGF("empty", "./basic.ngf")
|
||||
|
||||
# abstract syntax
|
||||
|
||||
def test_abstractName(PGF):
|
||||
assert PGF.abstractName == "basic"
|
||||
|
||||
def test_categories(PGF):
|
||||
assert PGF.categories == ["Float","Int","N","P","S","String"]
|
||||
|
||||
def test_functions(PGF):
|
||||
assert PGF.functions == ["c","ind","s","z"]
|
||||
|
||||
def test_functionsByCat_1(PGF):
|
||||
assert PGF.functionsByCat("N") == ["s","z"]
|
||||
|
||||
def test_functionsByCat_2(PGF):
|
||||
assert PGF.functionsByCat("S") == ["c"]
|
||||
|
||||
def test_functionsByCat_non_existant(PGF):
|
||||
assert PGF.functionsByCat("X") == []
|
||||
|
||||
def test_categoryContext_1(PGF):
|
||||
assert PGF.categoryContext("N") == []
|
||||
|
||||
def test_categoryContext_2(PGF):
|
||||
assert PGF.categoryContext("S") == []
|
||||
|
||||
def test_categoryContext_3(PGF):
|
||||
cxt = PGF.categoryContext("P")
|
||||
assert len(cxt) == 1
|
||||
tup = cxt[0]
|
||||
assert tup[0] == 0 # explicit
|
||||
assert tup[1] == "_" # cid
|
||||
assert tup[2] == pgf.readType("N")
|
||||
|
||||
def test_categoryContext_4(PGF):
|
||||
assert PGF.categoryContext("X") == None
|
||||
|
||||
def test_functionIsConstructor_1(PGF):
|
||||
assert PGF.functionIsConstructor("s") == True
|
||||
|
||||
def test_functionIsConstructor_2(PGF):
|
||||
assert PGF.functionIsConstructor("z") == True
|
||||
|
||||
def test_functionIsConstructor_3(PGF):
|
||||
assert PGF.functionIsConstructor("c") == True
|
||||
|
||||
def test_functionIsConstructor_4(PGF):
|
||||
assert PGF.functionIsConstructor("ind") == False
|
||||
|
||||
# types
|
||||
|
||||
def test_readType_invalid():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readType("->")
|
||||
|
||||
def test_readType_equality_1():
|
||||
assert pgf.readType("A") == pgf.readType("A")
|
||||
|
||||
def test_readType_equality_2():
|
||||
assert pgf.readType("A -> B") == pgf.readType("A->B")
|
||||
|
||||
def test_readType_equality_3():
|
||||
assert pgf.readType("A -> B -> C") == pgf.readType("A->B -> C")
|
||||
|
||||
def test_readType_inequality_1():
|
||||
assert pgf.readType("A") != pgf.readType("B")
|
||||
|
||||
def test_readType_inequality_2():
|
||||
assert pgf.readType("A -> B") != pgf.readType("B->B")
|
||||
|
||||
def test_readType_str():
|
||||
assert str(pgf.readType("A-> BÄ->C")) == "A -> BÄ -> C"
|
||||
|
||||
def test_functionType_1(PGF):
|
||||
assert PGF.functionType("z") == pgf.readType("N")
|
||||
|
||||
def test_functionType_2(PGF):
|
||||
assert PGF.functionType("s") == pgf.readType("N->N")
|
||||
|
||||
def test_functionType_3(PGF):
|
||||
assert PGF.functionType("c") == pgf.readType("N -> S")
|
||||
|
||||
def test_functionType_non_existant(PGF):
|
||||
with pytest.raises(KeyError):
|
||||
assert PGF.functionType("cbx")
|
||||
|
||||
def test_functionType_wrong(PGF):
|
||||
assert PGF.functionType("c") != pgf.readType("N -> S -> X")
|
||||
|
||||
def test_startCat(PGF):
|
||||
assert PGF.startCat == pgf.readType("S")
|
||||
|
||||
def test_showType_1(PGF):
|
||||
type = pgf.Type([], "N", [])
|
||||
assert pgf.showType([], type) == "N"
|
||||
|
||||
def test_showType_2(PGF):
|
||||
type = pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", [])
|
||||
assert pgf.showType([], type) == "N -> N"
|
||||
|
||||
def test_showType_3(PGF):
|
||||
type = pgf.Type([pgf.mkHypo(pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "N", [])
|
||||
assert pgf.showType([], type) == "(N -> N) -> N"
|
||||
|
||||
def test_showType_4(PGF):
|
||||
type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", []))], "P", [pgf.ExprVar(0)])
|
||||
assert pgf.showType([], type) == "(x : N) -> P x"
|
||||
|
||||
def test_showType_5(PGF):
|
||||
type = pgf.Type([pgf.mkDepHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprFun("z"))])
|
||||
assert pgf.showType([], type) == "(f : N -> N) -> P (f z)"
|
||||
|
||||
def test_showType_6(PGF):
|
||||
type = pgf.Type([pgf.mkDepHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprVar(1))])
|
||||
assert pgf.showType(["n"], type) == "(f : N -> N) -> P (f n)"
|
||||
|
||||
def test_showType_7(PGF):
|
||||
type = pgf.Type([pgf.mkImplHypo("f", pgf.Type([pgf.mkHypo(pgf.Type([], "N", []))], "N", []))], "P", [pgf.ExprApp(pgf.ExprVar(0), pgf.ExprVar(1))])
|
||||
assert pgf.showType(["n"], type) == "({f} : N -> N) -> P (f n)"
|
||||
|
||||
def test_showType_8(PGF):
|
||||
type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", [])), pgf.mkHypo(pgf.Type([], "P", [pgf.ExprVar(0)]))], "S", [])
|
||||
assert pgf.showType(["n"], type) == "(x : N) -> P x -> S"
|
||||
|
||||
def test_showType_9(PGF):
|
||||
type = pgf.Type([pgf.mkDepHypo("x", pgf.Type([], "N", [])), pgf.mkDepHypo("y", pgf.Type([], "P", [pgf.ExprVar(0)]))], "S", [])
|
||||
assert pgf.showType(["n"], type) == "(x : N) -> (y : P x) -> S"
|
||||
|
||||
# expressions
|
||||
|
||||
def test_readExpr_invalid():
|
||||
with pytest.raises(pgf.PGFError):
|
||||
pgf.readExpr("->")
|
||||
|
||||
# expressions: literals
|
||||
|
||||
def test_readExpr_lint_equality():
|
||||
assert pgf.readExpr("123") == pgf.ExprLit(123)
|
||||
|
||||
def test_readExpr_lint_equality_neg():
|
||||
assert pgf.readExpr("-123") == pgf.ExprLit(-123)
|
||||
|
||||
def test_readExpr_lint_equality_big2():
|
||||
assert pgf.readExpr("774763251095801167872") == pgf.ExprLit(774763251095801167872)
|
||||
|
||||
def test_readExpr_lint_equality_big2_neg():
|
||||
assert pgf.readExpr("-774763251095801167872") == pgf.ExprLit(-774763251095801167872)
|
||||
|
||||
def test_readExpr_lint_inequality():
|
||||
assert pgf.readExpr("123") != pgf.ExprLit(456)
|
||||
|
||||
def test_readExpr_lflt_equality():
|
||||
assert pgf.readExpr("3.142") == pgf.ExprLit(3.142)
|
||||
|
||||
def test_readExpr_lflt_inequality():
|
||||
assert pgf.readExpr("3.142") != pgf.ExprLit(3)
|
||||
|
||||
def test_readExpr_lstr_equality():
|
||||
assert pgf.readExpr("\"abc\"") == pgf.ExprLit("abc")
|
||||
|
||||
def test_readExpr_lstr_inequality():
|
||||
assert pgf.readExpr("\"abc\"") != pgf.ExprLit("def")
|
||||
|
||||
def test_readExpr_lint_str():
|
||||
assert str(pgf.readExpr("123")) == "123"
|
||||
|
||||
def test_readExpr_lint_str_neg():
|
||||
assert str(pgf.readExpr("-123")) == "-123"
|
||||
|
||||
def test_readExpr_lint_str_big2():
|
||||
assert str(pgf.readExpr("774763251095801167872")) == "774763251095801167872"
|
||||
|
||||
def test_readExpr_lint_str_big3():
|
||||
assert str(pgf.readExpr("7747632510958011678729003251095801167999")) == "7747632510958011678729003251095801167999"
|
||||
|
||||
def test_readExpr_lint_str_big2_neg():
|
||||
assert str(pgf.readExpr("-774763251095801167872")) == "-774763251095801167872"
|
||||
|
||||
def test_readExpr_lint_str_big3_neg():
|
||||
assert str(pgf.readExpr("-7747632510958011678729003251095801167999")) == "-7747632510958011678729003251095801167999"
|
||||
|
||||
def test_readExpr_lflt_str():
|
||||
assert str(pgf.readExpr("3.142")) == "3.142"
|
||||
|
||||
def test_readExpr_lstr_str_unicode():
|
||||
assert str(pgf.readExpr("\"açġħ\"")) == "\"açġħ\""
|
||||
|
||||
def test_readExpr_lstr_null():
|
||||
assert str(pgf.ExprLit("ab\0c")) == "\"ab\\0c\""
|
||||
|
||||
def test_readExpr_lstr_newline():
|
||||
assert str(pgf.ExprLit("ab\nc")) == "\"ab\\nc\""
|
||||
|
||||
# expressions: functions
|
||||
|
||||
def test_readExpr_efun_equality_1():
|
||||
assert pgf.readExpr("f") == pgf.ExprFun("f")
|
||||
|
||||
def test_readExpr_efun_equality_2():
|
||||
assert \
|
||||
pgf.readExpr("f x y") == \
|
||||
pgf.ExprApp(
|
||||
pgf.ExprApp(
|
||||
pgf.ExprFun("f"),
|
||||
pgf.ExprFun("x")
|
||||
),
|
||||
pgf.ExprFun("y")
|
||||
)
|
||||
|
||||
def test_readExpr_efun_equality_3():
|
||||
assert \
|
||||
pgf.readExpr("f (g x)") == \
|
||||
pgf.ExprApp(
|
||||
pgf.ExprFun("f"),
|
||||
pgf.ExprApp(
|
||||
pgf.ExprFun("g"),
|
||||
pgf.ExprFun("x")
|
||||
)
|
||||
)
|
||||
|
||||
def test_readExpr_efun_equality_4():
|
||||
assert \
|
||||
pgf.readExpr("f {g x}") == \
|
||||
pgf.ExprApp(
|
||||
pgf.ExprFun("f"),
|
||||
pgf.ExprImplArg(
|
||||
pgf.ExprApp(
|
||||
pgf.ExprFun("g"),
|
||||
pgf.ExprFun("x")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def test_readExpr_efun_str_unicode_1():
|
||||
assert str(pgf.readExpr("'абв'")) == "'абв'"
|
||||
|
||||
@pytest.mark.skip(reason="failing")
|
||||
def test_readExpr_efun_str_unicode_2():
|
||||
assert str(pgf.readExpr("'аb'")) == "аb"
|
||||
|
||||
@pytest.mark.skip(reason="failing")
|
||||
def test_readExpr_efun_str_unicode_3():
|
||||
assert str(pgf.readExpr("'а\\'b'")) == "а'b"
|
||||
|
||||
def test_readExpr_efun_str_unicode_4():
|
||||
assert str(pgf.readExpr("'а\\'б'")) == "'а\\'б'"
|
||||
|
||||
# expressions: variables
|
||||
|
||||
# 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
|
||||
|
||||
def test_showExpr_eabs_1():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "w", pgf.ExprVar(0))
|
||||
assert pgf.showExpr(["z", "y", "x"], expr) == "\\w->w"
|
||||
|
||||
def test_showExpr_eabs_2():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "w", pgf.ExprVar(2)))
|
||||
assert pgf.showExpr(["z", "y", "x"], expr) == "\\v,w->z"
|
||||
|
||||
def test_showExpr_eabs_3():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprVar(2)))
|
||||
assert pgf.showExpr(["z", "y", "x"], expr) == "\\v,{w}->z"
|
||||
|
||||
def test_showExpr_eabs_4():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "z", pgf.ExprVar(0))))
|
||||
assert pgf.showExpr(["y", "x"], expr) == "\\v,{w},z->z"
|
||||
|
||||
def test_showExpr_eabs_5():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprVar(2))))
|
||||
assert pgf.showExpr(["y", "x"], expr) == "\\v,{w,z}->v"
|
||||
|
||||
def test_showExpr_eabs_6():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "t", pgf.ExprVar(3)))))
|
||||
assert pgf.showExpr(["y", "x"], expr) == "\\v,{w,z},t->v"
|
||||
|
||||
def test_showExpr_eabs_7():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "u", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "w", pgf.ExprAbs(pgf.BIND_TYPE_IMPLICIT, "z", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "t", pgf.ExprVar(3))))))
|
||||
assert pgf.showExpr(["y", "x"], expr) == "\\u,v,{w,z},t->v"
|
||||
|
||||
def test_showExpr_eabs_8():
|
||||
expr = pgf.ExprApp(pgf.ExprFun("f"), pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "x", pgf.ExprVar(0)))
|
||||
assert pgf.showExpr([], expr) == "f (\\x->x)"
|
||||
|
||||
def test_showExpr_eabs_freshvars_1():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(0)))
|
||||
assert pgf.showExpr([], expr) == "\\v,v1->v1"
|
||||
|
||||
def test_showExpr_eabs_freshvars_2():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(1)))
|
||||
assert pgf.showExpr([], expr) == "\\v,v1->v"
|
||||
|
||||
def test_showExpr_eabs_freshvars_3():
|
||||
expr = pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprAbs(pgf.BIND_TYPE_EXPLICIT, "v", pgf.ExprVar(1))))
|
||||
assert pgf.showExpr([], expr) == "\\v,v1,v2->v1"
|
||||
|
||||
# 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)
|
||||
|
||||
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
|
||||
|
||||
def test_readExpr_emeta_equality():
|
||||
assert pgf.readExpr("<z : N>") == pgf.ExprTyped(pgf.ExprFun("z"), pgf.readType("N"))
|
||||
|
||||
def test_readExpr_emeta_str():
|
||||
assert str(pgf.readExpr("<z : N>")) == "<z : N>"
|
||||
421
src/runtime/python/tests/test_basic.py
Normal file
421
src/runtime/python/tests/test_basic.py
Normal file
@@ -0,0 +1,421 @@
|
||||
import os
|
||||
import pytest
|
||||
from pgf import *
|
||||
|
||||
# readPGF
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def PGF():
|
||||
return readPGF("../haskell/tests/basic.pgf")
|
||||
|
||||
def test_readPGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
readPGF("../haskell/tests/abc.pgf")
|
||||
|
||||
def test_readPGF_GF():
|
||||
with pytest.raises(PGFError):
|
||||
readPGF("../haskell/tests/basic.gf")
|
||||
|
||||
def test_readPGF_NGF(NGF):
|
||||
with pytest.raises(PGFError):
|
||||
readPGF("./basic.ngf")
|
||||
|
||||
# bootNGF
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def NGF():
|
||||
ngf = bootNGF("../haskell/tests/basic.pgf", "./basic.ngf")
|
||||
yield ngf
|
||||
os.remove("./basic.ngf")
|
||||
|
||||
def test_bootNGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
bootNGF("../haskell/tests/abc.pgf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_GF():
|
||||
with pytest.raises(PGFError):
|
||||
bootNGF("../haskell/tests/basic.gf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_NGF(NGF):
|
||||
with pytest.raises(PGFError):
|
||||
bootNGF("./basic.ngf", "./abc.ngf")
|
||||
|
||||
def test_bootNGF_existing(NGF):
|
||||
with pytest.raises(FileExistsError):
|
||||
bootNGF("../haskell/tests/basic.pgf", "./basic.ngf")
|
||||
|
||||
# readNGF
|
||||
|
||||
def test_readNGF_non_existant():
|
||||
with pytest.raises(FileNotFoundError):
|
||||
readNGF("./abc.ngf")
|
||||
|
||||
def test_readNGF_GF():
|
||||
with pytest.raises(PGFError):
|
||||
readNGF("../haskell/tests/basic.gf")
|
||||
|
||||
def test_readNGF_PGF():
|
||||
with pytest.raises(PGFError):
|
||||
readNGF("../haskell/tests/basic.pgf")
|
||||
|
||||
def test_readNGF(NGF):
|
||||
PGF = readNGF("./basic.ngf")
|
||||
assert len(PGF.categories) > 0
|
||||
|
||||
# newNGF
|
||||
|
||||
def test_newNGF_file(NGF):
|
||||
PGF = newNGF("empty", "./empty.ngf")
|
||||
assert len(PGF.categories) == 0
|
||||
os.remove("./empty.ngf") # cleanup
|
||||
|
||||
def test_newNGF_memory(NGF):
|
||||
PGF = newNGF("empty")
|
||||
assert len(PGF.categories) == 0
|
||||
|
||||
def test_newNGF_existing(NGF):
|
||||
with pytest.raises(FileExistsError):
|
||||
newNGF("empty", "./basic.ngf")
|
||||
|
||||
# abstract syntax
|
||||
|
||||
def test_abstractName(PGF):
|
||||
assert PGF.abstractName == "basic"
|
||||
|
||||
def test_categories(PGF):
|
||||
assert PGF.categories == ["Float","Int","N","P","S","String"]
|
||||
|
||||
def test_functions(PGF):
|
||||
assert PGF.functions == ["c","ind","s","z"]
|
||||
|
||||
def test_functionsByCat_1(PGF):
|
||||
assert PGF.functionsByCat("N") == ["s","z"]
|
||||
|
||||
def test_functionsByCat_2(PGF):
|
||||
assert PGF.functionsByCat("S") == ["c"]
|
||||
|
||||
def test_functionsByCat_non_existant(PGF):
|
||||
assert PGF.functionsByCat("X") == []
|
||||
|
||||
def test_categoryContext_1(PGF):
|
||||
assert PGF.categoryContext("N") == []
|
||||
|
||||
def test_categoryContext_2(PGF):
|
||||
assert PGF.categoryContext("S") == []
|
||||
|
||||
def test_categoryContext_3(PGF):
|
||||
cxt = PGF.categoryContext("P")
|
||||
assert len(cxt) == 1
|
||||
tup = cxt[0]
|
||||
assert tup[0] == 0 # explicit
|
||||
assert tup[1] == "_" # cid
|
||||
assert tup[2] == readType("N")
|
||||
|
||||
def test_categoryContext_4(PGF):
|
||||
assert PGF.categoryContext("X") == None
|
||||
|
||||
def test_functionIsConstructor_1(PGF):
|
||||
assert PGF.functionIsConstructor("s") == True
|
||||
|
||||
def test_functionIsConstructor_2(PGF):
|
||||
assert PGF.functionIsConstructor("z") == True
|
||||
|
||||
def test_functionIsConstructor_3(PGF):
|
||||
assert PGF.functionIsConstructor("c") == True
|
||||
|
||||
def test_functionIsConstructor_4(PGF):
|
||||
assert PGF.functionIsConstructor("ind") == False
|
||||
|
||||
# types
|
||||
|
||||
def test_readType_invalid():
|
||||
with pytest.raises(PGFError):
|
||||
readType("->")
|
||||
|
||||
def test_readType_equality_1():
|
||||
assert readType("A") == readType("A")
|
||||
|
||||
def test_readType_equality_2():
|
||||
assert readType("A -> B") == readType("A->B")
|
||||
|
||||
def test_readType_equality_3():
|
||||
assert readType("A -> B -> C") == readType("A->B -> C")
|
||||
|
||||
def test_readType_inequality_1():
|
||||
assert readType("A") != readType("B")
|
||||
|
||||
def test_readType_inequality_2():
|
||||
assert readType("A -> B") != readType("B->B")
|
||||
|
||||
def test_readType_str():
|
||||
assert str(readType("A-> BÄ->C")) == "A -> BÄ -> C"
|
||||
|
||||
def test_functionType_1(PGF):
|
||||
assert PGF.functionType("z") == readType("N")
|
||||
|
||||
def test_functionType_2(PGF):
|
||||
assert PGF.functionType("s") == readType("N->N")
|
||||
|
||||
def test_functionType_3(PGF):
|
||||
assert PGF.functionType("c") == readType("N -> S")
|
||||
|
||||
def test_functionType_non_existant(PGF):
|
||||
with pytest.raises(KeyError):
|
||||
assert PGF.functionType("cbx")
|
||||
|
||||
def test_functionType_wrong(PGF):
|
||||
assert PGF.functionType("c") != readType("N -> S -> X")
|
||||
|
||||
def test_startCat(PGF):
|
||||
assert PGF.startCat == readType("S")
|
||||
|
||||
def test_showType_1(PGF):
|
||||
type = Type([], "N", [])
|
||||
assert showType([], type) == "N"
|
||||
|
||||
def test_showType_2(PGF):
|
||||
type = Type([mkHypo(Type([], "N", []))], "N", [])
|
||||
assert showType([], type) == "N -> N"
|
||||
|
||||
def test_showType_3(PGF):
|
||||
type = Type([mkHypo(Type([mkHypo(Type([], "N", []))], "N", []))], "N", [])
|
||||
assert showType([], type) == "(N -> N) -> N"
|
||||
|
||||
def test_showType_4(PGF):
|
||||
type = Type([mkDepHypo("x", Type([], "N", []))], "P", [ExprVar(0)])
|
||||
assert showType([], type) == "(x : N) -> P x"
|
||||
|
||||
def test_showType_5(PGF):
|
||||
type = Type([mkDepHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprFun("z"))])
|
||||
assert showType([], type) == "(f : N -> N) -> P (f z)"
|
||||
|
||||
def test_showType_6(PGF):
|
||||
type = Type([mkDepHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprVar(1))])
|
||||
assert showType(["n"], type) == "(f : N -> N) -> P (f n)"
|
||||
|
||||
def test_showType_7(PGF):
|
||||
type = Type([mkImplHypo("f", Type([mkHypo(Type([], "N", []))], "N", []))], "P", [ExprApp(ExprVar(0), ExprVar(1))])
|
||||
assert showType(["n"], type) == "({f} : N -> N) -> P (f n)"
|
||||
|
||||
def test_showType_8(PGF):
|
||||
type = Type([mkDepHypo("x", Type([], "N", [])), mkHypo(Type([], "P", [ExprVar(0)]))], "S", [])
|
||||
assert showType(["n"], type) == "(x : N) -> P x -> S"
|
||||
|
||||
def test_showType_9(PGF):
|
||||
type = Type([mkDepHypo("x", Type([], "N", [])), mkDepHypo("y", Type([], "P", [ExprVar(0)]))], "S", [])
|
||||
assert showType(["n"], type) == "(x : N) -> (y : P x) -> S"
|
||||
|
||||
# expressions
|
||||
|
||||
def test_readExpr_invalid():
|
||||
with pytest.raises(PGFError):
|
||||
readExpr("->")
|
||||
|
||||
# expressions: literals
|
||||
|
||||
def test_readExpr_lint_equality():
|
||||
assert readExpr("123") == ExprLit(123)
|
||||
|
||||
def test_readExpr_lint_equality_neg():
|
||||
assert readExpr("-123") == ExprLit(-123)
|
||||
|
||||
def test_readExpr_lint_equality_big2():
|
||||
assert readExpr("774763251095801167872") == ExprLit(774763251095801167872)
|
||||
|
||||
def test_readExpr_lint_equality_big2_neg():
|
||||
assert readExpr("-774763251095801167872") == ExprLit(-774763251095801167872)
|
||||
|
||||
def test_readExpr_lint_inequality():
|
||||
assert readExpr("123") != ExprLit(456)
|
||||
|
||||
def test_readExpr_lflt_equality():
|
||||
assert readExpr("3.142") == ExprLit(3.142)
|
||||
|
||||
def test_readExpr_lflt_inequality():
|
||||
assert readExpr("3.142") != ExprLit(3)
|
||||
|
||||
def test_readExpr_lstr_equality():
|
||||
assert readExpr("\"abc\"") == ExprLit("abc")
|
||||
|
||||
def test_readExpr_lstr_inequality():
|
||||
assert readExpr("\"abc\"") != ExprLit("def")
|
||||
|
||||
def test_readExpr_lint_str():
|
||||
assert str(readExpr("123")) == "123"
|
||||
|
||||
def test_readExpr_lint_str_neg():
|
||||
assert str(readExpr("-123")) == "-123"
|
||||
|
||||
def test_readExpr_lint_str_big2():
|
||||
assert str(readExpr("774763251095801167872")) == "774763251095801167872"
|
||||
|
||||
def test_readExpr_lint_str_big3():
|
||||
assert str(readExpr("7747632510958011678729003251095801167999")) == "7747632510958011678729003251095801167999"
|
||||
|
||||
def test_readExpr_lint_str_big2_neg():
|
||||
assert str(readExpr("-774763251095801167872")) == "-774763251095801167872"
|
||||
|
||||
def test_readExpr_lint_str_big3_neg():
|
||||
assert str(readExpr("-7747632510958011678729003251095801167999")) == "-7747632510958011678729003251095801167999"
|
||||
|
||||
def test_readExpr_lflt_str():
|
||||
assert str(readExpr("3.142")) == "3.142"
|
||||
|
||||
def test_readExpr_lstr_str_unicode():
|
||||
assert str(readExpr("\"açġħ\"")) == "\"açġħ\""
|
||||
|
||||
def test_readExpr_lstr_null():
|
||||
assert str(ExprLit("ab\0c")) == "\"ab\\0c\""
|
||||
|
||||
def test_readExpr_lstr_newline():
|
||||
assert str(ExprLit("ab\nc")) == "\"ab\\nc\""
|
||||
|
||||
# expressions: functions
|
||||
|
||||
def test_readExpr_efun_equality_1():
|
||||
assert readExpr("f") == ExprFun("f")
|
||||
|
||||
def test_readExpr_efun_equality_2():
|
||||
assert \
|
||||
readExpr("f x y") == \
|
||||
ExprApp(
|
||||
ExprApp(
|
||||
ExprFun("f"),
|
||||
ExprFun("x")
|
||||
),
|
||||
ExprFun("y")
|
||||
)
|
||||
|
||||
def test_readExpr_efun_equality_3():
|
||||
assert \
|
||||
readExpr("f (g x)") == \
|
||||
ExprApp(
|
||||
ExprFun("f"),
|
||||
ExprApp(
|
||||
ExprFun("g"),
|
||||
ExprFun("x")
|
||||
)
|
||||
)
|
||||
|
||||
def test_readExpr_efun_equality_4():
|
||||
assert \
|
||||
readExpr("f {g x}") == \
|
||||
ExprApp(
|
||||
ExprFun("f"),
|
||||
ExprImplArg(
|
||||
ExprApp(
|
||||
ExprFun("g"),
|
||||
ExprFun("x")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def test_readExpr_efun_str_unicode_1():
|
||||
assert str(readExpr("'абв'")) == "'абв'"
|
||||
|
||||
@pytest.mark.skip(reason="failing")
|
||||
def test_readExpr_efun_str_unicode_2():
|
||||
assert str(readExpr("'аb'")) == "аb"
|
||||
|
||||
@pytest.mark.skip(reason="failing")
|
||||
def test_readExpr_efun_str_unicode_3():
|
||||
assert str(readExpr("'а\\'b'")) == "а'b"
|
||||
|
||||
def test_readExpr_efun_str_unicode_4():
|
||||
assert str(readExpr("'а\\'б'")) == "'а\\'б'"
|
||||
|
||||
# expressions: variables
|
||||
|
||||
# def test_readExpr_evar_equality_1():
|
||||
# assert readExpr("#0") == ExprVar()
|
||||
# assert readExpr("#0") == ExprVar(0)
|
||||
|
||||
# def test_readExpr_evar_equality_2():
|
||||
# assert readExpr("#42") == ExprVar(42)
|
||||
|
||||
def test_readExpr_evar_str_1():
|
||||
assert str(ExprVar(0)) == "#0"
|
||||
|
||||
def test_readExpr_evar_str_2():
|
||||
assert str(ExprVar(42)) == "#42"
|
||||
|
||||
def test_showExpr_evar_1():
|
||||
assert showExpr(["x"], ExprVar(0)) == "x"
|
||||
|
||||
def test_showExpr_evar_2():
|
||||
assert showExpr(["x"], ExprVar(1)) == "#1"
|
||||
|
||||
def test_showExpr_evar_3():
|
||||
assert showExpr(["z", "y", "x"], ExprVar(0)) == "z"
|
||||
|
||||
def test_showExpr_evar_4():
|
||||
assert showExpr(["z", "y", "x"], ExprVar(1)) == "y"
|
||||
|
||||
# expressions: lambda abstractions
|
||||
|
||||
def test_showExpr_eabs_1():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "w", ExprVar(0))
|
||||
assert showExpr(["z", "y", "x"], expr) == "\\w->w"
|
||||
|
||||
def test_showExpr_eabs_2():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "w", ExprVar(2)))
|
||||
assert showExpr(["z", "y", "x"], expr) == "\\v,w->z"
|
||||
|
||||
def test_showExpr_eabs_3():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprVar(2)))
|
||||
assert showExpr(["z", "y", "x"], expr) == "\\v,{w}->z"
|
||||
|
||||
def test_showExpr_eabs_4():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_EXPLICIT, "z", ExprVar(0))))
|
||||
assert showExpr(["y", "x"], expr) == "\\v,{w},z->z"
|
||||
|
||||
def test_showExpr_eabs_5():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprVar(2))))
|
||||
assert showExpr(["y", "x"], expr) == "\\v,{w,z}->v"
|
||||
|
||||
def test_showExpr_eabs_6():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprAbs(BIND_TYPE_EXPLICIT, "t", ExprVar(3)))))
|
||||
assert showExpr(["y", "x"], expr) == "\\v,{w,z},t->v"
|
||||
|
||||
def test_showExpr_eabs_7():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "u", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_IMPLICIT, "w", ExprAbs(BIND_TYPE_IMPLICIT, "z", ExprAbs(BIND_TYPE_EXPLICIT, "t", ExprVar(3))))))
|
||||
assert showExpr(["y", "x"], expr) == "\\u,v,{w,z},t->v"
|
||||
|
||||
def test_showExpr_eabs_8():
|
||||
expr = ExprApp(ExprFun("f"), ExprAbs(BIND_TYPE_EXPLICIT, "x", ExprVar(0)))
|
||||
assert showExpr([], expr) == "f (\\x->x)"
|
||||
|
||||
def test_showExpr_eabs_freshvars_1():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(0)))
|
||||
assert showExpr([], expr) == "\\v,v1->v1"
|
||||
|
||||
def test_showExpr_eabs_freshvars_2():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(1)))
|
||||
assert showExpr([], expr) == "\\v,v1->v"
|
||||
|
||||
def test_showExpr_eabs_freshvars_3():
|
||||
expr = ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprAbs(BIND_TYPE_EXPLICIT, "v", ExprVar(1))))
|
||||
assert showExpr([], expr) == "\\v,v1,v2->v1"
|
||||
|
||||
# expressions: meta variables
|
||||
|
||||
def test_readExpr_emeta_1():
|
||||
assert readExpr("?") == ExprMeta()
|
||||
assert readExpr("?") == ExprMeta(0)
|
||||
|
||||
def test_readExpr_emeta_2():
|
||||
assert readExpr("?42") == ExprMeta(42)
|
||||
|
||||
def test_readExpr_emeta_str_1():
|
||||
assert str(readExpr("?")) == "?"
|
||||
|
||||
def test_readExpr_emeta_str_2():
|
||||
assert str(readExpr("?42")) == "?42"
|
||||
|
||||
# expressions: typed expressions
|
||||
|
||||
def test_readExpr_emeta_equality():
|
||||
assert readExpr("<z : N>") == ExprTyped(ExprFun("z"), readType("N"))
|
||||
|
||||
def test_readExpr_emeta_str():
|
||||
assert str(readExpr("<z : N>")) == "<z : N>"
|
||||
71
src/runtime/python/tests/test_transactions.py
Normal file
71
src/runtime/python/tests/test_transactions.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import pytest
|
||||
from pgf import *
|
||||
import math
|
||||
|
||||
ty = readType("(N -> N) -> P (s z)")
|
||||
prob = math.pi
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def gr1():
|
||||
return readPGF("../haskell/tests/basic.pgf")
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def gr2(gr1):
|
||||
t = gr1.newTransaction()
|
||||
t.createFunction("foo", ty, 0, prob),
|
||||
t.createCategory("Q", [(BIND_TYPE_EXPLICIT, "x", ty)], prob)
|
||||
assert t.commit()
|
||||
return gr1
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def gr3():
|
||||
# TODO how to avoid reloading from file?
|
||||
gr1 = readPGF("../haskell/tests/basic.pgf")
|
||||
with gr1.newTransaction("bar_branch") as t:
|
||||
t.createFunction("bar", ty, 0, prob),
|
||||
t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob)
|
||||
return gr1
|
||||
|
||||
# gr1
|
||||
|
||||
def test_original_functions(gr1):
|
||||
assert gr1.functions == ["c", "ind", "s", "z"]
|
||||
|
||||
def test_original_categories(gr1):
|
||||
assert gr1.categories == ["Float","Int","N","P","S","String"]
|
||||
|
||||
def test_original_function_type(gr1):
|
||||
with pytest.raises(KeyError):
|
||||
gr1.functionType("foo")
|
||||
|
||||
def test_original_function_prob(gr1):
|
||||
# with pytest.raises(KeyError):
|
||||
# gr1.functionProbability("foo")
|
||||
assert gr1.functionProbability("foo") == float('inf')
|
||||
|
||||
# gr2
|
||||
|
||||
def test_extended_functions(gr2):
|
||||
assert gr2.functions == ["c", "foo", "ind", "s", "z"]
|
||||
|
||||
def test_extended_categories(gr2):
|
||||
assert gr2.categories == ["Float","Int","N","P","Q","S","String"]
|
||||
|
||||
def test_extended_category_context(gr2):
|
||||
assert gr2.categoryContext("Q") == [(BIND_TYPE_EXPLICIT, "x", ty)]
|
||||
|
||||
def test_extended_function_type(gr2):
|
||||
assert gr2.functionType("foo") == ty
|
||||
|
||||
def test_extended_function_prob(gr2):
|
||||
# TODO: can't we get higher precision?
|
||||
# assert gr2.functionProbability("foo") == prob
|
||||
assert math.isclose(gr2.functionProbability("foo"), prob, rel_tol=1e-06)
|
||||
|
||||
# gr3
|
||||
|
||||
def test_branched_functions(gr3):
|
||||
assert gr3.functions == ["bar", "c", "ind", "s", "z"]
|
||||
|
||||
def test_branched_function_type(gr3):
|
||||
assert gr3.functionType("bar") == ty
|
||||
276
src/runtime/python/transactions.c
Normal file
276
src/runtime/python/transactions.c
Normal file
@@ -0,0 +1,276 @@
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
#include "./expr.h"
|
||||
#include "./ffi.h"
|
||||
#include "./transactions.h"
|
||||
|
||||
TransactionObject *
|
||||
PGF_newTransaction(PGFObject *self, PyObject *args)
|
||||
{
|
||||
PgfText *name = NULL;
|
||||
const char *s = NULL;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "|s#", &s, &size))
|
||||
return NULL;
|
||||
|
||||
if (s != NULL) {
|
||||
name = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
|
||||
memcpy(name->text, s, size+1);
|
||||
name->size = size;
|
||||
}
|
||||
|
||||
PgfExn err;
|
||||
PgfRevision rev = pgf_clone_revision(self->db, self->revision, name, &err);
|
||||
if (name != NULL) {
|
||||
PyMem_Free(name);
|
||||
}
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TransactionObject *trans = (TransactionObject *)pgf_TransactionType.tp_alloc(&pgf_TransactionType, 0);
|
||||
trans->pgf = self;
|
||||
trans->revision = rev;
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_commit(TransactionObject *self, PyObject *args)
|
||||
{
|
||||
PgfExn err;
|
||||
pgf_commit_revision(self->pgf->db, self->revision, &err);
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pgf_free_revision(self->pgf->db, self->pgf->revision);
|
||||
self->pgf->revision = self->revision;
|
||||
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_createFunction(TransactionObject *self, PyObject *args)
|
||||
{
|
||||
const char *s;
|
||||
Py_ssize_t size;
|
||||
TypeObject *type;
|
||||
Py_ssize_t arity = 0;
|
||||
float prob = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "s#O!nf", &s, &size, &pgf_TypeType, &type, &arity, &prob))
|
||||
return NULL;
|
||||
|
||||
PgfText *fname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
|
||||
memcpy(fname->text, s, size+1);
|
||||
fname->size = size;
|
||||
|
||||
PgfExn err;
|
||||
pgf_create_function(self->pgf->db, self->revision, fname, (PgfType) type, arity, prob, &marshaller, &err);
|
||||
PyMem_Free(fname);
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_dropFunction(TransactionObject *self, PyObject *args)
|
||||
{
|
||||
const char *s;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "s#", &s, &size))
|
||||
return NULL;
|
||||
|
||||
PgfText *fname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
|
||||
memcpy(fname->text, s, size+1);
|
||||
fname->size = size;
|
||||
|
||||
PgfExn err;
|
||||
pgf_drop_category(self->pgf->db, self->revision, fname, &err);
|
||||
PyMem_Free(fname);
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_createCategory(TransactionObject *self, PyObject *args)
|
||||
{
|
||||
const char *s;
|
||||
Py_ssize_t size;
|
||||
PyObject *hypos;
|
||||
float prob = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "s#O!f", &s, &size, &PyList_Type, &hypos, prob))
|
||||
return NULL;
|
||||
|
||||
PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
|
||||
memcpy(catname->text, s, size+1);
|
||||
catname->size = size;
|
||||
|
||||
Py_ssize_t n_hypos = PyList_Size(hypos);
|
||||
PgfTypeHypo context[n_hypos];
|
||||
// PgfTypeHypo *context = alloca(sizeof(PgfTypeHypo)*n_hypos);
|
||||
for (Py_ssize_t i = 0; i < n_hypos; i++) {
|
||||
PyObject *hytup = (PyObject *)PyList_GetItem(hypos, i);
|
||||
context[i].bind_type = PyLong_AsLong(PyTuple_GetItem(hytup, 0));
|
||||
context[i].cid = PyUnicode_AsPgfText(PyTuple_GetItem(hytup, 1));
|
||||
context[i].type = (PgfType) PyTuple_GetItem(hytup, 2);
|
||||
Py_INCREF(context[i].type);
|
||||
}
|
||||
|
||||
PgfExn err;
|
||||
pgf_create_category(self->pgf->db, self->revision, catname, n_hypos, context, prob, &marshaller, &err);
|
||||
PyMem_Free(catname);
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_dropCategory(TransactionObject *self, PyObject *args)
|
||||
{
|
||||
const char *s;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "s#", &s, &size))
|
||||
return NULL;
|
||||
|
||||
PgfText *catname = (PgfText *)PyMem_Malloc(sizeof(PgfText)+size+1);
|
||||
memcpy(catname->text, s, size+1);
|
||||
catname->size = size;
|
||||
|
||||
PgfExn err;
|
||||
pgf_drop_function(self->pgf->db, self->revision, catname, &err);
|
||||
PyMem_Free(catname);
|
||||
if (handleError(err) != PGF_EXN_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static TransactionObject *
|
||||
Transaction_enter(TransactionObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Transaction_exit(TransactionObject *self, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
// PyObject *exc_type = Py_None;
|
||||
// PyObject *exc_value = Py_None;
|
||||
// PyObject *exc_tb = Py_None;
|
||||
|
||||
// if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) {
|
||||
// Py_RETURN_FALSE;
|
||||
// }
|
||||
if (nargs < 1) {
|
||||
goto skip_optional;
|
||||
}
|
||||
// exc_type = args[0];
|
||||
// if (nargs < 2) {
|
||||
// goto skip_optional;
|
||||
// }
|
||||
// exc_value = args[1];
|
||||
// if (nargs < 3) {
|
||||
// goto skip_optional;
|
||||
// }
|
||||
// exc_tb = args[2];
|
||||
skip_optional:
|
||||
// TODO check exception
|
||||
|
||||
return Transaction_commit(self, NULL);
|
||||
}
|
||||
|
||||
// static void
|
||||
// Transaction_dealloc(PGFObject* self)
|
||||
// {
|
||||
// Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
// }
|
||||
|
||||
static PyGetSetDef Transaction_getseters[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyMemberDef Transaction_members[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyMethodDef Transaction_methods[] = {
|
||||
{"commit", (PyCFunction)Transaction_commit, METH_VARARGS,
|
||||
"Commit transaction"
|
||||
},
|
||||
|
||||
{"__enter__", (PyCFunction)Transaction_enter, METH_NOARGS,
|
||||
""
|
||||
},
|
||||
|
||||
{"__exit__", (PyCFunction)(void(*)(void))Transaction_exit, METH_FASTCALL,
|
||||
""
|
||||
},
|
||||
|
||||
{"createFunction", (PyCFunction)Transaction_createFunction, METH_VARARGS,
|
||||
"Create function"
|
||||
},
|
||||
{"dropFunction", (PyCFunction)Transaction_dropFunction, METH_VARARGS,
|
||||
"Drop function"
|
||||
},
|
||||
{"createCategory", (PyCFunction)Transaction_createCategory, METH_VARARGS,
|
||||
"Create category"
|
||||
},
|
||||
{"dropCategory", (PyCFunction)Transaction_dropCategory, METH_VARARGS,
|
||||
"Drop category"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject pgf_TransactionType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
//0, /*ob_size*/
|
||||
"pgf.Transaction", /*tp_name*/
|
||||
sizeof(TransactionObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
0, //(destructor)Transaction_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, /*tp_hash */
|
||||
0, /*tp_call*/
|
||||
0, // (reprfunc) Transaction_str, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
"Transaction object", /*tp_doc*/
|
||||
0, /*tp_traverse */
|
||||
0, /*tp_clear */
|
||||
0, /*tp_richcompare */
|
||||
0, /*tp_weaklistoffset */
|
||||
0, /*tp_iter */
|
||||
0, /*tp_iternext */
|
||||
Transaction_methods, /*tp_methods */
|
||||
Transaction_members, /*tp_members */
|
||||
Transaction_getseters, /*tp_getset */
|
||||
0, /*tp_base */
|
||||
0, /*tp_dict */
|
||||
0, /*tp_descr_get */
|
||||
0, /*tp_descr_set */
|
||||
0, /*tp_dictoffset */
|
||||
0, /*tp_init */
|
||||
0, /*tp_alloc */
|
||||
0, /*tp_new */
|
||||
};
|
||||
20
src/runtime/python/transactions.h
Normal file
20
src/runtime/python/transactions.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef PYPGF_TRANSACTIONS_H_
|
||||
#define PYPGF_TRANSACTIONS_H_
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
|
||||
#include <pgf/pgf.h>
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PGFObject *pgf; // original reference, gets updated on commit
|
||||
PgfRevision revision; // transient branch
|
||||
} TransactionObject;
|
||||
|
||||
PyTypeObject pgf_TransactionType;
|
||||
|
||||
TransactionObject *
|
||||
PGF_newTransaction(PGFObject *self, PyObject *args);
|
||||
|
||||
#endif // PYPGF_TRANSACTIONS_H_
|
||||
Reference in New Issue
Block a user