restore the sharing of sequences. Shrinks the grammar by ~45%

This commit is contained in:
Krasimir Angelov
2022-01-08 19:49:42 +01:00
parent cd2c6aa32a
commit 00f857559d
31 changed files with 882 additions and 353 deletions

View File

@@ -29,7 +29,9 @@ libpgf_la_SOURCES = \
pgf/data.h \
pgf/expr.cxx \
pgf/expr.h \
pgf/namespace.h
pgf/namespace.h \
pgf/phrasetable.cxx \
pgf/phrasetable.h
libpgf_la_LDFLAGS = -no-undefined
libpgf_la_CXXFLAGS = -fno-rtti -std=c++11 -DCOMPILING_PGF

View File

@@ -3,6 +3,7 @@
void PgfFlag::release(ref<PgfFlag> flag)
{
pgf_literal_free(flag->value);
PgfDB::free(flag);
}
void PgfAbsFun::release(ref<PgfAbsFun> absfun)
@@ -12,11 +13,14 @@ void PgfAbsFun::release(ref<PgfAbsFun> absfun)
if (absfun->bytecode != 0) {
PgfDB::free(absfun->bytecode);
}
PgfDB::free(absfun);
}
void PgfAbsCat::release(ref<PgfAbsCat> abscat)
{
pgf_context_free(abscat->context);
PgfDB::free(abscat);
}
void PgfPGF::release(ref<PgfPGF> pgf)
@@ -27,6 +31,7 @@ void PgfPGF::release(ref<PgfPGF> pgf)
namespace_release(pgf->abstract.funs);
namespace_release(pgf->abstract.cats);
namespace_release(pgf->concretes);
PgfDB::free(pgf);
}
void PgfConcr::release(ref<PgfConcr> concr)
@@ -35,6 +40,7 @@ void PgfConcr::release(ref<PgfConcr> concr)
namespace_release(concr->lins);
namespace_release(concr->lincats);
namespace_release(concr->printnames);
PgfDB::free(concr);
}
void PgfConcrLincat::release(ref<PgfConcrLincat> lincat)
@@ -44,6 +50,29 @@ void PgfConcrLincat::release(ref<PgfConcrLincat> lincat)
}
PgfDB::free(lincat->fields);
for (size_t i = 0; i < lincat->args->len; i++) {
PgfDB::free(vector_elem(lincat->args, i)->param);
}
PgfDB::free(lincat->args);
for (size_t i = 0; i < lincat->res->len; i++) {
ref<PgfPResult> res = *vector_elem(lincat->res, i);
if (res->vars != 0)
PgfDB::free(res->vars);
PgfDB::free(res);
}
PgfDB::free(lincat->res);
for (size_t i = 0; i < lincat->seqs->len; i++) {
ref<PgfSequence> seq = *vector_elem(lincat->seqs, i);
if (!(--seq->ref_count)) {
PgfSequence::release(seq);
}
}
PgfDB::free(lincat->seqs);
PgfDB::free(lincat);
}
PGF_INTERNAL
@@ -52,9 +81,9 @@ void pgf_symbol_free(PgfSymbol sym)
switch (ref<PgfSymbol>::get_tag(sym)) {
case PgfSymbolKP::tag: {
auto sym_kp = ref<PgfSymbolKP>::untagged(sym);
pgf_symbols_free(sym_kp->default_form);
PgfSequence::release(sym_kp->default_form);
for (size_t i = 0; i < sym_kp->alts.len; i++) {
pgf_symbols_free(sym_kp->alts.data[i].form);
PgfSequence::release(sym_kp->alts.data[i].form);
for (size_t j = 0; j < sym_kp->alts.data[i].prefixes->len; j++) {
ref<PgfText> prefix = *vector_elem(sym_kp->alts.data[i].prefixes, j);
PgfDB::free(prefix);
@@ -75,14 +104,13 @@ void pgf_symbol_free(PgfSymbol sym)
}
}
PGF_INTERNAL
void pgf_symbols_free(ref<Vector<PgfSymbol>> syms)
void PgfSequence::release(ref<PgfSequence> seq)
{
for (size_t i = 0; i < syms->len; i++) {
PgfSymbol sym = *vector_elem(syms, i);
for (size_t i = 0; i < seq->syms.len; i++) {
PgfSymbol sym = *vector_elem(&seq->syms, i);
pgf_symbol_free(sym);
}
PgfDB::free(syms);
PgfDB::free(seq);
}
void PgfConcrLin::release(ref<PgfConcrLin> lin)
@@ -101,17 +129,18 @@ void PgfConcrLin::release(ref<PgfConcrLin> lin)
PgfDB::free(lin->res);
for (size_t i = 0; i < lin->seqs->len; i++) {
ref<Vector<PgfSymbol>> syms = *vector_elem(lin->seqs, i);
for (size_t j = 0; j < syms->len; j++) {
PgfSymbol sym = *vector_elem(syms, j);
pgf_symbol_free(sym);
}
PgfDB::free(syms);
ref<PgfSequence> seq = *vector_elem(lin->seqs, i);
if (!(--seq->ref_count)) {
PgfSequence::release(seq);
}
}
PgfDB::free(lin->seqs);
PgfDB::free(lin);
}
void PgfConcrPrintname::release(ref<PgfConcrPrintname> printname)
{
PgfDB::free(printname->printname);
PgfDB::free(printname);
}

View File

@@ -64,6 +64,7 @@ class PgfConcr;
#include "text.h"
#include "vector.h"
#include "namespace.h"
#include "phrasetable.h"
#include "expr.h"
struct PGF_INTERNAL_DECL PgfFlag {
@@ -128,6 +129,14 @@ struct PGF_INTERNAL_DECL PgfPResult {
typedef object PgfSymbol;
struct PGF_INTERNAL_DECL PgfSequence {
size_t seq_id;
size_t ref_count;
Vector<PgfSymbol> syms;
static void release(ref<PgfSequence> lincat);
};
struct PGF_INTERNAL_DECL PgfSymbolCat {
static const uint8_t tag = 0;
size_t d;
@@ -151,7 +160,7 @@ struct PGF_INTERNAL_DECL PgfSymbolKS {
};
struct PGF_INTERNAL_DECL PgfAlternative {
ref<Vector<PgfSymbol>> form;
ref<PgfSequence> form;
/**< The form of this variant as a list of tokens. */
ref<Vector<ref<PgfText>>> prefixes;
@@ -161,7 +170,7 @@ struct PGF_INTERNAL_DECL PgfAlternative {
struct PGF_INTERNAL_DECL PgfSymbolKP {
static const uint8_t tag = 4;
ref<Vector<PgfSymbol>> default_form;
ref<PgfSequence> default_form;
Vector<PgfAlternative> alts;
};
@@ -192,9 +201,6 @@ struct PGF_INTERNAL_DECL PgfSymbolALLCAPIT {
PGF_INTERNAL_DECL
void pgf_symbol_free(PgfSymbol sym);
PGF_INTERNAL_DECL
void pgf_symbols_free(ref<Vector<PgfSymbol>> syms);
struct PGF_INTERNAL_DECL PgfConcrLincat {
size_t ref_count;
@@ -205,7 +211,7 @@ struct PGF_INTERNAL_DECL PgfConcrLincat {
size_t n_lindefs;
ref<Vector<PgfPArg>> args;
ref<Vector<ref<PgfPResult>>> res;
ref<Vector<ref<Vector<PgfSymbol>>>> seqs;
ref<Vector<ref<PgfSequence>>> seqs;
PgfText name;
@@ -219,7 +225,7 @@ struct PGF_INTERNAL_DECL PgfConcrLin {
ref<Vector<PgfPArg>> args;
ref<Vector<ref<PgfPResult>>> res;
ref<Vector<ref<Vector<PgfSymbol>>>> seqs;
ref<Vector<ref<PgfSequence>>> seqs;
PgfText name;
@@ -240,6 +246,7 @@ struct PGF_INTERNAL_DECL PgfConcr {
Namespace<PgfFlag> cflags;
Namespace<PgfConcrLin> lins;
Namespace<PgfConcrLincat> lincats;
PgfPhrasetable phrasetable;
Namespace<PgfConcrPrintname> printnames;
// If there are references from the host language to this concrete,

View File

@@ -792,7 +792,6 @@ void PgfDB::cleanup_revisions()
ref<PgfPGF> pgf = ms->transient_revisions;
ref<PgfPGF> next = pgf->next;
PgfPGF::release(pgf);
PgfDB::free(pgf);
ms->transient_revisions = next;
}
@@ -802,7 +801,6 @@ void PgfDB::cleanup_revisions()
concr->ref_count -= concr->ref_count_ex;
if (!concr->ref_count) {
PgfConcr::release(concr);
PgfDB::free(concr);
}
ms->transient_concr_revisions = next;
}

View File

@@ -52,10 +52,10 @@ void PgfLinearizer::TreeNode::linearize_var(PgfLinearizationOutputIface *out, Pg
out->symbol_token(linearizer->printer.get_text());
}
void PgfLinearizer::TreeNode::linearize_syms(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, ref<Vector<PgfSymbol>> syms)
void PgfLinearizer::TreeNode::linearize_seq(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, ref<PgfSequence> seq)
{
for (size_t i = 0; i < syms->len; i++) {
PgfSymbol sym = *vector_elem(syms, i);
for (size_t i = 0; i < seq->syms.len; i++) {
PgfSymbol sym = *vector_elem(&seq->syms, i);
switch (ref<PgfSymbol>::get_tag(sym)) {
case PgfSymbolCat::tag: {
@@ -307,8 +307,8 @@ void PgfLinearizer::TreeLinNode::linearize(PgfLinearizationOutputIface *out, Pgf
}
size_t n_seqs = lin->seqs->len / lin->res->len;
ref<Vector<PgfSymbol>> syms = *vector_elem(lin->seqs, (lin_index-1)*n_seqs + lindex);
linearize_syms(out, linearizer, syms);
ref<PgfSequence> seq = *vector_elem(lin->seqs, (lin_index-1)*n_seqs + lindex);
linearize_seq(out, linearizer, seq);
if (linearizer->pre_stack == NULL)
out->end_phrase(cat, fid, field, &lin->name);
@@ -382,8 +382,8 @@ void PgfLinearizer::TreeLindefNode::linearize(PgfLinearizationOutputIface *out,
linearizer->pre_stack->bracket_stack = bracket;
}
ref<Vector<PgfSymbol>> syms = *vector_elem(lincat->seqs, (lin_index-1)*lincat->fields->len + lindex);
linearize_syms(out, linearizer, syms);
ref<PgfSequence> seq = *vector_elem(lincat->seqs, (lin_index-1)*lincat->fields->len + lindex);
linearize_seq(out, linearizer, seq);
if (linearizer->pre_stack == NULL)
out->end_phrase(&lincat->name, fid, field, linearizer->wild);
@@ -429,8 +429,8 @@ void PgfLinearizer::TreeLinrefNode::linearize(PgfLinearizationOutputIface *out,
ref<PgfConcrLincat> lincat = args->get_lincat(linearizer);
if (lincat != 0) {
size_t i = lincat->n_lindefs*lincat->fields->len + (lin_index-1);
ref<Vector<PgfSymbol>> syms = *vector_elem(lincat->seqs, i);
linearize_syms(out, linearizer, syms);
ref<PgfSequence> seq = *vector_elem(lincat->seqs, i);
linearize_seq(out, linearizer, seq);
} else {
args->linearize(out, linearizer, lindex);
}
@@ -573,14 +573,14 @@ void PgfLinearizer::flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *t
for (size_t j = 0; j < alt->prefixes->len; j++) {
ref<PgfText> prefix = *vector_elem(alt->prefixes,j);
if (textstarts(token, &(*prefix))) {
pre->node->linearize_syms(out, this, alt->form);
pre->node->linearize_seq(out, this, alt->form);
goto done;
}
}
}
}
pre->node->linearize_syms(out, this, pre->sym_kp->default_form);
pre->node->linearize_seq(out, this, pre->sym_kp->default_form);
done:
if (pre->bracket_stack != NULL)

View File

@@ -45,7 +45,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat)=0;
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r);
virtual void linearize_var(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
virtual void linearize_syms(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, ref<Vector<PgfSymbol>> syms);
virtual void linearize_seq(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, ref<PgfSequence> seq);
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)=0;
size_t eval_param(PgfLParam *param);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer)=0;

View File

@@ -509,7 +509,6 @@ void namespace_release(Namespace<V> node)
if (!(--node->value->ref_count)) {
V::release(node->value);
PgfDB::free(node->value);
}
PgfDB::free(node);

View File

@@ -273,7 +273,7 @@ PGF_API_DECL
void pgf_free_revision(PgfDB *db, PgfRevision revision)
{
try {
DB_scope scope(db, WRITER_SCOPE);
DB_scope scope(db, READER_SCOPE);
ref<PgfPGF> pgf = PgfDB::revision2pgf(revision);
if (pgf->ref_count == 1 && PgfDB::is_persistant_revision(pgf)) {
@@ -287,7 +287,6 @@ void pgf_free_revision(PgfDB *db, PgfRevision revision)
if (!(--pgf->ref_count)) {
PgfDB::unlink_transient_revision(pgf);
PgfPGF::release(pgf);
PgfDB::free(pgf);
}
db->ref_count--;
@@ -303,7 +302,7 @@ PGF_API_DECL
void pgf_free_concr_revision(PgfDB *db, PgfConcrRevision revision)
{
try {
DB_scope scope(db, WRITER_SCOPE);
DB_scope scope(db, READER_SCOPE);
ref<PgfConcr> concr = PgfDB::revision2concr(revision);
if (!(--concr->ref_count_ex)) {
@@ -312,7 +311,6 @@ void pgf_free_concr_revision(PgfDB *db, PgfConcrRevision revision)
if (!(--concr->ref_count)) {
PgfConcr::release(concr);
PgfDB::free(concr);
}
db->ref_count--;
@@ -357,8 +355,7 @@ struct PgfItorConcrHelper : PgfItor
};
static
void iter_concretes_helper(PgfItor *itor, PgfText *key, object value,
PgfExn *err)
void iter_concretes_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err)
{
PgfItorConcrHelper* helper = (PgfItorConcrHelper*) itor;
ref<PgfConcr> concr = value;
@@ -501,8 +498,7 @@ struct PgfItorCatHelper : PgfItor
};
static
void iter_by_cat_helper(PgfItor *itor, PgfText *key, object value,
PgfExn *err)
void iter_by_cat_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err)
{
PgfItorCatHelper* helper = (PgfItorCatHelper*) itor;
ref<PgfAbsFun> absfun = value;
@@ -830,6 +826,19 @@ void pgf_iter_lins(PgfDB *db, PgfConcrRevision cnc_revision,
} PGF_API_END
}
PGF_API
void pgf_iter_sequences(PgfDB *db, PgfConcrRevision cnc_revision,
PgfSequenceItor *itor, PgfExn *err)
{
PGF_API_BEGIN {
DB_scope scope(db, READER_SCOPE);
ref<PgfConcr> concr = PgfDB::revision2concr(cnc_revision);
size_t next_id = 0;
phrasetable_iter(concr->phrasetable, itor, &next_id, err);
} PGF_API_END
}
PGF_API
void pgf_get_lincat_counts_internal(object o, size_t *counts)
{
@@ -847,15 +856,14 @@ PgfText *pgf_get_lincat_field_internal(object o, size_t i)
}
PGF_API
void pgf_get_lin_counts_internal(object o, size_t *counts)
size_t pgf_get_lin_get_prod_count(object o)
{
ref<PgfConcrLin> lin = o;
counts[0] = lin->res->len;
counts[1] = lin->seqs->len / lin->res->len;
return lin->res->len;
}
PGF_API
PgfText *pgf_print_lindef_sig_internal(object o, size_t i)
PgfText *pgf_print_lindef_internal(object o, size_t i)
{
ref<PgfConcrLincat> lincat = o;
@@ -877,29 +885,24 @@ PgfText *pgf_print_lindef_sig_internal(object o, size_t i)
printer.efun(&lincat->name);
printer.puts("(");
printer.lparam(ref<PgfLParam>::from_ptr(&res->param));
printer.puts(")");
return printer.get_text();
}
PGF_API
PgfText *pgf_print_lindef_seq_internal(object o, size_t i, size_t j)
{
ref<PgfConcrLincat> lincat = o;
PgfInternalMarshaller m;
PgfPrinter printer(NULL,0,&m);
printer.puts(") = [");
size_t n_seqs = lincat->fields->len;
ref<Vector<PgfSymbol>> syms = *vector_elem(lincat->seqs, i*n_seqs + j);
for (size_t j = 0; j < n_seqs; j++) {
if (j > 0)
printer.puts(",");
printer.symbols(syms);
ref<PgfSequence> seq = *vector_elem(lincat->seqs, i*n_seqs + j);
printer.seq_id(seq->seq_id);
}
printer.puts("]");
return printer.get_text();
}
PGF_API
PgfText *pgf_print_linref_sig_internal(object o, size_t i)
PgfText *pgf_print_linref_internal(object o, size_t i)
{
ref<PgfConcrLincat> lincat = o;
@@ -919,29 +922,19 @@ PgfText *pgf_print_linref_sig_internal(object o, size_t i)
printer.efun(&lincat->name);
printer.puts("(");
printer.lparam(vector_elem(lincat->args, lincat->n_lindefs+i)->param);
printer.puts(") -> String(0)");
printer.puts(") -> String(0) = [");
size_t n_seqs = lincat->fields->len;
ref<PgfSequence> seq = *vector_elem(lincat->seqs, lincat->n_lindefs*n_seqs+i);
printer.seq_id(seq->seq_id);
printer.puts("]");
return printer.get_text();
}
PGF_API
PgfText *pgf_print_linref_seq_internal(object o, size_t i)
{
ref<PgfConcrLincat> lincat = o;
PgfInternalMarshaller m;
PgfPrinter printer(NULL,0,&m);
size_t n_seqs = lincat->fields->len;
ref<Vector<PgfSymbol>> syms = *vector_elem(lincat->seqs, lincat->n_lindefs*n_seqs+i);
printer.symbols(syms);
return printer.get_text();
}
PGF_API
PgfText *pgf_print_lin_sig_internal(object o, size_t i)
PgfText *pgf_print_lin_internal(object o, size_t i)
{
ref<PgfConcrLin> lin = o;
ref<PgfDTyp> ty = lin->absfun->type;
@@ -974,23 +967,33 @@ PgfText *pgf_print_lin_sig_internal(object o, size_t i)
printer.efun(&ty->name);
printer.puts("(");
printer.lparam(ref<PgfLParam>::from_ptr(&res->param));
printer.puts(")");
printer.puts(") = [");
size_t n_seqs = lin->seqs->len / lin->res->len;
for (size_t j = 0; j < n_seqs; j++) {
if (j > 0)
printer.puts(",");
ref<PgfSequence> seq = *vector_elem(lin->seqs, i*n_seqs + j);
printer.seq_id(seq->seq_id);
}
printer.puts("]");
return printer.get_text();
}
PGF_API
PgfText *pgf_print_lin_seq_internal(object o, size_t i, size_t j)
PgfText *pgf_print_sequence_internal(object o)
{
ref<PgfConcrLin> lin = o;
ref<PgfSequence> seq = o;
PgfInternalMarshaller m;
PgfPrinter printer(NULL,0,&m);
size_t n_seqs = lin->seqs->len / lin->res->len;
ref<Vector<PgfSymbol>> syms = *vector_elem(lin->seqs, i*n_seqs + j);
printer.symbols(syms);
printer.seq_id(seq->seq_id);
printer.puts(" = ");
printer.sequence(seq);
return printer.get_text();
}
@@ -1256,6 +1259,7 @@ PgfConcrRevision pgf_create_concrete(PgfDB *db, PgfRevision revision,
concr->cflags = 0;
concr->lins = 0;
concr->lincats = 0;
concr->phrasetable = 0;
concr->printnames = 0;
concr->prev = 0;
concr->next = 0;
@@ -1348,9 +1352,11 @@ void pgf_drop_concrete(PgfDB *db, PgfRevision revision,
class PGF_INTERNAL PgfLinBuilder : public PgfLinBuilderIface
{
ref<PgfConcr> concr;
ref<Vector<PgfPArg>> args;
ref<Vector<ref<PgfPResult>>> res;
ref<Vector<ref<Vector<PgfSymbol>>>> seqs;
ref<Vector<ref<PgfSequence>>> seqs;
size_t var_index;
size_t arg_index;
@@ -1362,7 +1368,7 @@ class PGF_INTERNAL PgfLinBuilder : public PgfLinBuilderIface
size_t n_lindefs;
size_t n_linrefs;
ref<Vector<PgfSymbol>> syms;
ref<PgfSequence> seq;
size_t pre_sym_index;
@@ -1370,8 +1376,10 @@ class PGF_INTERNAL PgfLinBuilder : public PgfLinBuilderIface
"Detected incorrect use of the linearization builder";
public:
PgfLinBuilder()
PgfLinBuilder(ref<PgfConcr> concr)
{
this->concr = concr;
this->args = 0;
this->res = 0;
this->seqs = 0;
@@ -1383,11 +1391,11 @@ public:
this->alt_index = (size_t) -1;
this->n_lindefs = 0;
this->n_linrefs = 0;
this->syms = 0;
this->seq = 0;
this->pre_sym_index = (size_t) -1;
}
ref<PgfConcrLincat> build(ref<PgfAbsCat> abscat, PgfConcr *concr,
ref<PgfConcrLincat> build(ref<PgfAbsCat> abscat,
size_t n_fields, PgfText **fields,
size_t n_lindefs, size_t n_linrefs,
PgfBuildLinIface *build, PgfExn *err)
@@ -1395,7 +1403,7 @@ public:
size_t n_prods = n_lindefs+n_linrefs;
this->args = vector_new<PgfPArg>(n_prods);
this->res = vector_new<ref<PgfPResult>>(n_prods);
this->seqs = vector_new<ref<Vector<PgfSymbol>>>(n_lindefs*n_fields+n_linrefs);
this->seqs = vector_new<ref<PgfSequence>>(n_lindefs*n_fields+n_linrefs);
this->n_lindefs = n_lindefs;
this->n_linrefs = n_linrefs;
@@ -1434,7 +1442,7 @@ public:
return lincat;
}
ref<PgfConcrLin> build(ref<PgfAbsFun> absfun, PgfConcr *concr, size_t n_prods,
ref<PgfConcrLin> build(ref<PgfAbsFun> absfun, size_t n_prods,
PgfBuildLinIface *build, PgfExn *err)
{
ref<PgfConcrLincat> lincat =
@@ -1445,7 +1453,7 @@ public:
this->args = vector_new<PgfPArg>(n_prods*absfun->type->hypos->len);
this->res = vector_new<ref<PgfPResult>>(n_prods);
this->seqs = vector_new<ref<Vector<PgfSymbol>>>(n_prods*lincat->fields->len);
this->seqs = vector_new<ref<PgfSequence>>(n_prods*lincat->fields->len);
this->n_lindefs = n_prods;
ref<PgfConcrLin> lin = PgfDB::malloc<PgfConcrLin>(absfun->name.size+1);
@@ -1569,8 +1577,12 @@ public:
if (seq_index >= seqs->len)
throw pgf_error(builder_error_msg);
syms = vector_new<PgfSymbol>(n_syms);
*vector_elem(seqs, seq_index) = syms;
seq = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
seq->seq_id = 0;
seq->ref_count = 1;
seq->syms.len = n_syms;
*vector_elem(seqs, seq_index) = seq;
sym_index = 0;
} PGF_API_END
}
@@ -1581,7 +1593,7 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
ref<PgfSymbolCat> symcat = PgfDB::malloc<PgfSymbolCat>(n_terms*2*sizeof(size_t));
@@ -1594,7 +1606,7 @@ public:
symcat->r.terms[i].var = terms[2*i+1];
}
*vector_elem(syms, sym_index) = ref<PgfSymbolCat>::tagged(symcat);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolCat>::tagged(symcat);
sym_index++;
} PGF_API_END
}
@@ -1605,7 +1617,7 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
ref<PgfSymbolLit> symlit = PgfDB::malloc<PgfSymbolLit>(n_terms*2*sizeof(size_t));
@@ -1618,7 +1630,7 @@ public:
symlit->r.terms[i].var = terms[2*i+1];
}
*vector_elem(syms, sym_index) = ref<PgfSymbolLit>::tagged(symlit);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolLit>::tagged(symlit);
sym_index++;
} PGF_API_END
}
@@ -1629,14 +1641,14 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
ref<PgfSymbolVar> symvar = PgfDB::malloc<PgfSymbolVar>();
symvar->d = d;
symvar->r = r;
*vector_elem(syms, sym_index) = ref<PgfSymbolVar>::tagged(symvar);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolVar>::tagged(symvar);
sym_index++;
} PGF_API_END
}
@@ -1647,13 +1659,13 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
ref<PgfSymbolKS> symtok = PgfDB::malloc<PgfSymbolKS>(token->size+1);
memcpy(&symtok->token, token, sizeof(PgfText)+token->size+1);
*vector_elem(syms, sym_index) = ref<PgfSymbolKS>::tagged(symtok);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolKS>::tagged(symtok);
sym_index++;
} PGF_API_END
}
@@ -1664,19 +1676,22 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len || pre_sym_index != (size_t) -1)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len || pre_sym_index != (size_t) -1)
throw pgf_error(builder_error_msg);
ref<Vector<PgfSymbol>> def = vector_new<PgfSymbol>(n_syms);
ref<PgfSequence> def = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
def->seq_id = 0;
def->ref_count = 1;
def->syms.len = n_syms;
ref<PgfSymbolKP> symkp = PgfDB::malloc<PgfSymbolKP>(n_alts*sizeof(PgfAlternative));
symkp->default_form = def;
symkp->alts.len = n_alts;
*vector_elem(syms, sym_index) = ref<PgfSymbolKP>::tagged(symkp);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolKP>::tagged(symkp);
pre_sym_index = sym_index;
syms = def;
seq = def;
sym_index = 0;
alt_index = 0;
} PGF_API_END
@@ -1691,7 +1706,10 @@ public:
if (pre_sym_index == (size_t) -1)
throw pgf_error(builder_error_msg);
ref<Vector<PgfSymbol>> form = vector_new<PgfSymbol>(n_syms);
ref<PgfSequence> form = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
form->seq_id = 0;
form->ref_count = 1;
form->syms.len = n_syms;
ref<Vector<ref<PgfText>>> prefixes = vector_new<ref<PgfText>>(n_prefs);
for (size_t i = 0; i < n_prefs; i++) {
@@ -1699,14 +1717,14 @@ public:
*vector_elem(prefixes, i) = pref;
}
syms = *vector_elem(seqs, seq_index);
ref<PgfSymbolKP> symkp = ref<PgfSymbolKP>::untagged(*vector_elem(syms, pre_sym_index));
seq = *vector_elem(seqs, seq_index);
ref<PgfSymbolKP> symkp = ref<PgfSymbolKP>::untagged(*vector_elem(&seq->syms, pre_sym_index));
ref<PgfAlternative> alt = ref<PgfAlternative>::from_ptr(&symkp->alts.data[alt_index]);
alt->form = form;
alt->prefixes = prefixes;
syms = form;
seq = form;
sym_index = 0;
} PGF_API_END
}
@@ -1720,8 +1738,8 @@ public:
if (pre_sym_index == (size_t) -1)
throw pgf_error(builder_error_msg);
syms = *vector_elem(seqs, seq_index);
ref<PgfSymbolKP> symkp = ref<PgfSymbolKP>::untagged(*vector_elem(syms, pre_sym_index));
seq = *vector_elem(seqs, seq_index);
ref<PgfSymbolKP> symkp = ref<PgfSymbolKP>::untagged(*vector_elem(&seq->syms, pre_sym_index));
if (alt_index >= symkp->alts.len)
throw pgf_error(builder_error_msg);
@@ -1738,7 +1756,7 @@ public:
if (pre_sym_index == (size_t) -1)
throw pgf_error(builder_error_msg);
syms = *vector_elem(seqs, seq_index);
seq = *vector_elem(seqs, seq_index);
sym_index = pre_sym_index+1;
alt_index = 0;
pre_sym_index = (size_t) -1;
@@ -1751,10 +1769,10 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolBIND>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolBIND>::tagged(0);
sym_index++;
} PGF_API_END
}
@@ -1765,10 +1783,10 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolSOFTBIND>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolSOFTBIND>::tagged(0);
sym_index++;
} PGF_API_END
}
@@ -1779,10 +1797,10 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolNE>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolNE>::tagged(0);
sym_index++;
} PGF_API_END
}
@@ -1793,10 +1811,10 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolSOFTSPACE>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolSOFTSPACE>::tagged(0);
sym_index++;
} PGF_API_END
}
@@ -1807,10 +1825,10 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolCAPIT>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolCAPIT>::tagged(0);
sym_index++;
} PGF_API_END
}
@@ -1821,27 +1839,57 @@ public:
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index == (size_t) -1 || sym_index >= syms->len)
if (seq == 0 || sym_index == (size_t) -1 || sym_index >= seq->syms.len)
throw pgf_error(builder_error_msg);
*vector_elem(syms, sym_index) = ref<PgfSymbolALLCAPIT>::tagged(0);
*vector_elem(&seq->syms, sym_index) = ref<PgfSymbolALLCAPIT>::tagged(0);
sym_index++;
} PGF_API_END
}
void end_sequence(PgfExn *err)
object end_sequence(PgfExn *err)
{
if (err->type != PGF_EXN_NONE)
return 0;
ref<PgfSequence> res = 0;
PGF_API_BEGIN {
if (seq == 0 || sym_index != seq->syms.len)
throw pgf_error(builder_error_msg);
PgfPhrasetable phrasetable =
phrasetable_internalize(concr->phrasetable, &seq);
if (phrasetable != concr->phrasetable) {
phrasetable_release(concr->phrasetable);
concr->phrasetable = phrasetable;
} else {
*vector_elem(seqs, seq_index) = seq;
}
res = seq;
sym_index = (size_t) -1;
seq = 0;
seq_index++;
} PGF_API_END
return res.as_object();
}
void add_sequence_id(object seq_id, PgfExn *err)
{
if (err->type != PGF_EXN_NONE)
return;
PGF_API_BEGIN {
if (syms == 0 || sym_index != syms->len)
if (seq_index >= seqs->len)
throw pgf_error(builder_error_msg);
sym_index = (size_t) -1;
syms = 0;
*vector_elem(seqs, seq_index) = seq_id;
seq_index++;
} PGF_API_END
}
}
void end_production(PgfExn *err)
{
@@ -1882,33 +1930,33 @@ public:
PgfDB::free(res);
for (size_t i = 0; i < seq_index; i++) {
ref<Vector<PgfSymbol>> syms = *vector_elem(seqs, i);
pgf_symbols_free(syms);
ref<PgfSequence> seq = *vector_elem(seqs, i);
PgfSequence::release(seq);
}
if (sym_index != (size_t) -1) {
ref<Vector<PgfSymbol>> syms = *vector_elem(seqs, seq_index);
ref<PgfSequence> seq = *vector_elem(seqs, seq_index);
if (pre_sym_index != (size_t) -1) {
auto sym_kp = ref<PgfSymbolKP>::untagged(*vector_elem(syms, pre_sym_index));
auto sym_kp = ref<PgfSymbolKP>::untagged(*vector_elem(&seq->syms, pre_sym_index));
if (this->syms == sym_kp->default_form) {
if (this->seq == sym_kp->default_form) {
for (size_t i = 0; i < sym_index; i++) {
PgfSymbol sym = *vector_elem(syms, i);
PgfSymbol sym = *vector_elem(&seq->syms, i);
pgf_symbol_free(sym);
}
PgfDB::free(syms);
PgfDB::free(seq);
} else {
pgf_symbols_free(sym_kp->default_form);
PgfSequence::release(sym_kp->default_form);
for (size_t i = 0; i < alt_index; i++) {
pgf_symbols_free(sym_kp->alts.data[i].form);
PgfSequence::release(sym_kp->alts.data[i].form);
for (size_t j = 0; j < sym_kp->alts.data[i].prefixes->len; j++) {
ref<PgfText> prefix = *vector_elem(sym_kp->alts.data[i].prefixes, j);
PgfDB::free(prefix);
}
}
for (size_t i = 0; i < sym_index; i++) {
PgfSymbol sym = *vector_elem(sym_kp->alts.data[alt_index].form, i);
PgfSymbol sym = *vector_elem(&sym_kp->alts.data[alt_index].form->syms, i);
pgf_symbol_free(sym);
}
PgfDB::free(sym_kp->alts.data[alt_index].form);
@@ -1923,10 +1971,10 @@ public:
}
for (size_t j = 0; j < sym_index; j++) {
PgfSymbol sym = *vector_elem(syms, j);
PgfSymbol sym = *vector_elem(&seq->syms, j);
pgf_symbol_free(sym);
}
PgfDB::free(syms);
PgfDB::free(seq);
}
PgfDB::free(seqs);
@@ -1954,7 +2002,7 @@ void pgf_create_lincat(PgfDB *db,
}
ref<PgfConcrLincat> lincat =
PgfLinBuilder().build(abscat, concr, n_fields, fields, n_lindefs, n_linrefs, build, err);
PgfLinBuilder(concr).build(abscat, n_fields, fields, n_lindefs, n_linrefs, build, err);
if (lincat != 0) {
Namespace<PgfConcrLincat> lincats =
namespace_insert(concr->lincats, lincat);
@@ -2004,7 +2052,7 @@ void pgf_create_lin(PgfDB *db,
}
ref<PgfConcrLin> lin =
PgfLinBuilder().build(absfun, concr, n_prods, build, err);
PgfLinBuilder(concr).build(absfun, n_prods, build, err);
if (lin != 0) {
Namespace<PgfConcrLin> lins =
namespace_insert(concr->lins, lin);

View File

@@ -396,6 +396,15 @@ PGF_API_DECL
void pgf_iter_lins(PgfDB *db, PgfConcrRevision cnc_revision,
PgfItor *itor, PgfExn *err);
typedef struct PgfSequenceItor PgfSequenceItor;
struct PgfSequenceItor {
void (*fn)(PgfSequenceItor* self, object value, PgfExn *err);
};
PGF_API
void pgf_iter_sequences(PgfDB *db, PgfConcrRevision cnc_revision,
PgfSequenceItor *itor, PgfExn *err);
PGF_API_DECL
void pgf_get_lincat_counts_internal(object o, size_t *counts);
@@ -403,25 +412,19 @@ PGF_API_DECL
PgfText *pgf_get_lincat_field_internal(object o, size_t i);
PGF_API_DECL
void pgf_get_lin_counts_internal(object o, size_t *counts);
size_t pgf_get_lin_get_prod_count(object o);
PGF_API_DECL
PgfText *pgf_print_lindef_sig_internal(object o, size_t i);
PgfText *pgf_print_lindef_internal(object o, size_t i);
PGF_API_DECL
PgfText *pgf_print_lindef_seq_internal(object o, size_t i, size_t j);
PgfText *pgf_print_linref_internal(object o, size_t i);
PGF_API_DECL
PgfText *pgf_print_linref_sig_internal(object o, size_t i);
PgfText *pgf_print_lin_internal(object o, size_t i);
PGF_API_DECL
PgfText *pgf_print_linref_seq_internal(object o, size_t i);
PGF_API_DECL
PgfText *pgf_print_lin_sig_internal(object o, size_t i);
PGF_API_DECL
PgfText *pgf_print_lin_seq_internal(object o, size_t i, size_t j);
PgfText *pgf_print_sequence_internal(object o);
PGF_API_DECL
void pgf_check_expr(PgfDB *db, PgfRevision revision,
@@ -515,7 +518,8 @@ struct PgfLinBuilderIface {
virtual void add_symsoftspace(PgfExn *err)=0;
virtual void add_symcapit(PgfExn *err)=0;
virtual void add_symallcapit(PgfExn *err)=0;
virtual void end_sequence(PgfExn *err)=0;
virtual object end_sequence(PgfExn *err)=0;
virtual void add_sequence_id(object seq_id, PgfExn *err)=0;
virtual void end_production(PgfExn *err)=0;
};
@@ -545,7 +549,8 @@ typedef struct {
void (*add_symsoftspace)(PgfLinBuilderIface *this, PgfExn *err);
void (*add_symcapit)(PgfLinBuilderIface *this, PgfExn *err);
void (*add_symallcapit)(PgfLinBuilderIface *this, PgfExn *err);
void (*end_sequence)(PgfLinBuilderIface *this, PgfExn *err);
object (*end_sequence)(PgfLinBuilderIface *this, PgfExn *err);
void (*add_sequence_id)(PgfLinBuilderIface *this, object seq_id, PgfExn *err);
void (*end_production)(PgfLinBuilderIface *this, PgfExn *err);
} PgfLinBuilderIfaceVtbl;

View File

@@ -0,0 +1,239 @@
#include "data.h"
static
int lparam_cmp(PgfLParam *p1, PgfLParam *p2)
{
if (p1->i0 < p2->i0)
return -1;
else if (p1->i0 > p2->i0)
return 1;
for (size_t i = 0; ; i++) {
if (i >= p1->n_terms)
return -(i < p2->n_terms);
if (i >= p2->n_terms)
return 1;
if (p1->terms[i].factor > p2->terms[i].factor)
return 1;
else if (p1->terms[i].factor < p2->terms[i].factor)
return -1;
else if (p1->terms[i].var > p2->terms[i].var)
return 1;
else if (p1->terms[i].var < p2->terms[i].var)
return -1;
}
return 0;
}
static
int sequence_cmp(ref<PgfSequence> seq1, ref<PgfSequence> seq2);
static
void symbol_cmp(PgfSymbol sym1, PgfSymbol sym2, int res[2])
{
uint8_t t1 = ref<PgfSymbol>::get_tag(sym1);
uint8_t t2 = ref<PgfSymbol>::get_tag(sym2);
if (t1 != t2) {
res[0] = (res[1] = ((int) t1) - ((int) t2));
return;
}
switch (t1) {
case PgfSymbolCat::tag: {
auto sym_cat1 = ref<PgfSymbolCat>::untagged(sym1);
auto sym_cat2 = ref<PgfSymbolCat>::untagged(sym2);
if (sym_cat1->d < sym_cat2->d)
res[0] = (res[1] = -1);
else if (sym_cat1->d > sym_cat2->d)
res[0] = (res[1] = 1);
else
res[0] = (res[1] = lparam_cmp(&sym_cat1->r, &sym_cat2->r));
break;
}
case PgfSymbolLit::tag: {
auto sym_lit1 = ref<PgfSymbolLit>::untagged(sym1);
auto sym_lit2 = ref<PgfSymbolLit>::untagged(sym2);
if (sym_lit1->d < sym_lit2->d)
res[0] = (res[1] = -1);
else if (sym_lit1->d > sym_lit2->d)
res[0] = (res[1] = 1);
else
res[0] = (res[1] = lparam_cmp(&sym_lit1->r, &sym_lit2->r));
break;
}
case PgfSymbolVar::tag: {
auto sym_var1 = ref<PgfSymbolVar>::untagged(sym1);
auto sym_var2 = ref<PgfSymbolVar>::untagged(sym2);
if (sym_var1->d < sym_var2->d)
res[0] = (res[1] = -1);
else if (sym_var1->d > sym_var2->d)
res[0] = (res[1] = 1);
else if (sym_var1->r < sym_var2->r)
res[0] = (res[1] = -1);
else if (sym_var1->r > sym_var2->r)
res[0] = (res[1] = 1);
break;
}
case PgfSymbolKS::tag: {
auto sym_ks1 = ref<PgfSymbolKS>::untagged(sym1);
auto sym_ks2 = ref<PgfSymbolKS>::untagged(sym2);
texticmp(&sym_ks1->token,&sym_ks2->token,res);
break;
}
case PgfSymbolKP::tag: {
auto sym_kp1 = ref<PgfSymbolKP>::untagged(sym1);
auto sym_kp2 = ref<PgfSymbolKP>::untagged(sym2);
res[0] = (res[1] = sequence_cmp(sym_kp1->default_form, sym_kp2->default_form));
if (res[0] != 0)
return;
for (size_t i = 0; ; i++) {
if (i >= sym_kp1->alts.len) {
res[0] = (res[1] = -(i < sym_kp2->alts.len));
return;
}
if (i >= sym_kp2->alts.len) {
res[0] = (res[1] = 1);
return;
}
res[0] = (res[1] = sequence_cmp(sym_kp1->alts.data[i].form, sym_kp2->alts.data[i].form));
if (res[0] != 0)
return;
ref<Vector<ref<PgfText>>> prefixes1 = sym_kp1->alts.data[i].prefixes;
ref<Vector<ref<PgfText>>> prefixes2 = sym_kp2->alts.data[i].prefixes;
for (size_t j = 0; ; j++) {
if (j >= prefixes1->len) {
res[0] = (res[1] = -(j < prefixes2->len));
return;
}
if (j >= prefixes2->len) {
res[0] = (res[1] = 1);
return;
}
res[0] = (res[1] = textcmp(&(**vector_elem(prefixes1, j)), &(**vector_elem(prefixes2, j))));
if (res[0] != 0)
return;
}
}
}
case PgfSymbolBIND::tag:
case PgfSymbolSOFTBIND::tag:
case PgfSymbolNE::tag:
case PgfSymbolSOFTSPACE::tag:
case PgfSymbolCAPIT::tag:
case PgfSymbolALLCAPIT::tag:
break;
default:
throw pgf_error("Unknown symbol tag");
}
}
static
int sequence_cmp(ref<PgfSequence> seq1, ref<PgfSequence> seq2)
{
int res[2] = {0,0};
for (size_t i = 0; ; i++) {
if (i >= seq1->syms.len) {
if (i < seq2->syms.len)
return -1;
return res[1];
}
if (i >= seq2->syms.len)
return 1;
symbol_cmp(seq1->syms.data[i], seq2->syms.data[i], res);
if (res[0] != 0)
return res[0];
}
return 0;
}
PGF_INTERNAL
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table, ref<PgfSequence> *pseq)
{
if (table == 0) {
PgfPhrasetable table = Node<PgfSequence>::new_node(*pseq);
Node<PgfSequence>::add_value_ref(table->value);
return table;
}
int cmp = sequence_cmp(*pseq,table->value);
if (cmp < 0) {
PgfPhrasetable left = phrasetable_internalize(table->left, pseq);
if (left == table->left)
return table;
else {
PgfPhrasetable node = Node<PgfSequence>::balanceL(table->value,left,table->right);
namespace_release(left);
return node;
}
} else if (cmp > 0) {
PgfPhrasetable right = phrasetable_internalize(table->right, pseq);
if (right == table->right)
return table;
else {
PgfPhrasetable node = Node<PgfSequence>::balanceR(table->value, table->left, right);
phrasetable_release(right);
return node;
}
} else {
if (!(--(*pseq)->ref_count)) {
PgfSequence::release(*pseq);
}
Node<PgfSequence>::add_value_ref(table->value);
*pseq = table->value;
return table;
}
}
PGF_INTERNAL_DECL
ref<PgfSequence> phrasetable_get(PgfPhrasetable table, size_t seq_id)
{
while (table != 0) {
size_t left_sz = table->left->sz;
if (seq_id < left_sz)
table = table->left;
else if (seq_id == left_sz)
return table->value;
else {
table = table->right;
seq_id -= left_sz+1;
}
}
return 0;
}
PGF_INTERNAL
void phrasetable_iter(PgfPhrasetable table, PgfSequenceItor* itor, size_t *p_next_id, PgfExn *err)
{
if (table == 0)
return;
phrasetable_iter(table->left, itor, p_next_id, err);
if (err->type != PGF_EXN_NONE)
return;
table->value->seq_id = (*p_next_id)++;
itor->fn(itor, table->value.as_object(), err);
if (err->type != PGF_EXN_NONE)
return;
phrasetable_iter(table->right, itor, p_next_id, err);
if (err->type != PGF_EXN_NONE)
return;
}
PGF_INTERNAL
void phrasetable_release(PgfPhrasetable table)
{
namespace_release(table);
}

View File

@@ -0,0 +1,20 @@
#ifndef PHRASETABLE_H
#define PHRASETABLE_H
class PgfSequence;
class PgfSequenceItor;
typedef ref<Node<PgfSequence>> PgfPhrasetable;
PGF_INTERNAL_DECL
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table, ref<PgfSequence> *seq);
PGF_INTERNAL_DECL
ref<PgfSequence> phrasetable_get(PgfPhrasetable table, size_t seq_id);
PGF_INTERNAL_DECL
void phrasetable_iter(PgfPhrasetable table, PgfSequenceItor* itor, size_t *p_next_id, PgfExn *err);
PGF_INTERNAL_DECL
void phrasetable_release(PgfPhrasetable table);
#endif

View File

@@ -529,11 +529,11 @@ void PgfPrinter::symbol(PgfSymbol sym)
auto sym_kp = ref<PgfSymbolKP>::untagged(sym);
puts("pre {");
symbols(sym_kp->default_form);
sequence(sym_kp->default_form);
for (size_t i = 0; i < sym_kp->alts.len; i++) {
puts("; ");
symbols(sym_kp->alts.data[i].form);
sequence(sym_kp->alts.data[i].form);
puts(" /");
for (size_t j = 0; j < sym_kp->alts.data[i].prefixes->len; j++) {
puts(" ");
@@ -565,16 +565,21 @@ void PgfPrinter::symbol(PgfSymbol sym)
}
}
void PgfPrinter::symbols(ref<Vector<PgfSymbol>> syms)
void PgfPrinter::sequence(ref<PgfSequence> seq)
{
for (size_t i = 0; i < syms->len; i++) {
for (size_t i = 0; i < seq->syms.len; i++) {
if (i > 0)
puts(" ");
symbol(*vector_elem(syms, i));
symbol(*vector_elem(&seq->syms, i));
}
}
void PgfPrinter::seq_id(size_t seq_id)
{
nprintf(5, "S%zu", seq_id);
}
void PgfPrinter::free_ref(object x)
{
}

View File

@@ -56,8 +56,9 @@ public:
void lvar(size_t var);
void lparam(ref<PgfLParam> lparam);
void lvar_ranges(ref<Vector<PgfVariableRange>> vars);
void seq_id(size_t seqid);
void symbol(PgfSymbol sym);
void symbols(ref<Vector<PgfSymbol>> syms);
void sequence(ref<PgfSequence> seq);
virtual PgfExpr eabs(PgfBindType btype, PgfText *name, PgfExpr body);
virtual PgfExpr eapp(PgfExpr fun, PgfExpr arg);

View File

@@ -7,6 +7,7 @@ PgfReader::PgfReader(FILE *in)
{
this->in = in;
this->abstract = 0;
this->concrete = 0;
}
uint8_t PgfReader::read_uint8()
@@ -515,14 +516,14 @@ PgfSymbol PgfReader::read_symbol()
sym_kp->alts.len = n_alts;
for (size_t i = 0; i < n_alts; i++) {
auto form = read_vector(&PgfReader::read_symbol2);
auto form = read_seq();
auto prefixes = read_vector(&PgfReader::read_text2);
sym_kp->alts.data[i].form = form;
sym_kp->alts.data[i].prefixes = prefixes;
}
auto default_form = read_vector(&PgfReader::read_symbol2);
auto default_form = read_seq();
sym_kp->default_form = default_form;
sym = ref<PgfSymbolKP>::tagged(sym_kp);
@@ -559,6 +560,32 @@ PgfSymbol PgfReader::read_symbol()
return sym;
}
ref<PgfSequence> PgfReader::read_seq()
{
size_t n_syms = read_len();
ref<PgfSequence> seq = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
seq->seq_id = 0;
seq->ref_count = 1;
seq->syms.len = n_syms;
for (size_t i = 0; i < n_syms; i++) {
PgfSymbol sym = read_symbol();
*vector_elem(&seq->syms,i) = sym;
}
return seq;
}
void PgfReader::read_seq_id(ref<ref<PgfSequence>> r)
{
size_t seq_id = read_len();
ref<PgfSequence> seq = phrasetable_get(concrete->phrasetable, seq_id);
if (seq == 0)
throw pgf_error("Invalid sequence id");
*r = seq;
}
ref<PgfConcrLincat> PgfReader::read_lincat()
{
ref<PgfConcrLincat> lincat = read_name(&PgfConcrLincat::name);
@@ -568,7 +595,7 @@ ref<PgfConcrLincat> PgfReader::read_lincat()
lincat->n_lindefs = read_len();
lincat->args = read_vector(&PgfReader::read_parg);
lincat->res = read_vector(&PgfReader::read_presult2);
lincat->seqs = read_vector(&PgfReader::read_seq2);
lincat->seqs = read_vector(&PgfReader::read_seq_id);
return lincat;
}
@@ -579,7 +606,7 @@ ref<PgfConcrLin> PgfReader::read_lin()
lin->absfun = namespace_lookup(abstract->funs, &lin->name);
lin->args = read_vector(&PgfReader::read_parg);
lin->res = read_vector(&PgfReader::read_presult2);
lin->seqs = read_vector(&PgfReader::read_seq2);
lin->seqs = read_vector(&PgfReader::read_seq_id);
return lin;
}
@@ -593,16 +620,17 @@ ref<PgfConcrPrintname> PgfReader::read_printname()
ref<PgfConcr> PgfReader::read_concrete()
{
ref<PgfConcr> concr = read_name(&PgfConcr::name);
concr->ref_count = 1;
concr->ref_count_ex = 0;
concr->cflags = read_namespace<PgfFlag>(&PgfReader::read_flag);
concr->lincats = read_namespace<PgfConcrLincat>(&PgfReader::read_lincat);
concr->lins = read_namespace<PgfConcrLin>(&PgfReader::read_lin);
concr->printnames = read_namespace<PgfConcrPrintname>(&PgfReader::read_printname);
concr->prev = 0;
concr->next = 0;
return concr;
concrete = read_name(&PgfConcr::name);
concrete->ref_count = 1;
concrete->ref_count_ex = 0;
concrete->cflags = read_namespace<PgfFlag>(&PgfReader::read_flag);
concrete->phrasetable = read_namespace<PgfSequence>(&PgfReader::read_seq);
concrete->lincats = read_namespace<PgfConcrLincat>(&PgfReader::read_lincat);
concrete->lins = read_namespace<PgfConcrLin>(&PgfReader::read_lin);
concrete->printnames = read_namespace<PgfConcrPrintname>(&PgfReader::read_printname);
concrete->prev = 0;
concrete->next = 0;
return concrete;
}
ref<PgfPGF> PgfReader::read_pgf()

View File

@@ -73,6 +73,8 @@ public:
void read_parg(ref<PgfPArg> parg);
ref<PgfPResult> read_presult();
PgfSymbol read_symbol();
ref<PgfSequence> read_seq();
void read_seq_id(ref<ref<PgfSequence>> r);
ref<PgfConcrLin> read_lin();
ref<PgfConcrPrintname> read_printname();
@@ -84,14 +86,13 @@ public:
private:
FILE *in;
ref<PgfAbstr> abstract;
ref<PgfConcr> concrete;
object read_name_internal(size_t struct_size);
object read_text_internal(size_t struct_size);
void read_text2(ref<ref<PgfText>> r) { auto text = read_text(); *r = text; };
void read_lparam(ref<ref<PgfLParam>> r) { auto lparam = read_lparam(); *r = lparam; };
void read_symbol2(ref<PgfSymbol> r) { auto sym = read_symbol(); *r = sym; };
void read_seq2(ref<ref<Vector<PgfSymbol>>> r) { auto seq = read_vector(&PgfReader::read_symbol2); *r = seq; }
void read_text2(ref<ref<PgfText>> r) { auto text = read_text(); *r = text; }
void read_lparam(ref<ref<PgfLParam>> r) { auto lparam = read_lparam(); *r = lparam; }
void read_presult2(ref<ref<PgfPResult>> r) { auto res = read_presult(); *r = res; }
template<class I>

View File

@@ -5,7 +5,7 @@ int textcmp(PgfText *t1, PgfText *t2)
{
for (size_t i = 0; ; i++) {
if (i >= t1->size)
return (i - t2->size);
return -(i < t2->size);
if (i >= t2->size)
return 1;
@@ -16,6 +16,48 @@ int textcmp(PgfText *t1, PgfText *t2)
}
}
PGF_INTERNAL
void texticmp(PgfText *t1, PgfText *t2, int res[2])
{
const uint8_t *s1 = (uint8_t*) &t1->text;
const uint8_t *e1 = s1+t1->size;
const uint8_t *s2 = (uint8_t*) &t2->text;
const uint8_t *e2 = s2+t2->size;
for (;;) {
if (s1 >= e1) {
res[0] = (res[1] = -(s2 < e2));
return;
}
if (s2 >= e2) {
res[0] = (res[1] = 1);
return;
}
uint32_t ucs1 = pgf_utf8_decode(&s1);
uint32_t ucs1i = pgf_utf8_to_upper(ucs1);
uint32_t ucs2 = pgf_utf8_decode(&s2);
uint32_t ucs2i = pgf_utf8_to_upper(ucs2);
if (ucs1i > ucs2i) {
res[0] = (res[1] = 1);
return;
}
else if (ucs1i < ucs2i) {
res[0] = (res[1] = -1);
return;
}
else if (res[1] == 0) {
if (ucs1 > ucs2)
res[1] = 1;
else if (ucs1 < ucs2)
res[1] = -1;
}
}
}
PGF_INTERNAL
bool textstarts(PgfText *t, PgfText *prefix)
{
@@ -49,7 +91,7 @@ ref<PgfText> textdup_db(PgfText *t1)
}
PGF_API uint32_t
pgf_utf8_decode(const uint8_t** src_inout)
pgf_utf8_decode(const uint8_t **src_inout)
{
const uint8_t* src = *src_inout;
uint8_t c = src[0];
@@ -74,7 +116,7 @@ pgf_utf8_decode(const uint8_t** src_inout)
}
PGF_API void
pgf_utf8_encode(uint32_t ucs, uint8_t** buf)
pgf_utf8_encode(uint32_t ucs, uint8_t **buf)
{
uint8_t* p = *buf;
if (ucs < 0x80) {

View File

@@ -1,9 +1,19 @@
#ifndef TEXT_H
#define TEXT_H
/* Case sensitive comparison */
PGF_INTERNAL_DECL
int textcmp(PgfText *t1, PgfText *t2);
/* Performs both case-insensitive and case-sensitive comparison.
* The first element in res contains the result from
* the case-insensitive comparison. The second the result
* from case-sensitive one. Usually res must be initialized
* with {0,0}. If it is not then that can be used
* to chain a list of comparisons.*/
PGF_INTERNAL_DECL
void texticmp(PgfText *t1, PgfText *t2, int res[2]);
PGF_INTERNAL_DECL
bool textstarts(PgfText *t, PgfText *prefix);

View File

@@ -30,4 +30,10 @@ ref<A> vector_elem(ref<Vector<A>> v, size_t index)
return ref<A>::from_ptr(&v->data[index]);
}
template <class A> inline
A *vector_elem(Vector<A> *v, size_t index)
{
return &v->data[index];
}
#endif // VECTOR_H

View File

@@ -135,7 +135,7 @@ void PgfWriter::write_text(PgfText *text)
template<class V>
void PgfWriter::write_namespace(Namespace<V> nmsp, void (PgfWriter::*write_value)(ref<V>))
{
write_len(nmsp->sz);
write_len(namespace_size(nmsp));
write_namespace_helper(nmsp, write_value);
}
@@ -393,10 +393,11 @@ void PgfWriter::write_symbol(PgfSymbol sym)
auto sym_kp = ref<PgfSymbolKP>::untagged(sym);
write_len(sym_kp->alts.len);
for (size_t i = 0; i < sym_kp->alts.len; i++) {
write_seq(sym_kp->alts.data[i].form);
write_vector(sym_kp->alts.data[i].prefixes, &PgfWriter::write_text);
PgfAlternative *alt = vector_elem(&sym_kp->alts, i);
write_vector(ref<Vector<PgfSymbol>>::from_ptr(&alt->form->syms), &PgfWriter::write_symbol);
write_vector(alt->prefixes, &PgfWriter::write_text);
}
write_seq(sym_kp->default_form);
write_vector(ref<Vector<PgfSymbol>>::from_ptr(&sym_kp->default_form->syms), &PgfWriter::write_symbol);
break;
}
case PgfSymbolBIND::tag:
@@ -411,9 +412,10 @@ void PgfWriter::write_symbol(PgfSymbol sym)
}
}
void PgfWriter::write_seq(ref<Vector<PgfSymbol>> seq)
void PgfWriter::write_seq(ref<PgfSequence> seq)
{
write_vector(seq, &PgfWriter::write_symbol);
seq->seq_id = next_seq_id++;
write_vector(ref<Vector<PgfSymbol>>::from_ptr(&seq->syms), &PgfWriter::write_symbol);
}
void PgfWriter::write_lincat(ref<PgfConcrLincat> lincat)
@@ -423,7 +425,7 @@ void PgfWriter::write_lincat(ref<PgfConcrLincat> lincat)
write_len(lincat->n_lindefs);
write_vector(lincat->args, &PgfWriter::write_parg);
write_vector(lincat->res, &PgfWriter::write_presult);
write_vector(lincat->seqs, &PgfWriter::write_seq);
write_vector(lincat->seqs, &PgfWriter::write_seq_id);
}
void PgfWriter::write_lin(ref<PgfConcrLin> lin)
@@ -431,7 +433,7 @@ void PgfWriter::write_lin(ref<PgfConcrLin> lin)
write_name(&lin->name);
write_vector(lin->args, &PgfWriter::write_parg);
write_vector(lin->res, &PgfWriter::write_presult);
write_vector(lin->seqs, &PgfWriter::write_seq);
write_vector(lin->seqs, &PgfWriter::write_seq_id);
}
void PgfWriter::write_printname(ref<PgfConcrPrintname> printname)
@@ -442,8 +444,11 @@ void PgfWriter::write_printname(ref<PgfConcrPrintname> printname)
void PgfWriter::write_concrete(ref<PgfConcr> concr)
{
next_seq_id = 0;
write_name(&concr->name);
write_namespace<PgfFlag>(concr->cflags, &PgfWriter::write_flag);
write_namespace<PgfSequence>(concr->phrasetable, &PgfWriter::write_seq);
write_namespace<PgfConcrLincat>(concr->lincats, &PgfWriter::write_lincat);
write_namespace<PgfConcrLin>(concr->lins, &PgfWriter::write_lin);
write_namespace<PgfConcrPrintname>(concr->printnames, &PgfWriter::write_printname);

View File

@@ -44,7 +44,8 @@ public:
void write_parg(ref<PgfPArg> linarg);
void write_presult(ref<PgfPResult> linres);
void write_symbol(PgfSymbol sym);
void write_seq(ref<Vector<PgfSymbol>> seq);
void write_seq(ref<PgfSequence> seq);
void write_seq_id(ref<ref<PgfSequence>> r) { write_len((*r)->seq_id); };
void write_lin(ref<PgfConcrLin> lin);
void write_printname(ref<PgfConcrPrintname> printname);
@@ -58,10 +59,11 @@ private:
void write_text(ref<ref<PgfText>> r) { write_text(&(**r)); };
void write_lparam(ref<ref<PgfLParam>> r) { write_lparam(*r); };
void write_seq(ref<ref<Vector<PgfSymbol>>> r) { write_seq(*r); };
void write_symbol(ref<PgfSymbol> r) { write_symbol(*r); };
void write_presult(ref<ref<PgfPResult>> r) { write_presult(*r); };
size_t next_seq_id;
FILE *out;
ref<PgfAbstr> abstract;
};

