diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index 5c893a2f3..3d168945f 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -12,6 +12,21 @@ pgf_exn_clear(PgfExn* err) err->msg = NULL; } +#define PGF_API_BEGIN \ + pgf_exn_clear(err); \ +\ + try \ + +#define PGF_API_END \ + catch (pgf_systemerror& e) { \ + err->type = PGF_EXN_SYSTEM_ERROR; \ + err->code = e.code(); \ + err->msg = e.filepath(); \ + } catch (pgf_error& e) { \ + err->type = PGF_EXN_PGF_ERROR; \ + err->msg = strdup(e.what()); \ + } + PGF_API PgfDB *pgf_read_pgf(const char* fpath, PgfRevision *revision, @@ -19,9 +34,7 @@ PgfDB *pgf_read_pgf(const char* fpath, { PgfDB *db = NULL; - pgf_exn_clear(err); - - try { + PGF_API_BEGIN { db = new PgfDB(NULL, 0, 0); std::ifstream in(fpath, std::ios::binary); if (in.fail()) { @@ -39,14 +52,7 @@ PgfDB *pgf_read_pgf(const char* fpath, } return db; - } catch (pgf_systemerror& e) { - err->type = PGF_EXN_SYSTEM_ERROR; - err->code = e.code(); - err->msg = e.filepath(); - } catch (pgf_error& e) { - err->type = PGF_EXN_PGF_ERROR; - err->msg = strdup(e.what()); - } + } PGF_API_END end: if (db != NULL) @@ -62,9 +68,7 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, { PgfDB *db = NULL; - pgf_exn_clear(err); - - try { + PGF_API_BEGIN { db = new PgfDB(ngf_path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); std::ifstream in(pgf_path, std::ios::binary); @@ -85,14 +89,7 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, } return db; - } catch (pgf_systemerror& e) { - err->type = PGF_EXN_SYSTEM_ERROR; - err->code = e.code(); - err->msg = e.filepath(); - } catch (pgf_error& e) { - err->type = PGF_EXN_PGF_ERROR; - err->msg = strdup(e.what()); - } + } PGF_API_END if (db != NULL) { delete db; @@ -109,10 +106,8 @@ PgfDB *pgf_read_ngf(const char *fpath, { PgfDB *db = NULL; - pgf_exn_clear(err); - bool is_new = false; - try { + PGF_API_BEGIN { db = new PgfDB(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); { @@ -137,14 +132,7 @@ PgfDB *pgf_read_ngf(const char *fpath, } return db; - } catch (pgf_systemerror& e) { - err->type = PGF_EXN_SYSTEM_ERROR; - err->code = e.code(); - err->msg = e.filepath(); - } catch (pgf_error& e) { - err->type = PGF_EXN_PGF_ERROR; - err->msg = strdup(e.what()); - } + } PGF_API_END if (db != NULL) { delete db; @@ -167,114 +155,138 @@ void pgf_free_revision(PgfDB *pgf, PgfRevision revision) } PGF_API -PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision) +PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - return textdup(&(*pgf->abstract.name)); + return textdup(&(*pgf->abstract.name)); + } PGF_API_END + + return NULL; } PGF_API void pgf_iter_categories(PgfDB *db, PgfRevision revision, PgfItor *itor, PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; - - pgf_exn_clear(err); - namespace_iter(pgf->abstract.cats, itor, err); + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; + + namespace_iter(pgf->abstract.cats, itor, err); + } PGF_API_END } PGF_API PgfType pgf_start_cat(PgfDB *db, PgfRevision revision, - PgfUnmarshaller *u) + PgfUnmarshaller *u, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - PgfText *startcat = (PgfText *) - alloca(sizeof(PgfText)+9); - startcat->size = 8; - strcpy(startcat->text, "startcat"); + PgfText *startcat = (PgfText *) + alloca(sizeof(PgfText)+9); + startcat->size = 8; + strcpy(startcat->text, "startcat"); - ref flag = - namespace_lookup(pgf->abstract.aflags, startcat); + ref flag = + namespace_lookup(pgf->abstract.aflags, startcat); - if (flag != 0) { - switch (ref::get_tag(flag->value)) { - case PgfLiteralStr::tag: { - auto lstr = ref::untagged(flag->value); + if (flag != 0) { + switch (ref::get_tag(flag->value)) { + case PgfLiteralStr::tag: { + auto lstr = ref::untagged(flag->value); - PgfType type = pgf_read_type(&lstr->val, u); - if (type == 0) - break; - return type; - } - } - } + PgfType type = pgf_read_type(&lstr->val, u); + if (type == 0) + break; + return type; + } + } + } - PgfText *s = (PgfText *) - alloca(sizeof(PgfText)+2); - s->size = 1; - s->text[0] = 'S'; - s->text[1] = 0; - return u->dtyp(0,NULL,s,0,NULL); + PgfText *s = (PgfText *) + alloca(sizeof(PgfText)+2); + s->size = 1; + s->text[0] = 'S'; + s->text[1] = 0; + return u->dtyp(0,NULL,s,0,NULL); + } PGF_API_END + + return 0; } PGF_API PgfTypeHypo *pgf_category_context(PgfDB *db, PgfRevision revision, - PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u) + PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - ref abscat = - namespace_lookup(pgf->abstract.cats, catname); - if (abscat == 0) { - *n_hypos = 0; - return NULL; - } + ref abscat = + namespace_lookup(pgf->abstract.cats, catname); + if (abscat == 0) { + *n_hypos = 0; + return NULL; + } - PgfDBMarshaller m; + PgfDBMarshaller m; - PgfTypeHypo *hypos = (PgfTypeHypo *) - malloc(abscat->context->len * sizeof(PgfTypeHypo)); - for (size_t i = 0; i < abscat->context->len; i++) { - hypos[i].bind_type = abscat->context->data[i].bind_type; - hypos[i].cid = textdup(abscat->context->data[i].cid); - hypos[i].type = m.match_type(u, abscat->context->data[i].type.as_object()); - } + PgfTypeHypo *hypos = (PgfTypeHypo *) + malloc(abscat->context->len * sizeof(PgfTypeHypo)); + for (size_t i = 0; i < abscat->context->len; i++) { + hypos[i].bind_type = abscat->context->data[i].bind_type; + hypos[i].cid = textdup(abscat->context->data[i].cid); + hypos[i].type = m.match_type(u, abscat->context->data[i].type.as_object()); + } - *n_hypos = abscat->context->len; - return hypos; + *n_hypos = abscat->context->len; + return hypos; + } PGF_API_END + + *n_hypos = 0; + return NULL; } PGF_API prob_t pgf_category_prob(PgfDB *db, PgfRevision revision, - PgfText *catname) + PgfText *catname, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - ref abscat = - namespace_lookup(pgf->abstract.cats, catname); - if (abscat == 0) { - return 0; - } + ref abscat = + namespace_lookup(pgf->abstract.cats, catname); + if (abscat == 0) { + return 0; + } - return abscat->prob; + return abscat->prob; + } PGF_API_END + + return INFINITY; } PGF_API void pgf_iter_functions(PgfDB *db, PgfRevision revision, PgfItor *itor, PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - pgf_exn_clear(err); - namespace_iter(pgf->abstract.funs, itor, err); + pgf_exn_clear(err); + namespace_iter(pgf->abstract.funs, itor, err); + } PGF_API_END } struct PgfItorHelper : PgfItor @@ -297,61 +309,77 @@ PGF_API void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision, PgfText *cat, PgfItor *itor, PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - PgfItorHelper helper; - helper.fn = iter_by_cat_helper; - helper.cat = cat; - helper.itor = itor; + PgfItorHelper helper; + helper.fn = iter_by_cat_helper; + helper.cat = cat; + helper.itor = itor; - pgf_exn_clear(err); - namespace_iter(pgf->abstract.funs, &helper, err); + namespace_iter(pgf->abstract.funs, &helper, err); + } PGF_API_END } PGF_API PgfType pgf_function_type(PgfDB *db, PgfRevision revision, - PgfText *funname, PgfUnmarshaller *u) + PgfText *funname, PgfUnmarshaller *u, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - ref absfun = - namespace_lookup(pgf->abstract.funs, funname); - if (absfun == 0) - return 0; + ref absfun = + namespace_lookup(pgf->abstract.funs, funname); + if (absfun == 0) + return 0; - return PgfDBMarshaller().match_type(u, absfun->type.as_object()); + return PgfDBMarshaller().match_type(u, absfun->type.as_object()); + } PGF_API_END + + return 0; } PGF_API int pgf_function_is_constructor(PgfDB *db, PgfRevision revision, - PgfText *funname) + PgfText *funname, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - ref absfun = - namespace_lookup(pgf->abstract.funs, funname); - if (absfun == 0) - return false; + ref absfun = + namespace_lookup(pgf->abstract.funs, funname); + if (absfun == 0) + return false; - return (absfun->defns == 0); + return (absfun->defns == 0); + } PGF_API_END + + return false; } PGF_API prob_t pgf_function_prob(PgfDB *db, PgfRevision revision, - PgfText *funname) + PgfText *funname, + PgfExn *err) { - DB_scope scope(db, READER_SCOPE); - ref pgf = revision; + PGF_API_BEGIN { + DB_scope scope(db, READER_SCOPE); + ref pgf = revision; - ref absfun = - namespace_lookup(pgf->abstract.funs, funname); - if (absfun == 0) - return INFINITY; + ref absfun = + namespace_lookup(pgf->abstract.funs, funname); + if (absfun == 0) + return INFINITY; - return absfun->ep.prob; + return absfun->ep.prob; + } PGF_API_END + + return INFINITY; } PGF_API diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index 015bf4f83..b16f9813f 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -248,7 +248,8 @@ PGF_API_DECL void pgf_free_revision(PgfDB *pgf, PgfRevision revision); PGF_API_DECL -PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision); +PgfText *pgf_abstract_name(PgfDB *db, PgfRevision revision, + PgfExn* err); PGF_API_DECL void pgf_iter_categories(PgfDB *db, PgfRevision revision, @@ -256,15 +257,18 @@ void pgf_iter_categories(PgfDB *db, PgfRevision revision, PGF_API_DECL PgfType pgf_start_cat(PgfDB *db, PgfRevision revision, - PgfUnmarshaller *u); + PgfUnmarshaller *u, + PgfExn* err); PGF_API_DECL PgfTypeHypo *pgf_category_context(PgfDB *db, PgfRevision revision, - PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u); + PgfText *catname, size_t *n_hypos, PgfUnmarshaller *u, + PgfExn* err); PGF_API_DECL prob_t pgf_category_prob(PgfDB *db, PgfRevision revision, - PgfText *catname); + PgfText *catname, + PgfExn* err); PGF_API_DECL void pgf_iter_functions(PgfDB *db, PgfRevision revision, @@ -276,15 +280,18 @@ void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision, PGF_API_DECL PgfType pgf_function_type(PgfDB *db, PgfRevision revision, - PgfText *funname, PgfUnmarshaller *u); + PgfText *funname, PgfUnmarshaller *u, + PgfExn* err); PGF_API_DECL int pgf_function_is_constructor(PgfDB *db, PgfRevision revision, - PgfText *funname); + PgfText *funname, + PgfExn* err); PGF_API_DECL prob_t pgf_function_prob(PgfDB *db, PgfRevision revision, - PgfText *funname); + PgfText *funname, + PgfExn* err); typedef struct PgfPrintContext PgfPrintContext; diff --git a/src/runtime/haskell/PGF2.hsc b/src/runtime/haskell/PGF2.hsc index 5cfcd395c..dac0ec3d6 100644 --- a/src/runtime/haskell/PGF2.hsc +++ b/src/runtime/haskell/PGF2.hsc @@ -113,7 +113,7 @@ abstractName p = unsafePerformIO $ withForeignPtr (a_db p) $ \c_db -> withForeignPtr (revision p) $ \c_revision -> - bracket (pgf_abstract_name c_db c_revision) free $ \c_text -> + bracket (withPgfExn (pgf_abstract_name c_db c_revision)) free $ \c_text -> peekText c_text -- | The start category is defined in the grammar with @@ -127,7 +127,7 @@ startCat p = withForeignPtr unmarshaller $ \u -> withForeignPtr (a_db p) $ \c_db -> withForeignPtr (revision p) $ \c_revision -> do - c_typ <- pgf_start_cat c_db c_revision u + c_typ <- withPgfExn (pgf_start_cat c_db c_revision u) typ <- deRefStablePtr c_typ freeStablePtr c_typ return typ @@ -140,7 +140,7 @@ functionType p fn = withForeignPtr (a_db p) $ \c_db -> withForeignPtr (revision p) $ \c_revision -> withText fn $ \c_fn -> do - c_typ <- pgf_function_type c_db c_revision c_fn u + c_typ <- withPgfExn (pgf_function_type c_db c_revision c_fn u) if c_typ == castPtrToStablePtr nullPtr then return Nothing else do typ <- deRefStablePtr c_typ @@ -153,7 +153,7 @@ functionIsConstructor p fun = withText fun $ \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 + do res <- withPgfExn (pgf_function_is_constructor c_db c_revision c_fun) return (res /= 0) functionProb :: PGF -> Fun -> Float @@ -162,8 +162,7 @@ functionProb p fun = withText fun $ \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) + withPgfExn (pgf_function_prob c_db c_revision c_fun) -- | List of all functions defined in the abstract syntax categories :: PGF -> [Cat] @@ -194,7 +193,7 @@ categoryContext p cat = withForeignPtr (a_db p) $ \c_db -> withForeignPtr (revision p) $ \c_revision -> mask_ $ do - c_hypos <- pgf_category_context c_db c_revision c_cat p_n_hypos u + c_hypos <- withPgfExn (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 @@ -221,8 +220,7 @@ categoryProb p cat = withText cat $ \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) + withPgfExn (pgf_category_prob c_db c_revision c_cat) -- | List of all functions defined in the abstract syntax functions :: PGF -> [Fun] diff --git a/src/runtime/haskell/PGF2/FFI.hsc b/src/runtime/haskell/PGF2/FFI.hsc index 2810fe05c..3e67c78b8 100644 --- a/src/runtime/haskell/PGF2/FFI.hsc +++ b/src/runtime/haskell/PGF2/FFI.hsc @@ -62,7 +62,7 @@ foreign import ccall "pgf_free_revision" pgf_free_revision :: Ptr PgfDB -> Ptr PgfRevision -> IO () foreign import ccall "pgf_abstract_name" - pgf_abstract_name :: Ptr PgfDB -> Ptr PgfRevision -> IO (Ptr PgfText) + pgf_abstract_name :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfExn -> IO (Ptr PgfText) foreign import ccall "pgf_print_expr" pgf_print_expr :: StablePtr Expr -> Ptr PgfPrintContext -> CInt -> Ptr PgfMarshaller -> IO (Ptr PgfText) @@ -85,13 +85,13 @@ foreign import ccall "pgf_iter_categories" pgf_iter_categories :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfItor -> Ptr PgfExn -> IO () foreign import ccall "pgf_start_cat" - pgf_start_cat :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfUnmarshaller -> IO (StablePtr Type) + pgf_start_cat :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfUnmarshaller -> Ptr PgfExn -> IO (StablePtr Type) foreign import ccall "pgf/pgf.h pgf_category_context" - pgf_category_context :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr CSize -> Ptr PgfUnmarshaller -> IO (Ptr PgfTypeHypo) + pgf_category_context :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr CSize -> Ptr PgfUnmarshaller -> Ptr PgfExn -> IO (Ptr PgfTypeHypo) foreign import ccall "pgf/pgf.h pgf_category_prob" - pgf_category_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type prob_t) + pgf_category_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfExn -> IO (#type prob_t) foreign import ccall "pgf_iter_functions" pgf_iter_functions :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfItor -> Ptr PgfExn -> IO () @@ -99,14 +99,14 @@ foreign import ccall "pgf_iter_functions" foreign import ccall "pgf_iter_functions_by_cat" 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 PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type) +foreign import ccall "pgf_function_type" + pgf_function_type :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfUnmarshaller -> Ptr PgfExn -> IO (StablePtr Type) -foreign import ccall "pgf/expr.h pgf_function_is_constructor" - pgf_function_is_constructor :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type int) +foreign import ccall "pgf_function_is_constructor" + pgf_function_is_constructor :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfExn -> IO (#type int) foreign import ccall "pgf_function_prob" - pgf_function_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> IO (#type prob_t) + pgf_function_prob :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfText -> Ptr PgfExn -> IO (#type prob_t) foreign import ccall "pgf_clone_revision" pgf_clone_revision :: Ptr PgfDB -> Ptr PgfRevision -> Ptr PgfExn -> IO (Ptr PgfRevision)