mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-08 10:42:50 -06:00
added the "alter lin" command
This commit is contained in:
@@ -406,22 +406,26 @@ Namespace<V> namespace_insert(Namespace<V> map, ref<V> value)
|
||||
}
|
||||
|
||||
template <class V>
|
||||
Namespace<V> namespace_update(Namespace<V> map, ref<V> value)
|
||||
Namespace<V> namespace_replace(Namespace<V> map,
|
||||
ref<V> value, ref<V> *old_value)
|
||||
{
|
||||
if (map == 0)
|
||||
if (map == 0) {
|
||||
*old_value = 0;
|
||||
return Node<ref<V>>::new_node(value);
|
||||
}
|
||||
|
||||
int cmp = textcmp(&value->name,&map->value->name);
|
||||
if (cmp < 0) {
|
||||
Namespace<V> left = namespace_update(map->left, value);
|
||||
Namespace<V> left = namespace_replace(map->left, value, old_value);
|
||||
map = Node<ref<V>>::upd_node(map,left,map->right);
|
||||
return Node<ref<V>>::balanceL(map);
|
||||
} else if (cmp > 0) {
|
||||
Namespace<V> right = namespace_update(map->right, value);
|
||||
Namespace<V> right = namespace_replace(map->right, value, old_value);
|
||||
map = Node<ref<V>>::upd_node(map,map->left,right);
|
||||
return Node<ref<V>>::balanceR(map);
|
||||
} else {
|
||||
map = Node<ref<V>>::upd_node(map,map->left,map->right);
|
||||
*old_value = map->value;
|
||||
map->value = value;
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -1364,8 +1364,9 @@ ref<PgfConcr> clone_concrete(ref<PgfPGF> pgf, ref<PgfConcr> concr)
|
||||
clone->printnames = concr->printnames;
|
||||
memcpy(&clone->name, &concr->name, sizeof(PgfText)+concr->name.size+1);
|
||||
|
||||
ref<PgfConcr> old_concr;
|
||||
Namespace<PgfConcr> concrs =
|
||||
namespace_update(pgf->concretes, clone);
|
||||
namespace_replace(pgf->concretes, clone, &old_concr);
|
||||
pgf->concretes = concrs;
|
||||
|
||||
PgfDB::free(concr, concr->name.size+1);
|
||||
@@ -2301,6 +2302,47 @@ void pgf_create_lin(PgfDB *db,
|
||||
} PGF_API_END
|
||||
}
|
||||
|
||||
PGF_API
|
||||
void pgf_alter_lin(PgfDB *db,
|
||||
PgfRevision revision, PgfConcrRevision cnc_revision,
|
||||
PgfText *name, size_t n_prods,
|
||||
PgfBuildLinIface *build,
|
||||
PgfExn *err)
|
||||
{
|
||||
PGF_API_BEGIN {
|
||||
DB_scope scope(db, WRITER_SCOPE);
|
||||
|
||||
ref<PgfPGF> pgf = db->revision2pgf(revision);
|
||||
ref<PgfConcr> concr = db->revision2concr(cnc_revision);
|
||||
|
||||
ref<PgfAbsFun> absfun =
|
||||
namespace_lookup(pgf->abstract.funs, name);
|
||||
if (absfun == 0) {
|
||||
throw pgf_error("There is no corresponding function in the abstract syntax");
|
||||
}
|
||||
|
||||
ref<PgfConcrLin> lin =
|
||||
PgfLinBuilder(concr).build(absfun, n_prods, build, err);
|
||||
if (lin != 0) {
|
||||
ref<PgfConcrLin> old_lin;
|
||||
Namespace<PgfConcrLin> lins =
|
||||
namespace_replace(concr->lins, lin, &old_lin);
|
||||
concr->lins = lins;
|
||||
if (old_lin != 0) {
|
||||
object container = old_lin.tagged();
|
||||
PgfPhrasetable phrasetable = concr->phrasetable;
|
||||
for (size_t i = 0; i < old_lin->seqs->len; i++) {
|
||||
ref<PgfSequence> seq = *vector_elem(old_lin->seqs, i);
|
||||
phrasetable =
|
||||
phrasetable_delete(phrasetable,container,i,seq);
|
||||
}
|
||||
concr->phrasetable = phrasetable;
|
||||
PgfConcrLin::release(old_lin);
|
||||
}
|
||||
}
|
||||
} PGF_API_END
|
||||
}
|
||||
|
||||
PGF_API
|
||||
void pgf_drop_lin(PgfDB *db,
|
||||
PgfRevision revision, PgfConcrRevision cnc_revision,
|
||||
@@ -2635,8 +2677,12 @@ void pgf_set_printname(PgfDB *db, PgfConcrRevision revision,
|
||||
memcpy(&printname->name, fun, sizeof(PgfText)+fun->size+1);
|
||||
printname->printname = textdup_db(name);
|
||||
|
||||
ref<PgfConcrPrintname> old_printname;
|
||||
Namespace<PgfConcrPrintname> printnames =
|
||||
namespace_update(concr->printnames, printname);
|
||||
namespace_replace(concr->printnames, printname, &old_printname);
|
||||
if (old_printname != 0) {
|
||||
PgfConcrPrintname::release(old_printname);
|
||||
}
|
||||
concr->printnames = printnames;
|
||||
} PGF_API_END
|
||||
}
|
||||
@@ -2680,8 +2726,13 @@ void pgf_set_global_flag(PgfDB *db, PgfRevision revision,
|
||||
memcpy(&flag->name, name, sizeof(PgfText)+name->size+1);
|
||||
PgfLiteral lit = m->match_lit(&u, value);
|
||||
flag->value = lit;
|
||||
|
||||
ref<PgfFlag> old_flag;
|
||||
Namespace<PgfFlag> gflags =
|
||||
namespace_update(pgf->gflags, flag);
|
||||
namespace_replace(pgf->gflags, flag, &old_flag);
|
||||
if (old_flag != 0) {
|
||||
PgfFlag::release(old_flag);
|
||||
}
|
||||
pgf->gflags = gflags;
|
||||
} PGF_API_END
|
||||
}
|
||||
@@ -2725,8 +2776,13 @@ void pgf_set_abstract_flag(PgfDB *db, PgfRevision revision,
|
||||
memcpy(&flag->name, name, sizeof(PgfText)+name->size+1);
|
||||
PgfLiteral lit = m->match_lit(&u, value);
|
||||
flag->value = lit;
|
||||
|
||||
ref<PgfFlag> old_flag;
|
||||
Namespace<PgfFlag> aflags =
|
||||
namespace_update(pgf->abstract.aflags, flag);
|
||||
namespace_replace(pgf->abstract.aflags, flag, &old_flag);
|
||||
if (old_flag != 0) {
|
||||
PgfFlag::release(old_flag);
|
||||
}
|
||||
pgf->abstract.aflags = aflags;
|
||||
} PGF_API_END
|
||||
}
|
||||
@@ -2770,8 +2826,13 @@ void pgf_set_concrete_flag(PgfDB *db, PgfConcrRevision revision,
|
||||
memcpy(&flag->name, name, sizeof(PgfText)+name->size+1);
|
||||
PgfLiteral lit = m->match_lit(&u, value);
|
||||
flag->value = lit;
|
||||
|
||||
ref<PgfFlag> old_flag;
|
||||
Namespace<PgfFlag> cflags =
|
||||
namespace_update(concr->cflags, flag);
|
||||
namespace_replace(concr->cflags, flag, &old_flag);
|
||||
if (old_flag != 0) {
|
||||
PgfFlag::release(old_flag);
|
||||
}
|
||||
concr->cflags = cflags;
|
||||
} PGF_API_END
|
||||
}
|
||||
|
||||
@@ -891,7 +891,10 @@ void PgfReader::merge_pgf(ref<PgfPGF> pgf)
|
||||
size_t len = read_len();
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ref<PgfConcr> concr = PgfReader::read_concrete();
|
||||
pgf->concretes =
|
||||
namespace_update(pgf->concretes, concr);
|
||||
Namespace<PgfConcr> concretes =
|
||||
namespace_insert(pgf->concretes, concr);
|
||||
if (concretes != 0)
|
||||
throw pgf_error("One and the same concrete syntax is included in several PGF files");
|
||||
pgf->concretes = concretes;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user