forked from GitHub/gf-core
implemented functionType and marshalling for types and expressions
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
#ifndef PGF_DATA_H_
|
||||
#define PGF_DATA_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
@@ -121,9 +119,15 @@ struct PGF_INTERNAL_DECL PgfPGFRoot {
|
||||
#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() {};
|
||||
PGF_INTERNAL_DECL PgfPGF(const char* fpath, int flags, int mode,
|
||||
PgfUnmarshaller *unmarshaller)
|
||||
: DB(fpath, flags, mode)
|
||||
{ u = unmarshaller; };
|
||||
|
||||
PGF_INTERNAL_DECL ~PgfPGF()
|
||||
{ u->free_me(u); };
|
||||
|
||||
PgfUnmarshaller *u;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
@@ -7,13 +7,6 @@ typedef variant PgfExpr;
|
||||
struct PgfHypo;
|
||||
struct PgfType;
|
||||
|
||||
typedef int PgfMetaId;
|
||||
|
||||
typedef enum {
|
||||
PGF_BIND_TYPE_EXPLICIT,
|
||||
PGF_BIND_TYPE_IMPLICIT
|
||||
} PgfBindType;
|
||||
|
||||
/// A literal for an abstract syntax tree
|
||||
typedef variant PgfLiteral;
|
||||
|
||||
@@ -106,4 +99,13 @@ typedef struct {
|
||||
PgfExpr expr;
|
||||
} PgfExprProb;
|
||||
|
||||
PGF_INTERNAL_DECL
|
||||
uintptr_t pgf_unmarshall_literal(PgfUnmarshaller *u, PgfLiteral l);
|
||||
|
||||
PGF_INTERNAL_DECL
|
||||
uintptr_t pgf_unmarshall_expr(PgfUnmarshaller *u, PgfExpr e);
|
||||
|
||||
PGF_INTERNAL_DECL
|
||||
uintptr_t pgf_unmarshall_type(PgfUnmarshaller *u, PgfType *tp);
|
||||
|
||||
#endif /* EXPR_H_ */
|
||||
|
||||
@@ -216,10 +216,10 @@ Namespace<V> namespace_insert(Namespace<V> map, ref<V> value)
|
||||
}
|
||||
|
||||
template <class V>
|
||||
ref<V> namespace_lookup(Namespace<V> map, const char *name)
|
||||
ref<V> namespace_lookup(Namespace<V> map, PgfText *name)
|
||||
{
|
||||
while (map != 0) {
|
||||
int cmp = strcmp(name,map->value->name);
|
||||
int cmp = textcmp(name,&map->value->name);
|
||||
if (cmp < 0)
|
||||
map = map->left;
|
||||
else if (cmp > 0)
|
||||
@@ -227,7 +227,7 @@ ref<V> namespace_lookup(Namespace<V> map, const char *name)
|
||||
else
|
||||
return map->value;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
|
||||
@@ -11,14 +11,16 @@ pgf_exn_clear(PgfExn* err)
|
||||
}
|
||||
|
||||
PGF_API
|
||||
PgfPGF *pgf_read_pgf(const char* fpath, PgfExn* err)
|
||||
PgfPGF *pgf_read_pgf(const char* fpath,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
PgfExn* err)
|
||||
{
|
||||
PgfPGF *pgf = NULL;
|
||||
|
||||
pgf_exn_clear(err);
|
||||
|
||||
try {
|
||||
pgf = new PgfPGF(NULL, 0, 0);
|
||||
pgf = new PgfPGF(NULL, 0, 0, unmarshaller);
|
||||
|
||||
std::ifstream in(fpath, std::ios::binary);
|
||||
if (in.fail()) {
|
||||
@@ -50,14 +52,16 @@ PgfPGF *pgf_read_pgf(const char* fpath, PgfExn* err)
|
||||
}
|
||||
|
||||
PGF_API
|
||||
PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, PgfExn* err)
|
||||
PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
PgfExn* err)
|
||||
{
|
||||
PgfPGF *pgf = NULL;
|
||||
|
||||
pgf_exn_clear(err);
|
||||
|
||||
try {
|
||||
pgf = new PgfPGF(ngf_path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
pgf = new PgfPGF(ngf_path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, unmarshaller);
|
||||
|
||||
std::ifstream in(pgf_path, std::ios::binary);
|
||||
if (in.fail()) {
|
||||
@@ -93,7 +97,9 @@ PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path, PgfExn* err)
|
||||
}
|
||||
|
||||
PGF_API
|
||||
PgfPGF *pgf_read_ngf(const char *fpath, PgfExn* err)
|
||||
PgfPGF *pgf_read_ngf(const char *fpath,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
PgfExn* err)
|
||||
{
|
||||
PgfPGF *pgf = NULL;
|
||||
|
||||
@@ -101,7 +107,7 @@ PgfPGF *pgf_read_ngf(const char *fpath, PgfExn* err)
|
||||
|
||||
bool is_new = false;
|
||||
try {
|
||||
pgf = new PgfPGF(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
pgf = new PgfPGF(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, unmarshaller);
|
||||
|
||||
{
|
||||
DB_scope scope(pgf, WRITER_SCOPE);
|
||||
@@ -195,3 +201,16 @@ void pgf_iter_functions_by_cat(PgfPGF* pgf, PgfText* cat, PgfItor* itor)
|
||||
helper.itor = itor;
|
||||
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.funs, &helper);
|
||||
}
|
||||
|
||||
PGF_API uintptr_t
|
||||
pgf_function_type(PgfPGF* pgf, PgfText *funname)
|
||||
{
|
||||
DB_scope scope(pgf, READER_SCOPE);
|
||||
|
||||
ref<PgfAbsFun> absfun =
|
||||
namespace_lookup(pgf->get_root<PgfPGFRoot>()->abstract.funs, funname);
|
||||
if (absfun == 0)
|
||||
return 0;
|
||||
|
||||
return pgf_unmarshall_type(pgf->u, absfun->type);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include<stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* A generic structure to store text. The last field is variable length */
|
||||
typedef struct {
|
||||
size_t size;
|
||||
@@ -50,6 +53,49 @@ struct PgfItor {
|
||||
void (*fn)(PgfItor* self, PgfText* key, void *value);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PGF_BIND_TYPE_EXPLICIT,
|
||||
PGF_BIND_TYPE_IMPLICIT
|
||||
} PgfBindType;
|
||||
|
||||
typedef int PgfMetaId;
|
||||
|
||||
typedef struct {
|
||||
PgfBindType bind_type;
|
||||
PgfText *cid;
|
||||
uintptr_t type;
|
||||
} PgfTypeHypo;
|
||||
|
||||
/* This structure tells the runtime how to create abstract syntax
|
||||
* expressions in the heap of the host language. For instance,
|
||||
* when used from Haskell the runtime will create values of
|
||||
* an algebraic data type which can be garbage collected
|
||||
* when not needed. Similarly in Python the expressions are
|
||||
* normal Python objects. From the point of view of the runtime,
|
||||
* each node is a value of type uintptr_t. For Haskell that would
|
||||
* actually be a stable pointer, while for Python that would be
|
||||
* a PyObject pointer.
|
||||
*/
|
||||
typedef struct PgfUnmarshaller PgfUnmarshaller;
|
||||
struct PgfUnmarshaller {
|
||||
uintptr_t (*eabs)(PgfBindType btype, PgfText *name, uintptr_t body);
|
||||
uintptr_t (*eapp)(uintptr_t fun, uintptr_t arg);
|
||||
uintptr_t (*elit)(uintptr_t lit);
|
||||
uintptr_t (*emeta)(PgfMetaId meta);
|
||||
uintptr_t (*efun)(PgfText *name);
|
||||
uintptr_t (*evar)(int index);
|
||||
uintptr_t (*etyped)(uintptr_t expr, uintptr_t typ);
|
||||
uintptr_t (*eimplarg)(uintptr_t expr);
|
||||
uintptr_t (*lint)(int v);
|
||||
uintptr_t (*lflt)(double v);
|
||||
uintptr_t (*lstr)(PgfText *v);
|
||||
uintptr_t (*dtyp)(int n_hypos, PgfTypeHypo *hypos,
|
||||
PgfText *cat,
|
||||
int n_exprs, uintptr_t *exprs);
|
||||
void (*free_ref)(uintptr_t x);
|
||||
void (*free_me)(PgfUnmarshaller *unmarshaller);
|
||||
};
|
||||
|
||||
typedef struct PgfPGF PgfPGF;
|
||||
|
||||
/* All functions that may fail take a reference to a PgfExn structure.
|
||||
@@ -82,21 +128,27 @@ typedef struct {
|
||||
|
||||
/* Reads a PGF file and keeps it in memory. */
|
||||
PGF_API_DECL
|
||||
PgfPGF *pgf_read_pgf(const char* fpath, PgfExn* err);
|
||||
PgfPGF *pgf_read_pgf(const char* fpath,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
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.
|
||||
* 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);
|
||||
PgfPGF *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
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. */
|
||||
PGF_API_DECL
|
||||
PgfPGF *pgf_read_ngf(const char* fpath, PgfExn* err);
|
||||
PgfPGF *pgf_read_ngf(const char* fpath,
|
||||
PgfUnmarshaller *unmarshaller,
|
||||
PgfExn* err);
|
||||
|
||||
/* Release the grammar when it is no longer needed. */
|
||||
PGF_API_DECL
|
||||
|
||||
Reference in New Issue
Block a user