From 9cea2cc70ed247ea00f2e744ec56824595914d87 Mon Sep 17 00:00:00 2001 From: krangelov Date: Mon, 6 Sep 2021 15:49:39 +0200 Subject: [PATCH] change the API to allow different grammar revisions --- src/runtime/c/pgf/data.h | 18 +-- src/runtime/c/pgf/db.cxx | 20 +-- src/runtime/c/pgf/db.h | 16 +-- src/runtime/c/pgf/expr.cxx | 26 ++-- src/runtime/c/pgf/namespace.h | 2 +- src/runtime/c/pgf/pgf.cxx | 192 +++++++++++++++++------------ src/runtime/c/pgf/pgf.h | 68 ++++++---- src/runtime/c/pgf/reader.cxx | 24 ++-- src/runtime/c/pgf/reader.h | 2 +- src/runtime/c/pgf/vector.h | 4 +- src/runtime/haskell/PGF2.hsc | 83 ++++++++----- src/runtime/haskell/PGF2/FFI.hsc | 43 ++++--- src/runtime/haskell/tests/basic.hs | 3 + src/runtime/python/pypgf.c | 23 ++-- 14 files changed, 298 insertions(+), 226 deletions(-) diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index a528db6f3..5886ab710 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -107,26 +107,12 @@ typedef struct { Namespace cats; } PgfAbstr; -struct PGF_INTERNAL_DECL PgfPGFRoot { +typedef struct PGF_INTERNAL_DECL { uint16_t major_version; uint16_t minor_version; Namespace gflags; PgfAbstr abstract; //PgfConcrs* concretes; -}; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" - -struct PgfPGF : DB { - PGF_INTERNAL_DECL PgfPGF(const char* fpath, int flags, int mode) - : DB(fpath, flags, mode) - { }; - - PGF_INTERNAL_DECL ~PgfPGF() - { }; -}; - -#pragma GCC diagnostic pop +} PgfPGF; #endif diff --git a/src/runtime/c/pgf/db.cxx b/src/runtime/c/pgf/db.cxx index 9f6758b70..ac952f56a 100644 --- a/src/runtime/c/pgf/db.cxx +++ b/src/runtime/c/pgf/db.cxx @@ -7,7 +7,7 @@ #include "data.h" PGF_INTERNAL __thread unsigned char* current_base __attribute__((tls_model("initial-exec"))) = NULL; -PGF_INTERNAL __thread DB* current_db __attribute__((tls_model("initial-exec"))) = NULL; +PGF_INTERNAL __thread PgfDB* current_db __attribute__((tls_model("initial-exec"))) = NULL; PGF_INTERNAL __thread DB_scope *last_db_scope __attribute__((tls_model("initial-exec"))) = NULL; #ifndef DEFAULT_TOP_PAD @@ -269,7 +269,7 @@ struct malloc_state object root_offset; }; -DB::DB(const char* pathname, int flags, int mode) { +PgfDB::PgfDB(const char* pathname, int flags, int mode) { size_t file_size; bool is_new = false; @@ -313,7 +313,7 @@ DB::DB(const char* pathname, int flags, int mode) { } } -DB::~DB() { +PgfDB::~PgfDB() { if (ms != NULL) { size_t size = ms->top + chunksize(ptr(ms,ms->top)) + sizeof(size_t); @@ -327,7 +327,7 @@ DB::~DB() { pthread_rwlock_destroy(&rwlock); } -void DB::sync() +void PgfDB::sync() { malloc_state *ms = current_db->ms; size_t size = @@ -338,16 +338,16 @@ void DB::sync() throw std::system_error(errno, std::generic_category()); } -object DB::get_root_internal() { +object PgfDB::get_root_internal() { return ms->root_offset; } -void DB::set_root_internal(object root_offset) { +void PgfDB::set_root_internal(object root_offset) { ms->root_offset = root_offset; } void -DB::init_state(size_t size) +PgfDB::init_state(size_t size) { /* Init fastbins */ ms->have_fastchunks = false; @@ -483,7 +483,7 @@ static void malloc_consolidate(malloc_state *ms) } object -DB::malloc_internal(size_t bytes) +PgfDB::malloc_internal(size_t bytes) { unsigned int idx; /* associated bin index */ mbin* bin; /* associated bin */ @@ -856,7 +856,7 @@ DB::malloc_internal(size_t bytes) } void -DB::free_internal(object o) +PgfDB::free_internal(object o) { size_t size; /* its size */ object *fb; /* associated fastbin */ @@ -948,7 +948,7 @@ DB::free_internal(object o) } -DB_scope::DB_scope(DB *db, DB_scope_mode tp) +DB_scope::DB_scope(PgfDB *db, DB_scope_mode tp) { int res = (tp == READER_SCOPE) ? pthread_rwlock_rdlock(&db->rwlock) diff --git a/src/runtime/c/pgf/db.h b/src/runtime/c/pgf/db.h index 748d60e88..768913b72 100644 --- a/src/runtime/c/pgf/db.h +++ b/src/runtime/c/pgf/db.h @@ -3,10 +3,10 @@ #define MALLOC_ALIGN_MASK (2*sizeof(size_t) - 1) -class DB; +class PgfDB; extern PGF_INTERNAL_DECL __thread unsigned char* current_base __attribute__((tls_model("initial-exec"))); -extern PGF_INTERNAL_DECL __thread DB* current_db __attribute__((tls_model("initial-exec"))); +extern PGF_INTERNAL_DECL __thread PgfDB* current_db __attribute__((tls_model("initial-exec"))); struct malloc_state; @@ -14,7 +14,7 @@ template class PGF_INTERNAL_DECL ref { private: object offset; - friend class DB; + friend class PgfDB; public: ref() { } @@ -54,7 +54,7 @@ public: } }; -class PGF_INTERNAL_DECL DB { +class PgfDB { private: int fd; malloc_state* ms; @@ -64,8 +64,8 @@ private: friend class PgfReader; public: - DB(const char* pathname, int flags, int mode); - ~DB(); + PgfDB(const char* pathname, int flags, int mode); + ~PgfDB(); template static ref malloc() { @@ -112,11 +112,11 @@ enum DB_scope_mode {READER_SCOPE, WRITER_SCOPE}; class PGF_INTERNAL_DECL DB_scope { public: - DB_scope(DB *db, DB_scope_mode type); + DB_scope(PgfDB *db, DB_scope_mode type); ~DB_scope(); private: - DB* save_db; + PgfDB* save_db; DB_scope* next_scope; }; diff --git a/src/runtime/c/pgf/expr.cxx b/src/runtime/c/pgf/expr.cxx index bbb4cfb8f..603739604 100644 --- a/src/runtime/c/pgf/expr.cxx +++ b/src/runtime/c/pgf/expr.cxx @@ -111,7 +111,7 @@ PgfType PgfDBMarshaller::match_type(PgfUnmarshaller *u, PgfType ty) PgfExpr PgfDBUnmarshaller::eabs(PgfBindType bind_type, PgfText *name, PgfExpr body) { ref eabs = - DB::malloc(sizeof(PgfExprAbs)+name->size+1); + PgfDB::malloc(sizeof(PgfExprAbs)+name->size+1); eabs->bind_type = bind_type; eabs->body = m->match_expr(this, body); memcpy(&eabs->name, name, sizeof(PgfText)+name->size+1); @@ -120,7 +120,7 @@ PgfExpr PgfDBUnmarshaller::eabs(PgfBindType bind_type, PgfText *name, PgfExpr bo PgfExpr PgfDBUnmarshaller::eapp(PgfExpr fun, PgfExpr arg) { - ref eapp = DB::malloc(); + ref eapp = PgfDB::malloc(); eapp->fun = m->match_expr(this, fun); eapp->arg = m->match_expr(this, arg); return ref::tagged(eapp); @@ -128,14 +128,14 @@ PgfExpr PgfDBUnmarshaller::eapp(PgfExpr fun, PgfExpr arg) PgfExpr PgfDBUnmarshaller::elit(PgfLiteral lit) { - ref elit = DB::malloc(); + ref elit = PgfDB::malloc(); elit->lit = m->match_lit(this, lit); return ref::tagged(elit); } PgfExpr PgfDBUnmarshaller::emeta(PgfMetaId meta_id) { - ref emeta = DB::malloc(); + ref emeta = PgfDB::malloc(); emeta->id = meta_id; return ref::tagged(emeta); } @@ -143,21 +143,21 @@ PgfExpr PgfDBUnmarshaller::emeta(PgfMetaId meta_id) PgfExpr PgfDBUnmarshaller::efun(PgfText *name) { ref efun = - DB::malloc(sizeof(PgfExprFun)+name->size+1); + PgfDB::malloc(sizeof(PgfExprFun)+name->size+1); memcpy(&efun->name, name, sizeof(PgfText)+name->size+1); return ref::tagged(efun); } PgfExpr PgfDBUnmarshaller::evar(int index) { - ref evar = DB::malloc(); + ref evar = PgfDB::malloc(); evar->var = index; return ref::tagged(evar); } PgfExpr PgfDBUnmarshaller::etyped(PgfExpr expr, PgfType ty) { - ref etyped = DB::malloc(); + ref etyped = PgfDB::malloc(); etyped->expr = m->match_expr(this, expr); etyped->type = m->match_type(this, ty); return ref::tagged(etyped); @@ -173,7 +173,7 @@ PgfExpr PgfDBUnmarshaller::eimplarg(PgfExpr expr) PgfLiteral PgfDBUnmarshaller::lint(size_t size, uintmax_t *val) { ref lit_int = - DB::malloc(sizeof(PgfLiteralInt)+size*sizeof(uintmax_t)); + PgfDB::malloc(sizeof(PgfLiteralInt)+size*sizeof(uintmax_t)); lit_int->size = size; memcpy(&lit_int->val, val, size*sizeof(uintmax_t)); return ref::tagged(lit_int); @@ -181,7 +181,7 @@ PgfLiteral PgfDBUnmarshaller::lint(size_t size, uintmax_t *val) PgfLiteral PgfDBUnmarshaller::lflt(double val) { - ref lit_flt = DB::malloc(); + ref lit_flt = PgfDB::malloc(); lit_flt->val = val; return ref::tagged(lit_flt); } @@ -189,7 +189,7 @@ PgfLiteral PgfDBUnmarshaller::lflt(double val) PgfLiteral PgfDBUnmarshaller::lstr(PgfText *val) { ref lit_str = - DB::malloc(sizeof(PgfLiteralStr)+val->size+1); + PgfDB::malloc(sizeof(PgfLiteralStr)+val->size+1); memcpy(&lit_str->val, val, sizeof(PgfText)+val->size+1); return ref::tagged(lit_str); } @@ -199,13 +199,13 @@ PgfType PgfDBUnmarshaller::dtyp(int n_hypos, PgfTypeHypo *hypos, int n_exprs, PgfExpr *exprs) { ref ty = - DB::malloc(sizeof(PgfDTyp)+cat->size+1); + PgfDB::malloc(sizeof(PgfDTyp)+cat->size+1); memcpy(&ty->name, cat, sizeof(PgfText)+cat->size+1); ty->hypos = vector_new(n_hypos); for (size_t i = 0; i < n_hypos; i++) { ref hypo = vector_elem(ty->hypos,i); hypo->bind_type = hypos[i].bind_type; - hypo->cid = DB::malloc(sizeof(PgfText)+hypos[i].cid->size+1); + hypo->cid = PgfDB::malloc(sizeof(PgfText)+hypos[i].cid->size+1); memcpy(&hypo->cid->text, hypos[i].cid, sizeof(PgfText)+hypos[i].cid->size+1); hypo->type = m->match_type(this, hypos[i].type); } @@ -219,7 +219,7 @@ PgfType PgfDBUnmarshaller::dtyp(int n_hypos, PgfTypeHypo *hypos, void PgfDBUnmarshaller::free_ref(object x) { - DB::free(ref::untagged(x)); + PgfDB::free(ref::untagged(x)); } PgfExprParser::PgfExprParser(PgfText *input, PgfUnmarshaller *unmarshaller) diff --git a/src/runtime/c/pgf/namespace.h b/src/runtime/c/pgf/namespace.h index 686f18bd0..96faab9cd 100644 --- a/src/runtime/c/pgf/namespace.h +++ b/src/runtime/c/pgf/namespace.h @@ -339,7 +339,7 @@ void namespace_release(Namespace node) if (!(--node->ref_count)) { namespace_release(node->left); namespace_release(node->right); - DB::free(node); + PgfDB::free(node); } } diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index 55ee35880..e03ebf7a4 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -13,15 +13,16 @@ pgf_exn_clear(PgfExn* err) } PGF_API -PgfPGF *pgf_read_pgf(const char* fpath, - PgfExn* err) +PgfDB *pgf_read_pgf(const char* fpath, + PgfRevision *revision, + PgfExn* err) { - PgfPGF *pgf = NULL; + PgfDB *db = NULL; pgf_exn_clear(err); try { - pgf = new PgfPGF(NULL, 0, 0); + db = new PgfDB(NULL, 0, 0); std::ifstream in(fpath, std::ios::binary); if (in.fail()) { @@ -29,15 +30,16 @@ PgfPGF *pgf_read_pgf(const char* fpath, } { - DB_scope scope(pgf, WRITER_SCOPE); + DB_scope scope(db, WRITER_SCOPE); PgfReader rdr(&in); - ref pgf_root = rdr.read_pgf(); + ref pgf = rdr.read_pgf(); - pgf->set_root(pgf_root); + PgfDB::set_root(pgf); + *revision = pgf.as_object(); } - return pgf; + return db; } catch (std::system_error& e) { err->type = PGF_EXN_SYSTEM_ERROR; err->code = e.code().value(); @@ -46,22 +48,23 @@ PgfPGF *pgf_read_pgf(const char* fpath, err->msg = strdup(e.what()); } - if (pgf != NULL) - delete pgf; + if (db != NULL) + delete db; return NULL; } PGF_API -PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, - PgfExn* err) +PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, + PgfRevision *revision, + PgfExn* err) { - PgfPGF *pgf = NULL; + PgfDB *db = NULL; pgf_exn_clear(err); try { - pgf = new PgfPGF(ngf_path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); + db = new PgfDB(ngf_path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); std::ifstream in(pgf_path, std::ios::binary); if (in.fail()) { @@ -69,17 +72,18 @@ PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, } { - DB_scope scope(pgf, WRITER_SCOPE); + DB_scope scope(db, WRITER_SCOPE); PgfReader rdr(&in); - ref pgf_root = rdr.read_pgf(); + ref pgf = rdr.read_pgf(); - pgf->set_root(pgf_root); + db->set_root(pgf); + *revision = pgf.as_object(); - DB::sync(); + PgfDB::sync(); } - return pgf; + return db; } catch (std::system_error& e) { err->type = PGF_EXN_SYSTEM_ERROR; err->code = e.code().value(); @@ -88,8 +92,8 @@ PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, err->msg = strdup(e.what()); } - if (pgf != NULL) { - delete pgf; + if (db != NULL) { + delete db; remove(ngf_path); } @@ -97,36 +101,40 @@ PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, } PGF_API -PgfPGF *pgf_read_ngf(const char *fpath, +PgfDB *pgf_read_ngf(const char *fpath, + PgfRevision *revision, PgfExn* err) { - PgfPGF *pgf = NULL; + PgfDB *db = NULL; pgf_exn_clear(err); bool is_new = false; try { - pgf = new PgfPGF(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + db = new PgfDB(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); { - DB_scope scope(pgf, WRITER_SCOPE); + DB_scope scope(db, WRITER_SCOPE); - if (DB::get_root() == 0) { + if (PgfDB::get_root() == 0) { is_new = true; - ref root = DB::malloc(); - root->major_version = 2; - root->minor_version = 0; - root->gflags = 0; - root->abstract.name = DB::malloc(); - root->abstract.name->size = 0; - root->abstract.aflags = 0; - root->abstract.funs = 0; - root->abstract.cats = 0; - DB::set_root(root); + ref pgf = PgfDB::malloc(); + pgf->major_version = 2; + pgf->minor_version = 0; + pgf->gflags = 0; + pgf->abstract.name = PgfDB::malloc(); + pgf->abstract.name->size = 0; + pgf->abstract.aflags = 0; + pgf->abstract.funs = 0; + pgf->abstract.cats = 0; + PgfDB::set_root(pgf); + *revision = pgf.as_object(); + } else { + *revision = PgfDB::get_root().as_object(); } } - return pgf; + return db; } catch (std::system_error& e) { err->type = PGF_EXN_SYSTEM_ERROR; err->code = e.code().value(); @@ -135,8 +143,8 @@ PgfPGF *pgf_read_ngf(const char *fpath, err->msg = strdup(e.what()); } - if (pgf != NULL) { - delete pgf; + if (db != NULL) { + delete db; if (is_new) remove(fpath); } @@ -145,32 +153,42 @@ PgfPGF *pgf_read_ngf(const char *fpath, } PGF_API -void pgf_free(PgfPGF *pgf) +void pgf_free(PgfDB *db) +{ + delete db; +} + +PGF_API_DECL +void pgf_free_revision(PgfDB *pgf, PgfRevision revision) { - delete pgf; } PGF_API -PgfText *pgf_abstract_name(PgfPGF* pgf) +PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - return textdup(&(*pgf->get_root()->abstract.name)); + return textdup(&(*pgf->abstract.name)); } PGF_API -void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor, PgfExn *err) +void pgf_iter_categories(PgfDB *db, PgfRevision revision, + PgfItor *itor, PgfExn *err) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; err->type = PGF_EXN_NONE; - namespace_iter(pgf->get_root()->abstract.cats, itor, err); + namespace_iter(pgf->abstract.cats, itor, err); } PGF_API -PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u) +PgfType pgf_start_cat(PgfDB *db, PgfRevision revision, + PgfUnmarshaller *u) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; PgfText *startcat = (PgfText *) alloca(sizeof(PgfText)+9); @@ -178,7 +196,7 @@ PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u) strcpy(startcat->text, "startcat"); ref flag = - namespace_lookup(pgf->get_root()->abstract.aflags, startcat); + namespace_lookup(pgf->abstract.aflags, startcat); if (flag != 0) { switch (ref::get_tag(flag->value)) { @@ -202,12 +220,14 @@ PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u) } PGF_API -PgfTypeHypo *pgf_category_context(PgfPGF *pgf, PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u) +PgfTypeHypo *pgf_category_context(PgfDB *db, PgfRevision revision, + PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; ref abscat = - namespace_lookup(pgf->get_root()->abstract.cats, catname); + namespace_lookup(pgf->abstract.cats, catname); if (abscat == 0) { *n_hypos = 0; return NULL; @@ -228,12 +248,14 @@ PgfTypeHypo *pgf_category_context(PgfPGF *pgf, PgfText *catname, size_t *n_hypos } PGF_API -prob_t pgf_category_prob(PgfPGF *pgf, PgfText *catname) +prob_t pgf_category_prob(PgfDB *db, PgfRevision revision, + PgfText *catname) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; ref abscat = - namespace_lookup(pgf->get_root()->abstract.cats, catname); + namespace_lookup(pgf->abstract.cats, catname); if (abscat == 0) { return 0; } @@ -242,12 +264,14 @@ prob_t pgf_category_prob(PgfPGF *pgf, PgfText *catname) } PGF_API -void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor, PgfExn *err) +void pgf_iter_functions(PgfDB *db, PgfRevision revision, + PgfItor *itor, PgfExn *err) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; err->type = PGF_EXN_NONE; - namespace_iter(pgf->get_root()->abstract.funs, itor, err); + namespace_iter(pgf->abstract.funs, itor, err); } struct PgfItorHelper : PgfItor @@ -267,9 +291,11 @@ void iter_by_cat_helper(PgfItor *itor, PgfText *key, void *value, } PGF_API -void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor, PgfExn *err) +void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision, + PgfText *cat, PgfItor *itor, PgfExn *err) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; PgfItorHelper helper; helper.fn = iter_by_cat_helper; @@ -277,16 +303,18 @@ void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor, PgfExn helper.itor = itor; err->type = PGF_EXN_NONE; - namespace_iter(pgf->get_root()->abstract.funs, &helper, err); + namespace_iter(pgf->abstract.funs, &helper, err); } PGF_API -PgfType pgf_function_type(PgfPGF *pgf, PgfText *funname, PgfUnmarshaller *u) +PgfType pgf_function_type(PgfDB *db, PgfRevision revision, + PgfText *funname, PgfUnmarshaller *u) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; ref absfun = - namespace_lookup(pgf->get_root()->abstract.funs, funname); + namespace_lookup(pgf->abstract.funs, funname); if (absfun == 0) return 0; @@ -294,12 +322,14 @@ PgfType pgf_function_type(PgfPGF *pgf, PgfText *funname, PgfUnmarshaller *u) } PGF_API -int pgf_function_is_constructor(PgfPGF *pgf, PgfText *funname) +int pgf_function_is_constructor(PgfDB *db, PgfRevision revision, + PgfText *funname) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; ref absfun = - namespace_lookup(pgf->get_root()->abstract.funs, funname); + namespace_lookup(pgf->abstract.funs, funname); if (absfun == 0) return false; @@ -307,12 +337,14 @@ int pgf_function_is_constructor(PgfPGF *pgf, PgfText *funname) } PGF_API -prob_t pgf_function_prob(PgfPGF *pgf, PgfText *funname) +prob_t pgf_function_prob(PgfDB *db, PgfRevision revision, + PgfText *funname) { - DB_scope scope(pgf, READER_SCOPE); + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; ref absfun = - namespace_lookup(pgf->get_root()->abstract.funs, funname); + namespace_lookup(pgf->abstract.funs, funname); if (absfun == 0) return INFINITY; @@ -364,16 +396,18 @@ PgfType pgf_read_type(PgfText *input, PgfUnmarshaller *u) } PGF_API -void pgf_create_function(PgfPGF *pgf, PgfText *name, +void pgf_create_function(PgfDB *db, PgfRevision revision, + PgfText *name, PgfType ty, prob_t prob, - PgfMarshaller *m) + PgfMarshaller *m, + PgfExn *err) { - DB_scope scope(pgf, WRITER_SCOPE); + DB_scope scope(db, WRITER_SCOPE); PgfDBUnmarshaller u(m); - ref root = pgf->get_root(); - ref absfun = DB::malloc(sizeof(PgfAbsFun)+name->size+1); + ref pgf = revision; + ref absfun = PgfDB::malloc(sizeof(PgfAbsFun)+name->size+1); absfun->type = m->match_type(&u, ty); absfun->arity = 0; absfun->defns = 0; @@ -384,7 +418,7 @@ void pgf_create_function(PgfPGF *pgf, PgfText *name, memcpy(&absfun->name, name, sizeof(PgfText)+name->size+1); Namespace nmsp = - namespace_insert(root->abstract.funs, absfun); - namespace_release(root->abstract.funs); - root->abstract.funs = nmsp; + namespace_insert(pgf->abstract.funs, absfun); + namespace_release(pgf->abstract.funs); + pgf->abstract.funs = nmsp; } diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index f930aacb0..f64d8b1fc 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -210,62 +210,80 @@ struct PgfMarshaller { typedef float prob_t; -typedef struct PgfPGF PgfPGF; +typedef struct PgfDB PgfDB; +typedef object PgfRevision; -/* Reads a PGF file and keeps it in memory. */ +/* Reads a PGF file and builds the database in memory. + * If successful, *revision will contain the initial revision of + * the grammar. */ PGF_API_DECL -PgfPGF *pgf_read_pgf(const char* fpath, - PgfExn* err); +PgfDB *pgf_read_pgf(const char* fpath, PgfRevision *revision, + PgfExn* err); /* Reads a PGF file and stores the unpacked data in an NGF file - * ready to be shared with other process, or used for quick startup. + * ready to be shared with other process, or used for quick re-start. * The NGF file is platform dependent and should not be copied * between machines. */ PGF_API_DECL -PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, - PgfExn* err); +PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, + PgfRevision *revision, + PgfExn* err); /* Tries to read the grammar from an already booted NGF file. * If the file does not exist then a new one is created, and the * grammar is set to be empty. It can later be populated with - * rules dynamically. */ + * rules dynamically. The default grammar revision is stored + * in *revision. */ PGF_API_DECL -PgfPGF *pgf_read_ngf(const char* fpath, - PgfExn* err); +PgfDB *pgf_read_ngf(const char* fpath, + PgfRevision *revision, + PgfExn* err); -/* Release the grammar when it is no longer needed. */ +/* Release the database when it is no longer needed. */ PGF_API_DECL -void pgf_free(PgfPGF *pgf); +void pgf_free(PgfDB *pgf); PGF_API_DECL -PgfText *pgf_abstract_name(PgfPGF *pgf); +void pgf_free_revision(PgfDB *pgf, PgfRevision revision); PGF_API_DECL -void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor, PgfExn *err); +PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision); PGF_API_DECL -PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u); +void pgf_iter_categories(PgfDB *db, PgfRevision revision, + PgfItor *itor, PgfExn *err); PGF_API_DECL -PgfTypeHypo *pgf_category_context(PgfPGF *pgf, PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u); +PgfType pgf_start_cat(PgfDB *db, PgfRevision revision, + PgfUnmarshaller *u); PGF_API_DECL -prob_t pgf_category_prob(PgfPGF* pgf, PgfText *catname); +PgfTypeHypo *pgf_category_context(PgfDB *db, PgfRevision revision, + PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u); PGF_API_DECL -void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor, PgfExn *err); +prob_t pgf_category_prob(PgfDB *db, PgfRevision revision, + PgfText *catname); PGF_API_DECL -void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor, PgfExn *err); +void pgf_iter_functions(PgfDB *db, PgfRevision revision, + PgfItor *itor, PgfExn *err); PGF_API_DECL -PgfType pgf_function_type(PgfPGF *pgf, PgfText *funname, PgfUnmarshaller *u); +void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision, + PgfText *cat, PgfItor *itor, PgfExn *err); PGF_API_DECL -int pgf_function_is_constructor(PgfPGF *pgf, PgfText *funname); +PgfType pgf_function_type(PgfDB *db, PgfRevision revision, + PgfText *funname, PgfUnmarshaller *u); PGF_API_DECL -prob_t pgf_function_prob(PgfPGF *pgf, PgfText *funname); +int pgf_function_is_constructor(PgfDB *db, PgfRevision revision, + PgfText *funname); + +PGF_API_DECL +prob_t pgf_function_prob(PgfDB *db, PgfRevision revision, + PgfText *funname); typedef struct PgfPrintContext PgfPrintContext; @@ -291,8 +309,10 @@ PGF_API_DECL PgfType pgf_read_type(PgfText *input, PgfUnmarshaller *u); PGF_API_DECL -void pgf_create_function(PgfPGF *pgf, PgfText *name, +void pgf_create_function(PgfDB *db, PgfRevision revision, + PgfText *name, PgfType ty, prob_t prob, - PgfMarshaller *m); + PgfMarshaller *m, + PgfExn *err); #endif // PGF_H_ diff --git a/src/runtime/c/pgf/reader.cxx b/src/runtime/c/pgf/reader.cxx index 525bee5f0..00af469e0 100644 --- a/src/runtime/c/pgf/reader.cxx +++ b/src/runtime/c/pgf/reader.cxx @@ -204,7 +204,7 @@ PgfLiteral PgfReader::read_literal() } case PgfLiteralInt::tag: { ref lit_int = - DB::malloc(sizeof(PgfLiteralInt)+sizeof(uintmax_t)); + PgfDB::malloc(sizeof(PgfLiteralInt)+sizeof(uintmax_t)); lit_int->size = 1; lit_int->val[0] = read_int(); lit = ref::tagged(lit_int); @@ -245,20 +245,20 @@ PgfExpr PgfReader::read_expr() break; } case PgfExprApp::tag: { - ref eapp = DB::malloc(); + ref eapp = PgfDB::malloc(); eapp->fun = read_expr(); eapp->arg = read_expr(); expr = ref::tagged(eapp); break; } case PgfExprLit::tag: { - ref elit = DB::malloc(); + ref elit = PgfDB::malloc(); elit->lit = read_literal(); expr = ref::tagged(elit); break; } case PgfExprMeta::tag: { - ref emeta = DB::malloc(); + ref emeta = PgfDB::malloc(); emeta->id = read_int(); expr = ref::tagged(emeta); break; @@ -269,13 +269,13 @@ PgfExpr PgfReader::read_expr() break; } case PgfExprVar::tag: { - ref evar = DB::malloc(); + ref evar = PgfDB::malloc(); evar->var = read_int(); expr = ref::tagged(evar); break; } case PgfExprTyped::tag: { - ref etyped = DB::malloc(); + ref etyped = PgfDB::malloc(); etyped->expr = read_expr(); etyped->type = read_type(); expr = ref::tagged(etyped); @@ -339,24 +339,24 @@ PgfPatt PgfReader::read_patt() break; } case PgfPattWild::tag: { - ref pwild = DB::malloc(); + ref pwild = PgfDB::malloc(); patt = ref::tagged(pwild); break; } case PgfPattLit::tag: { - ref plit = DB::malloc(); + ref plit = PgfDB::malloc(); plit->lit = read_literal(); patt = ref::tagged(plit); break; } case PgfPattImplArg::tag: { - ref pimpl = DB::malloc(); + ref pimpl = PgfDB::malloc(); pimpl->patt = read_patt(); patt = ref::tagged(pimpl); break; } case PgfPattTilde::tag: { - ref ptilde = DB::malloc(); + ref ptilde = PgfDB::malloc(); ptilde->expr = read_expr(); patt = ref::tagged(ptilde); break; @@ -425,9 +425,9 @@ void PgfReader::read_abstract(ref abstract) abstract->cats = read_namespace(&PgfReader::read_abscat); } -ref PgfReader::read_pgf() +ref PgfReader::read_pgf() { - ref pgf = DB::malloc(); + ref pgf = PgfDB::malloc(); pgf->major_version = read_u16be(); pgf->minor_version = read_u16be(); diff --git a/src/runtime/c/pgf/reader.h b/src/runtime/c/pgf/reader.h index 84d763dac..0565ed41d 100644 --- a/src/runtime/c/pgf/reader.h +++ b/src/runtime/c/pgf/reader.h @@ -70,7 +70,7 @@ public: ref read_abscat(); void read_abstract(ref abstract); - ref read_pgf(); + ref read_pgf(); private: std::istream *in; diff --git a/src/runtime/c/pgf/vector.h b/src/runtime/c/pgf/vector.h index f999edaaf..261d69020 100644 --- a/src/runtime/c/pgf/vector.h +++ b/src/runtime/c/pgf/vector.h @@ -10,7 +10,7 @@ struct PgfVector { template inline ref> vector_new(size_t len) { - ref> res = DB::malloc>(sizeof(PgfVector)+len*sizeof(A)); + ref> res = PgfDB::malloc>(sizeof(PgfVector)+len*sizeof(A)); res->len = len; return res; } @@ -18,7 +18,7 @@ ref> vector_new(size_t len) template inline ref vector_new(PgfVector C::* field, size_t len) { - ref res = DB::malloc(((size_t) &(((C*) NULL)->*field))+sizeof(PgfVector)+len*sizeof(A)); + ref res = PgfDB::malloc(((size_t) &(((C*) NULL)->*field))+sizeof(PgfVector)+len*sizeof(A)); (res->*field).len = len; return res; } diff --git a/src/runtime/haskell/PGF2.hsc b/src/runtime/haskell/PGF2.hsc index 0e2dba1a9..34962fb38 100644 --- a/src/runtime/haskell/PGF2.hsc +++ b/src/runtime/haskell/PGF2.hsc @@ -56,6 +56,7 @@ import PGF2.FFI import Foreign import Foreign.C +import qualified Foreign.Concurrent as C import qualified Data.Map as Map import Data.IORef @@ -68,10 +69,13 @@ type ConcName = String -- ^ Name of concrete syntax readPGF :: FilePath -> IO PGF readPGF fpath = withCString fpath $ \c_fpath -> + alloca $ \p_revision -> mask_ $ do - c_pgf <- withPgfExn fpath (pgf_read_pgf c_fpath) - fptr <- newForeignPtr pgf_free_fptr c_pgf - return (PGF fptr Map.empty) + c_pgf <- withPgfExn fpath (pgf_read_pgf c_fpath p_revision) + c_revision <- peek p_revision + fptr1 <- newForeignPtr pgf_free_fptr c_pgf + fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) + return (PGF fptr1 fptr2 Map.empty) -- | Reads a PGF file and stores the unpacked data in an NGF file -- ready to be shared with other process, or used for quick startup. @@ -81,10 +85,13 @@ bootNGF :: FilePath -> FilePath -> IO PGF bootNGF pgf_path ngf_path = withCString pgf_path $ \c_pgf_path -> withCString ngf_path $ \c_ngf_path -> + alloca $ \p_revision -> mask_ $ do - c_pgf <- withPgfExn pgf_path (pgf_boot_ngf c_pgf_path c_ngf_path) - fptr <- newForeignPtr pgf_free_fptr c_pgf - return (PGF fptr Map.empty) + c_pgf <- withPgfExn pgf_path (pgf_boot_ngf c_pgf_path c_ngf_path p_revision) + c_revision <- peek p_revision + fptr1 <- newForeignPtr pgf_free_fptr c_pgf + fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) + return (PGF fptr1 fptr2 Map.empty) -- | Tries to read the grammar from an already booted NGF file. -- If the file does not exist then a new one is created, and the @@ -93,18 +100,22 @@ bootNGF pgf_path ngf_path = readNGF :: FilePath -> IO PGF readNGF fpath = withCString fpath $ \c_fpath -> + alloca $ \p_revision -> mask_ $ do - c_pgf <- withPgfExn fpath (pgf_read_ngf c_fpath) - fptr <- newForeignPtr pgf_free_fptr c_pgf - return (PGF fptr Map.empty) + c_db <- withPgfExn fpath (pgf_read_ngf c_fpath p_revision) + c_revision <- peek p_revision + fptr1 <- newForeignPtr pgf_free_fptr c_db + fptr2 <- C.newForeignPtr c_revision (withForeignPtr fptr1 (\c_db -> pgf_free_revision c_db c_revision)) + return (PGF fptr1 fptr2 Map.empty) -- | The abstract language name is the name of the top-level -- abstract module abstractName :: PGF -> AbsName abstractName p = unsafePerformIO $ - withForeignPtr (a_pgf p) $ \p_pgf -> - bracket (pgf_abstract_name p_pgf) free $ \c_text -> + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> + bracket (pgf_abstract_name c_db c_revision) free $ \c_text -> peekText c_text -- | The start category is defined in the grammar with @@ -116,8 +127,9 @@ startCat :: PGF -> Type startCat p = unsafePerformIO $ withForeignPtr unmarshaller $ \u -> - withForeignPtr (a_pgf p) $ \c_pgf -> do - c_typ <- pgf_start_cat c_pgf u + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> do + c_typ <- pgf_start_cat c_db c_revision u typ <- deRefStablePtr c_typ freeStablePtr c_typ return typ @@ -127,9 +139,10 @@ functionType :: PGF -> Fun -> Maybe Type functionType p fn = unsafePerformIO $ withForeignPtr unmarshaller $ \u -> - withForeignPtr (a_pgf p) $ \p_pgf -> + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> withText fn $ \c_fn -> do - c_typ <- pgf_function_type p_pgf c_fn u + c_typ <- pgf_function_type c_db c_revision c_fn u if c_typ == castPtrToStablePtr nullPtr then return Nothing else do typ <- deRefStablePtr c_typ @@ -140,16 +153,18 @@ functionIsConstructor :: PGF -> Fun -> Bool functionIsConstructor p fun = unsafePerformIO $ withText fun $ \c_fun -> - withForeignPtr (a_pgf p) $ \c_pgf -> - do res <- pgf_function_is_constructor c_pgf c_fun + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> + do res <- pgf_function_is_constructor c_db c_revision c_fun return (res /= 0) functionProb :: PGF -> Fun -> Float functionProb p fun = unsafePerformIO $ withText fun $ \c_fun -> - withForeignPtr (a_pgf p) $ \c_pgf -> - do c_prob <- pgf_function_prob c_pgf c_fun + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> + do c_prob <- pgf_function_prob c_db c_revision c_fun return (realToFrac c_prob) -- | List of all functions defined in the abstract syntax @@ -159,9 +174,10 @@ categories p = ref <- newIORef [] (allocaBytes (#size PgfItor) $ \itor -> bracket (wrapItorCallback (getCategories ref)) freeHaskellFunPtr $ \fptr -> - withForeignPtr (a_pgf p) $ \p_pgf -> do + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> do (#poke PgfItor, fn) itor fptr - withPgfExn "" (pgf_iter_categories p_pgf itor) + withPgfExn "" (pgf_iter_categories c_db c_revision itor) cs <- readIORef ref return (reverse cs)) where @@ -177,9 +193,10 @@ categoryContext p cat = withText cat $ \c_cat -> alloca $ \p_n_hypos -> withForeignPtr unmarshaller $ \u -> - withForeignPtr (a_pgf p) $ \c_pgf -> + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> mask_ $ do - c_hypos <- pgf_category_context c_pgf c_cat p_n_hypos u + c_hypos <- pgf_category_context c_db c_revision c_cat p_n_hypos u if c_hypos == nullPtr then return [] else do n_hypos <- peek p_n_hypos @@ -204,8 +221,9 @@ categoryProb :: PGF -> Cat -> Float categoryProb p cat = unsafePerformIO $ withText cat $ \c_cat -> - withForeignPtr (a_pgf p) $ \c_pgf -> - do c_prob <- pgf_category_prob c_pgf c_cat + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> + do c_prob <- pgf_category_prob c_db c_revision c_cat return (realToFrac c_prob) -- | List of all functions defined in the abstract syntax @@ -215,9 +233,10 @@ functions p = ref <- newIORef [] (allocaBytes (#size PgfItor) $ \itor -> bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr -> - withForeignPtr (a_pgf p) $ \p_pgf -> do + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> do (#poke PgfItor, fn) itor fptr - withPgfExn "" (pgf_iter_functions p_pgf itor) + withPgfExn "" (pgf_iter_functions c_db c_revision itor) fs <- readIORef ref return (reverse fs)) where @@ -235,9 +254,10 @@ functionsByCat p cat = (withText cat $ \c_cat -> allocaBytes (#size PgfItor) $ \itor -> bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr -> - withForeignPtr (a_pgf p) $ \p_pgf -> do + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> do (#poke PgfItor, fn) itor fptr - withPgfExn "" (pgf_iter_functions_by_cat p_pgf c_cat itor) + withPgfExn "" (pgf_iter_functions_by_cat c_db c_revision c_cat itor) fs <- readIORef ref return (reverse fs)) where @@ -319,8 +339,9 @@ readType str = createFunction :: PGF -> Fun -> Type -> Float -> IO () createFunction p name ty prob = - withForeignPtr (a_pgf p) $ \p_pgf -> + withForeignPtr (a_db p) $ \c_db -> + withForeignPtr (revision p) $ \c_revision -> withText name $ \c_name -> bracket (newStablePtr ty) freeStablePtr $ \c_ty -> withForeignPtr marshaller $ \m -> do - pgf_create_function p_pgf c_name c_ty prob m + pgf_create_function c_db c_revision c_name c_ty prob m diff --git a/src/runtime/haskell/PGF2/FFI.hsc b/src/runtime/haskell/PGF2/FFI.hsc index 9070251dc..bd5b7202a 100644 --- a/src/runtime/haskell/PGF2/FFI.hsc +++ b/src/runtime/haskell/PGF2/FFI.hsc @@ -20,8 +20,11 @@ import PGF2.Expr -- | An abstract data type representing multilingual grammar -- in Portable Grammar Format. -data PGF = PGF {a_pgf :: ForeignPtr PgfPGF, langs :: Map.Map String Concr} -data Concr = Concr {c_pgf :: ForeignPtr PgfPGF, concr :: Ptr PgfConcr} +data PGF = PGF { a_db :: ForeignPtr PgfDB + , revision :: ForeignPtr PgfRevision + , langs :: Map.Map String Concr + } +data Concr = Concr {c_pgf :: ForeignPtr PgfDB, concr :: Ptr PgfConcr} ------------------------------------------------------------------ -- libpgf API @@ -29,7 +32,8 @@ data Concr = Concr {c_pgf :: ForeignPtr PgfPGF, concr :: Ptr PgfConcr} data PgfExn data PgfText data PgfItor -data PgfPGF +data PgfDB +data PgfRevision data PgfPrintContext data PgfConcr data PgfTypeHypo @@ -43,19 +47,22 @@ foreign import ccall unsafe "pgf_utf8_encode" pgf_utf8_encode :: Word32 -> Ptr CString -> IO () foreign import ccall "pgf_read_pgf" - pgf_read_pgf :: CString -> Ptr PgfExn -> IO (Ptr PgfPGF) + pgf_read_pgf :: CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB) foreign import ccall "pgf_boot_ngf" - pgf_boot_ngf :: CString -> CString -> Ptr PgfExn -> IO (Ptr PgfPGF) + pgf_boot_ngf :: CString -> CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB) foreign import ccall "pgf_read_ngf" - pgf_read_ngf :: CString -> Ptr PgfExn -> IO (Ptr PgfPGF) + pgf_read_ngf :: CString -> Ptr (Ptr PgfRevision) -> Ptr PgfExn -> IO (Ptr PgfDB) foreign import ccall "&pgf_free" - pgf_free_fptr :: FinalizerPtr PgfPGF + pgf_free_fptr :: FinalizerPtr PgfDB + +foreign import ccall "pgf_free_revision" + pgf_free_revision :: Ptr PgfDB -> Ptr PgfRevision -> IO () foreign import ccall "pgf_abstract_name" - pgf_abstract_name :: Ptr PgfPGF -> IO (Ptr PgfText) + pgf_abstract_name :: Ptr PgfDB -> Ptr PgfRevision -> IO (Ptr PgfText) foreign import ccall "pgf_print_expr" pgf_print_expr :: StablePtr Expr -> Ptr PgfPrintContext -> CInt -> Ptr PgfMarshaller -> IO (Ptr PgfText) @@ -75,34 +82,34 @@ foreign import ccall "wrapper" wrapItorCallback :: ItorCallback -> IO (FunPtr ItorCallback) foreign import ccall "pgf_iter_categories" - pgf_iter_categories :: Ptr PgfPGF -> Ptr PgfItor -> Ptr PgfExn -> IO () + pgf_iter_categories :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfItor -> Ptr PgfExn -> IO () foreign import ccall "pgf_start_cat" - pgf_start_cat :: Ptr PgfPGF -> Ptr PgfUnmarshaller -> IO (StablePtr Type) + pgf_start_cat :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfUnmarshaller -> IO (StablePtr Type) foreign import ccall "pgf/pgf.h pgf_category_context" - pgf_category_context :: Ptr PgfPGF -> Ptr PgfText -> Ptr CSize -> Ptr PgfUnmarshaller -> IO (Ptr PgfTypeHypo) + pgf_category_context :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr CSize -> Ptr PgfUnmarshaller -> IO (Ptr PgfTypeHypo) foreign import ccall "pgf/pgf.h pgf_category_prob" - pgf_category_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t) + pgf_category_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type prob_t) foreign import ccall "pgf_iter_functions" - pgf_iter_functions :: Ptr PgfPGF -> Ptr PgfItor -> Ptr PgfExn -> IO () + pgf_iter_functions :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfItor -> Ptr PgfExn -> IO () foreign import ccall "pgf_iter_functions_by_cat" - pgf_iter_functions_by_cat :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfItor -> Ptr PgfExn -> IO () + pgf_iter_functions_by_cat :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfItor -> Ptr PgfExn -> IO () foreign import ccall "pgf/pgf.h pgf_function_type" - pgf_function_type :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type) + pgf_function_type :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type) foreign import ccall "pgf/expr.h pgf_function_is_constructor" - pgf_function_is_constructor :: Ptr PgfPGF -> Ptr PgfText -> IO (#type int) + pgf_function_is_constructor :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type int) foreign import ccall "pgf/expr.h pgf_function_is_constructor" - pgf_function_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t) + pgf_function_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type prob_t) foreign import ccall "pgf_create_function" - pgf_create_function :: Ptr PgfPGF -> Ptr PgfText -> StablePtr Type -> (#type prob_t) -> Ptr PgfMarshaller -> IO () + pgf_create_function :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> StablePtr Type -> (#type prob_t) -> Ptr PgfMarshaller -> IO () ----------------------------------------------------------------------- diff --git a/src/runtime/haskell/tests/basic.hs b/src/runtime/haskell/tests/basic.hs index 0a5783e67..f5a40d752 100644 --- a/src/runtime/haskell/tests/basic.hs +++ b/src/runtime/haskell/tests/basic.hs @@ -74,8 +74,11 @@ main = do print (e :: SomeException) gr1 <- readPGF "tests/basic.pgf" + print (abstractName gr1) gr2 <- bootNGF "tests/basic.pgf" "tests/basic.ngf" + print (abstractName gr2) gr3 <- readNGF "tests/basic.ngf" + print (abstractName gr3) rp1 <- testLoadFailure (readPGF "non-existing.pgf") rp2 <- testLoadFailure (readPGF "tests/basic.gf") diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c index bd7da4c86..3bebd250d 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pypgf.c @@ -15,7 +15,8 @@ static PyObject *PGFError; typedef struct { PyObject_HEAD - PgfPGF *pgf; + PgfDB *db; + PgfRevision revision; } PGFObject; // typedef struct IterObject { @@ -1719,7 +1720,7 @@ typedef struct { static void PGF_dealloc(PGFObject* self) { - pgf_free(self->pgf); + pgf_free(self->db); Py_TYPE(self)->tp_free((PyObject*)self); } @@ -1767,7 +1768,7 @@ PGF_repr(PGFObject *self) static PyObject* PGF_getAbstractName(PGFObject *self, void *closure) { - PgfText* txt = pgf_abstract_name(self->pgf); + PgfText* txt = pgf_abstract_name(self->db, self->revision); PyObject *name = PyString_FromStringAndSize(txt->text, txt->size); free(txt); return name; @@ -1866,7 +1867,7 @@ PGF_getCategories(PGFObject *self, void *closure) PgfExn err; PyPGFClosure clo = { { pgf_collect_cats }, self, categories }; - pgf_iter_categories(self->pgf, &clo.fn, &err); + pgf_iter_categories(self->db, self->revision, &clo.fn, &err); if (err.type != PGF_EXN_NONE) { Py_DECREF(categories); return NULL; @@ -1878,7 +1879,7 @@ PGF_getCategories(PGFObject *self, void *closure) static TypeObject * PGF_getStartCat(PGFObject *self, void *closure) { - PgfType type = pgf_start_cat(self->pgf, &unmarshaller); + PgfType type = pgf_start_cat(self->db, self->revision, &unmarshaller); if (type == 0) { PyErr_SetString(PGFError, "The start category cannot be found"); return NULL; @@ -1915,7 +1916,7 @@ PGF_getFunctions(PGFObject *self, void *closure) PgfExn err; PyPGFClosure clo = { { pgf_collect_funs }, self, functions }; - pgf_iter_functions(self->pgf, &clo.fn, &err); + pgf_iter_functions(self->db, self->revision, &clo.fn, &err); if (err.type != PGF_EXN_NONE) { Py_DECREF(functions); return NULL; @@ -1943,7 +1944,7 @@ PGF_functionsByCat(PGFObject* self, PyObject *args) PgfExn err; PyPGFClosure clo = { { pgf_collect_funs }, self, functions }; - pgf_iter_functions_by_cat(self->pgf, catname, &clo.fn, &err); + pgf_iter_functions_by_cat(self->db, self->revision, catname, &clo.fn, &err); if (err.type != PGF_EXN_NONE) { Py_DECREF(functions); return NULL; @@ -1964,7 +1965,7 @@ PGF_functionType(PGFObject *self, PyObject *args) memcpy(funname->text, s, size+1); funname->size = size; - PgfType type = pgf_function_type(self->pgf, funname, &unmarshaller); + PgfType type = pgf_function_type(self->db, self->revision, funname, &unmarshaller); if (type == 0) { PyErr_Format(PyExc_KeyError, "Function '%s' is not defined", funname->text); return NULL; @@ -2385,7 +2386,7 @@ pgf_readPGF(PyObject *self, PyObject *args) // Read the PGF grammar. PgfExn err; - py_pgf->pgf = pgf_read_pgf(fpath, &err); + py_pgf->db = pgf_read_pgf(fpath, &py_pgf->revision, &err); if (err.type == PGF_EXN_SYSTEM_ERROR) { errno = err.code; PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath); @@ -2413,7 +2414,7 @@ pgf_bootNGF(PyObject *self, PyObject *args) // Read the PGF grammar. PgfExn err; - py_pgf->pgf = pgf_boot_ngf(fpath, npath, &err); + py_pgf->db = pgf_boot_ngf(fpath, npath, &py_pgf->revision, &err); if (err.type == PGF_EXN_SYSTEM_ERROR) { errno = err.code; PyErr_SetFromErrnoWithFilename(PyExc_IOError, npath); @@ -2440,7 +2441,7 @@ pgf_readNGF(PyObject *self, PyObject *args) // Read the NGF grammar. PgfExn err; - py_pgf->pgf = pgf_read_ngf(fpath, &err); + py_pgf->db = pgf_read_ngf(fpath, &py_pgf->revision, &err); if (err.type == PGF_EXN_SYSTEM_ERROR) { errno = err.code; PyErr_SetFromErrnoWithFilename(PyExc_IOError, fpath);