View File

@@ -222,11 +222,15 @@ showPGF p =
def <- bracket (pgf_print_function_internal val) free peekText
modifyIORef ref (\doc -> doc $$ text def)
ppConcr name c =
text "concrete" <+> text name <+> char '{' $$
nest 2 (ppLincats c $$
ppLins c) $$
char '}'
ppConcr name c = unsafePerformIO $ do
doc <- prepareSequences c -- run first to update all seq_id
return (text "concrete" <+> text name <+> char '{' $$
nest 2 (ppLincats c $$
ppLins c $$
(text "sequences" <+> char '{' $$
nest 2 doc $$
char '}')) $$
char '}')
ppLincats c = unsafePerformIO $ do
ref <- newIORef empty
@@ -248,32 +252,20 @@ showPGF p =
n_lindefs <- peekElemOff pcounts 1
n_linrefs <- peekElemOff pcounts 2
return (n_fields,n_lindefs,n_linrefs)
fields <- allocaBytes (3*(#size size_t)) $ \pcounts -> do
forM (init [0..n_fields]) $ \i -> do
pgf_get_lincat_field_internal val i >>= peekText
fields <- forM (init [0..n_fields]) $ \i -> do
pgf_get_lincat_field_internal val i >>= peekText
let def = text "lincat" <+> (text name <+> char '=' <+> char '[' $$
nest 2 (vcat (map (text.show) fields)) $$
char ']')
modifyIORef ref $ (\doc -> doc $$ def)
forM_ (init [0..n_lindefs]) $ \i -> do
sig <- bracket (pgf_print_lindef_sig_internal val i) free $ \c_text -> do
def <- bracket (pgf_print_lindef_internal val i) free $ \c_text -> do
fmap text (peekText c_text)
seqs <- forM (init [0..n_fields]) $ \j ->
bracket (pgf_print_lindef_seq_internal val i j) free $ \c_text -> do
fmap text (peekText c_text)
let def = text "lindef" <+> (sig <+> char '=' <+> char '[' $$
nest 2 (vcat seqs) $$
char ']')
modifyIORef ref $ (\doc -> doc $$ def)
modifyIORef ref (\doc -> doc $$ text "lindef" <+> def)
forM_ (init [0..n_linrefs]) $ \i -> do
sig <- bracket (pgf_print_linref_sig_internal val i) free $ \c_text -> do
def <- bracket (pgf_print_linref_internal val i) free $ \c_text -> do
fmap text (peekText c_text)
seq <- bracket (pgf_print_linref_seq_internal val i) free $ \c_text -> do
fmap text (peekText c_text)
let def = text "linref" <+> (sig <+> char '=' <+> char '[' $$
nest 2 seq $$
char ']')
modifyIORef ref $ (\doc -> doc $$ def)
modifyIORef ref $ (\doc -> doc $$ text "linref" <+> def)
ppLins c = unsafePerformIO $ do
ref <- newIORef empty
@@ -285,22 +277,28 @@ showPGF p =
readIORef ref
where
getLins :: IORef Doc -> ItorCallback
getLins ref itor key val exn =
allocaBytes (2*(#size size_t)) $ \pcounts -> do
pgf_get_lin_counts_internal val pcounts
n_prods <- peekElemOff pcounts 0
n_seqs <- peekElemOff pcounts 1
forM_ (init [0..n_prods]) $ \i -> do
sig <- bracket (pgf_print_lin_sig_internal val i) free $ \c_text -> do
fmap text (peekText c_text)
syms <- forM (init [0..n_seqs]) $ \j ->
bracket (pgf_print_lin_seq_internal val i j) free $ \c_text -> do
fmap text (peekText c_text)
let def = text "lin" <+> (sig <+> char '=' <+> char '[' $$
nest 2 (vcat syms) $$
char ']')
modifyIORef ref $ (\doc -> doc $$ def)
return ()
getLins ref itor key val exn = do
n_prods <- pgf_get_lin_get_prod_count val
forM_ (init [0..n_prods]) $ \i -> do
def <- bracket (pgf_print_lin_internal val i) free $ \c_text -> do
fmap text (peekText c_text)
modifyIORef ref (\doc -> doc $$ text "lin" <+> def)
return ()
prepareSequences c = do
ref <- newIORef empty
(allocaBytes (#size PgfSequenceItor) $ \itor ->
bracket (wrapSequenceItorCallback (getSequences ref)) freeHaskellFunPtr $ \fptr ->
withForeignPtr (c_revision c) $ \c_revision -> do
(#poke PgfSequenceItor, fn) itor fptr
withPgfExn "showPGF" (pgf_iter_sequences (a_db p) c_revision itor))
readIORef ref
where
getSequences :: IORef Doc -> SequenceItorCallback
getSequences ref itor val exn = do
def <- bracket (pgf_print_sequence_internal val) free $ \c_text -> do
fmap text (peekText c_text)
modifyIORef ref $ (\doc -> doc $$ def)
-- | The abstract language name is the name of the top-level
-- abstract module

View File

@@ -45,6 +45,7 @@ data PgfBuildLinIface
data PgfLinBuilderIface
data PgfLinearizationOutputIface
data PgfGraphvizOptions
data PgfSequenceItor
type Wrapper a = a -> IO (FunPtr a)
type Dynamic a = FunPtr a -> a
@@ -110,23 +111,25 @@ foreign import ccall pgf_iter_lincats :: Ptr PgfDB -> Ptr Concr -> Ptr PgfItor -
foreign import ccall pgf_iter_lins :: Ptr PgfDB -> Ptr Concr -> Ptr PgfItor -> Ptr PgfExn -> IO ()
type SequenceItorCallback = Ptr PgfSequenceItor -> Ptr () -> Ptr PgfExn -> IO ()
foreign import ccall "wrapper" wrapSequenceItorCallback :: Wrapper SequenceItorCallback
foreign import ccall pgf_iter_sequences :: Ptr PgfDB -> Ptr Concr -> Ptr PgfSequenceItor -> Ptr PgfExn -> IO ()
foreign import ccall pgf_get_lincat_counts_internal :: Ptr () -> Ptr CSize -> IO ()
foreign import ccall pgf_get_lincat_field_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_lindef_sig_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_lindef_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_lindef_seq_internal :: Ptr () -> CSize -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_linref_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_linref_sig_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_get_lin_get_prod_count :: Ptr () -> IO CSize
foreign import ccall pgf_print_linref_seq_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_lin_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_get_lin_counts_internal :: Ptr () -> Ptr CSize -> IO ()
foreign import ccall pgf_print_lin_sig_internal :: Ptr () -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_lin_seq_internal :: Ptr () -> CSize -> CSize -> IO (Ptr PgfText)
foreign import ccall pgf_print_sequence_internal :: Ptr () -> IO (Ptr PgfText)
type ItorCallback = Ptr PgfItor -> Ptr PgfText -> Ptr () -> Ptr PgfExn -> IO ()
@@ -200,6 +203,8 @@ foreign import ccall "dynamic" callLinBuilder5 :: Dynamic (Ptr PgfLinBuilderIfac
foreign import ccall "dynamic" callLinBuilder6 :: Dynamic (Ptr PgfLinBuilderIface -> CSize -> CSize -> Ptr (Ptr PgfText) -> Ptr PgfExn -> IO ())
foreign import ccall "dynamic" callLinBuilder7 :: Dynamic (Ptr PgfLinBuilderIface -> Ptr PgfExn -> IO CSize)
foreign import ccall pgf_create_lincat :: Ptr PgfDB -> Ptr PGF -> Ptr Concr -> Ptr PgfText -> CSize -> Ptr (Ptr PgfText) -> CSize -> CSize -> Ptr PgfBuildLinIface -> Ptr PgfExn -> IO ()
foreign import ccall pgf_drop_lincat :: Ptr PgfDB -> Ptr Concr -> Ptr PgfText -> Ptr PgfExn -> IO ()

View File

@@ -13,7 +13,7 @@ module PGF2.Transactions
, setAbstractFlag
-- concrete syntax
, Token, LIndex, LVar, LParam(..)
, Token, SeqId, LIndex, LIndex, LVar, LParam(..)
, PArg(..), Symbol(..), Production(..)
, createConcrete
@@ -21,6 +21,7 @@ module PGF2.Transactions
, dropConcrete
, mergePGF
, setConcreteFlag
, SeqTable
, createLincat
, dropLincat
, createLin
@@ -35,6 +36,8 @@ import PGF2.ByteCode
import Foreign
import Foreign.C
import Control.Exception
import qualified Data.Sequence as Seq
import Data.IORef
#include <pgf/pgf.h>
@@ -197,10 +200,11 @@ setConcreteFlag name value = Transaction $ \c_db _ c_revision c_exn ->
type Token = String
type SeqId = Int
type LIndex = Int
type LVar = Int
data LParam = LParam {-# UNPACK #-} !LIndex [(LIndex,LVar)]
deriving (Eq,Show)
deriving (Eq,Ord,Show)
data Symbol
= SymCat {-# UNPACK #-} !Int {-# UNPACK #-} !LParam
@@ -214,21 +218,23 @@ data Symbol
| SymSOFT_SPACE -- the special SOFT_SPACE token
| SymCAPIT -- the special CAPIT token
| SymALL_CAPIT -- the special ALL_CAPIT token
deriving (Eq,Show)
deriving (Eq,Ord,Show)
data PArg = PArg [(LIndex,LIndex)] {-# UNPACK #-} !LParam
deriving (Eq,Show)
data Production = Production [(LVar,LIndex)] [PArg] LParam [[Symbol]]
data Production = Production [(LVar,LIndex)] [PArg] LParam [SeqId]
deriving (Eq,Show)
createLincat :: Cat -> [String] -> [Production] -> [Production] -> Transaction Concr ()
createLincat name fields lindefs linrefs = Transaction $ \c_db c_abstr c_revision c_exn ->
type SeqTable = Seq.Seq (Either [Symbol] SeqId)
createLincat :: Cat -> [String] -> [Production] -> [Production] -> SeqTable -> Transaction Concr SeqTable
createLincat name fields lindefs linrefs seqtbl = Transaction $ \c_db c_abstr c_revision c_exn ->
let n_fields = length fields
in withText name $ \c_name ->
allocaBytes (n_fields*(#size PgfText*)) $ \c_fields ->
withTexts c_fields 0 fields $
withBuildLinIface (lindefs++linrefs) $ \c_build ->
withBuildLinIface (lindefs++linrefs) seqtbl $ \c_build ->
pgf_create_lincat c_db c_abstr c_revision c_name
(fromIntegral n_fields) c_fields
(fromIntegral (length lindefs)) (fromIntegral (length linrefs))
@@ -245,19 +251,21 @@ dropLincat name = Transaction $ \c_db _ c_revision c_exn ->
withText name $ \c_name ->
pgf_drop_lincat c_db c_revision c_name c_exn
createLin :: Fun -> [Production] -> Transaction Concr ()
createLin name prods = Transaction $ \c_db c_abstr c_revision c_exn ->
createLin :: Fun -> [Production] -> SeqTable -> Transaction Concr SeqTable
createLin name prods seqtbl = Transaction $ \c_db c_abstr c_revision c_exn ->
withText name $ \c_name ->
withBuildLinIface prods $ \c_build ->
withBuildLinIface prods seqtbl $ \c_build ->
pgf_create_lin c_db c_abstr c_revision c_name (fromIntegral (length prods)) c_build c_exn
withBuildLinIface prods f =
allocaBytes (#size PgfBuildLinIface) $ \c_build ->
allocaBytes (#size PgfBuildLinIfaceVtbl) $ \vtbl ->
bracket (wrapLinBuild build) freeHaskellFunPtr $ \c_callback -> do
(#poke PgfBuildLinIface, vtbl) c_build vtbl
(#poke PgfBuildLinIfaceVtbl, build) vtbl c_callback
f c_build
withBuildLinIface prods seqtbl f = do
ref <- newIORef seqtbl
(allocaBytes (#size PgfBuildLinIface) $ \c_build ->
allocaBytes (#size PgfBuildLinIfaceVtbl) $ \vtbl ->
bracket (wrapLinBuild (build ref)) freeHaskellFunPtr $ \c_callback -> do
(#poke PgfBuildLinIface, vtbl) c_build vtbl
(#poke PgfBuildLinIfaceVtbl, build) vtbl c_callback
f c_build)
readIORef ref
where
forM_ [] c_exn f = return ()
forM_ (x:xs) c_exn f = do
@@ -266,9 +274,9 @@ withBuildLinIface prods f =
then f x >> forM_ xs c_exn f
else return ()
build _ c_builder c_exn = do
build ref _ c_builder c_exn = do
vtbl <- (#peek PgfLinBuilderIface, vtbl) c_builder
forM_ prods c_exn $ \(Production vars args res seqs) -> do
forM_ prods c_exn $ \(Production vars args res seqids) -> do
fun <- (#peek PgfLinBuilderIfaceVtbl, start_production) vtbl
callLinBuilder0 fun c_builder c_exn
fun <- (#peek PgfLinBuilderIfaceVtbl, add_argument) vtbl
@@ -279,12 +287,17 @@ withBuildLinIface prods f =
fun <- (#peek PgfLinBuilderIfaceVtbl, add_variable) vtbl
forM_ vars c_exn $ \(v,r) ->
callLinBuilder2 fun c_builder (fromIntegral v) (fromIntegral r) c_exn
forM_ seqs c_exn $ \syms -> do
fun <- (#peek PgfLinBuilderIfaceVtbl, start_sequence) vtbl
callLinBuilder1 fun c_builder (fromIntegral (length syms)) c_exn
forM_ syms c_exn (addSymbol c_builder vtbl c_exn)
fun <- (#peek PgfLinBuilderIfaceVtbl, end_sequence) vtbl
callLinBuilder0 fun c_builder c_exn
fun <- (#peek PgfLinBuilderIfaceVtbl, add_sequence_id) vtbl
seqtbl <- readIORef ref
forM_ seqids c_exn $ \seqid ->
case Seq.index seqtbl seqid of
Left syms -> do fun <- (#peek PgfLinBuilderIfaceVtbl, start_sequence) vtbl
callLinBuilder1 fun c_builder (fromIntegral (length syms)) c_exn
forM_ syms c_exn (addSymbol c_builder vtbl c_exn)
fun <- (#peek PgfLinBuilderIfaceVtbl, end_sequence) vtbl
seqid' <- callLinBuilder7 fun c_builder c_exn
writeIORef ref $! Seq.update seqid (Right (fromIntegral seqid')) seqtbl
Right seqid -> do callLinBuilder1 fun c_builder (fromIntegral seqid) c_exn
fun <- (#peek PgfLinBuilderIfaceVtbl, end_production) vtbl
callLinBuilder0 fun c_builder c_exn