1
0
forked from GitHub/gf-core

implemented functionType and marshalling for types and expressions

This commit is contained in:
krangelov
2021-08-10 15:07:41 +02:00
parent 7b5669a333
commit a5008c2fe1
11 changed files with 329 additions and 193 deletions

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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