implement linearization with lindef

This commit is contained in:
Krasimir Angelov
2026-05-22 11:10:33 +02:00
parent 5151b67afa
commit 8f4403b745
2 changed files with 83 additions and 66 deletions
+75 -59
View File
@@ -217,8 +217,6 @@ PgfLinearizer::TreeLinNode::TreeLinNode(PgfLinearizer *linearizer, ref<PgfConcrL
bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
{
vector<PgfHypo> hypos = lin->absfun->type->hypos;
while (rule_index < lin->rules.size()) {
Item *item = new (lin->rules[rule_index]) Item();
item->rule = lin->rules[rule_index];
@@ -226,8 +224,6 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
int i = 0;
TreeNode *arg = args;
while (arg != NULL) {
arg->check_category(linearizer, &hypos[i].type->name);
if (!item->instantiate(item->rule->args[i], arg->value))
goto next;
@@ -275,10 +271,9 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
return true;
}
void PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
bool PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
{
if (textcmp(&lin->absfun->type->name, cat) != 0)
throw pgf_error("An attempt to linearize an expression which is not type correct");
return (textcmp(&lin->absfun->type->name, cat) == 0);
}
void PgfLinearizer::TreeLinNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
@@ -361,32 +356,36 @@ PgfLinearizer::TreeLindefNode::TreeLindefNode(PgfLinearizer *linearizer, PgfText
bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
{
/* while (rule_index < lincat->n_lindefs2) {
if (lincat == 0)
return true;
while (rule_index < lincat->n_lindefs) {
ref<PgfConcrRule> rule = lincat->rules[rule_index];
Item *item = new (rule) Item();
item->rule = rule;
size_t max_value = 1;
for (size_t i = 0; i < item->vars.size(); i++) {
if (item->vars[i] == 0)
max_value *= item->rule->vars[i].range;
max_value *= item->rule->ranges[i];
}
for (size_t value = 0; value < max_value; value++) {
Item *new_item = new (item) Item;
size_t v = value;
for (size_t i = 0; i < item->vars.size(); i++) {
if (item->vars[i] == 0) {
size_t range = item->rule->vars[i].range;
item->vars[i] = v % range;
for (size_t i = 0; i < new_item->vars.size(); i++) {
if (new_item->vars[i] == 0) {
size_t range = new_item->rule->ranges[i];
new_item->vars[i] = (v % range)+1;
v = v / range;
}
}
Item *new_item = new (item) Item;
size_t lin_idx = item->eval(new_item->rule->lin_idx);
size_t lin_idx = new_item->eval(new_item->rule->lin_idx);
items[lin_idx] = new_item;
this->value = item->eval(new_item->rule->res);
this->value = new_item->eval(new_item->rule->res);
}
delete item;
@@ -399,19 +398,19 @@ bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
return false;
}
}
*/
return true;
}
void PgfLinearizer::TreeLindefNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
bool PgfLinearizer::TreeLindefNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
{
lincat = namespace_lookup(linearizer->concr->lincats, cat);
if (lincat == 0)
throw pgf_error("Cannot find a lincat for a category");
this->items = new Item*[lincat->fields.size()]();
if (lincat != 0)
this->items = new Item*[lincat->fields.size()]();
return true;
}
void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r)
void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r)
{
linearizer->flush_pre_stack(out, literal);
out->symbol_token(literal);
@@ -425,39 +424,42 @@ void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *o
void PgfLinearizer::TreeLindefNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
{
/* if (lincat != 0) {
PgfText *field = &*lincat->fields[lindex];
if (linearizer->pre_stack == NULL)
out->begin_phrase(&lincat->name, fid, field, fun);
else {
BracketStack *bracket = new BracketStack();
bracket->next = linearizer->pre_stack->bracket_stack;
bracket->begin = true;
bracket->fid = fid;
bracket->cat = &lincat->name;
bracket->field = field;
bracket->fun = fun;
linearizer->pre_stack->bracket_stack = bracket;
}
if (lincat==0) {
linearize_arg(out, linearizer, 0, 0);
return;
}
ref<PgfSequence> seq = lincat->seqs[(rule_index-1)*lincat->fields.size() + lindex];
// linearize_seq(out, linearizer, seq);
PgfText *cat = &lincat->name;
PgfText *field = &*lincat->fields[lindex];
if (linearizer->pre_stack == NULL)
out->end_phrase(&lincat->name, fid, field, fun);
else {
BracketStack *bracket = new BracketStack();
bracket->next = linearizer->pre_stack->bracket_stack;
bracket->begin = false;
bracket->fid = fid;
bracket->cat = &lincat->name;
bracket->field = field;
bracket->fun = fun;
linearizer->pre_stack->bracket_stack = bracket;
}
} else {
linearize_arg(out, linearizer, 0, NULL);
}*/
if (linearizer->pre_stack == NULL)
out->begin_phrase(cat, fid, field, linearizer->wild);
else {
BracketStack *bracket = new BracketStack();
bracket->next = linearizer->pre_stack->bracket_stack;
bracket->begin = true;
bracket->fid = fid;
bracket->cat = cat;
bracket->field = field;
bracket->fun = linearizer->wild;
linearizer->pre_stack->bracket_stack = bracket;
}
linearize_item(out, linearizer,
items[lindex],items[lindex]->rule->syms.as_vector());
if (linearizer->pre_stack == NULL)
out->end_phrase(cat, fid, field, linearizer->wild);
else {
BracketStack *bracket = new BracketStack();
bracket->next = linearizer->pre_stack->bracket_stack;
bracket->begin = false;
bracket->fid = fid;
bracket->cat = cat;
bracket->field = field;
bracket->fun = linearizer->wild;
linearizer->pre_stack->bracket_stack = bracket;
}
}
ref<PgfConcrLincat> PgfLinearizer::TreeLindefNode::get_lincat(PgfLinearizer *linearizer)
@@ -562,10 +564,9 @@ PgfLinearizer::TreeLitNode::TreeLitNode(PgfLinearizer *linearizer, ref<PgfConcrL
this->literal = lit;
}
void PgfLinearizer::TreeLitNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
bool PgfLinearizer::TreeLitNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
{
if (textcmp(&lincat->name, cat) != 0)
throw pgf_error("An attempt to linearize an expression which is not type correct");
return (textcmp(&lincat->name, cat) == 0);
}
void PgfLinearizer::TreeLitNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
@@ -599,6 +600,7 @@ PgfLinearizer::PgfLinearizer(PgfPrintContext *ctxt, ref<PgfConcr> concr, PgfMars
this->args = NULL;
this->capit = CAPIT_NONE;
this->pre_stack = NULL;
this->type_error = false;
this->wild = (PgfText*) malloc(sizeof(PgfText)+2);
this->wild->size = 1;
this->wild->text[0] = '_';
@@ -638,6 +640,10 @@ PgfLinearizer::~PgfLinearizer()
bool PgfLinearizer::resolve()
{
if (type_error) {
throw pgf_error("An attempt to linearize an expression which is not type correct");
}
for (;;) {
if (!prev || prev->resolve(this)) {
if (next == NULL)
@@ -768,9 +774,19 @@ PgfExpr PgfLinearizer::emeta(PgfMetaId meta)
PgfExpr PgfLinearizer::efun(PgfText *name)
{
ref<PgfConcrLin> lin = namespace_lookup(concr->lins, name);
if (lin != 0)
if (lin != 0) {
TreeNode *node = args;
size_t i = 0;
vector<PgfHypo> hypos = lin->absfun->type->hypos;
while (node != NULL) {
if (!node->check_category(this, &hypos[i].type->name)) {
type_error = true;
}
node = node->next_arg; i++;
}
return (PgfExpr) new TreeLinNode(this, lin);
else {
} else {
printer.puts("[");
printer.efun(name);
printer.puts("]");
+8 -7
View File
@@ -82,7 +82,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
TreeNode(PgfLinearizer *linearizer);
virtual bool resolve(PgfLinearizer *linearizer) { return true; };
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat)=0;
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat)=0;
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
virtual void linearize_var(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
virtual void linearize_item(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, Item *item, vector<PgfSymbol> syms);
@@ -98,7 +98,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
TreeLinNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin);
virtual bool resolve(PgfLinearizer *linearizer);
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
virtual ~TreeLinNode();
@@ -113,8 +113,8 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
TreeLindefNode(PgfLinearizer *linearizer, PgfText *fun, PgfText *lit);
virtual bool resolve(PgfLinearizer *linearizer);
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r);
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
~TreeLindefNode();
@@ -126,7 +126,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
TreeLinrefNode(PgfLinearizer *linearizer, TreeNode *root);
virtual bool resolve(PgfLinearizer *linearizer);
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat) {};
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat) { return true; };
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
~TreeLinrefNode();
@@ -137,7 +137,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
PgfText *literal;
TreeLitNode(PgfLinearizer *linearizer, ref<PgfConcrLincat> lincat, PgfText *lit);
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
~TreeLitNode() { free(literal); };
@@ -146,7 +146,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
struct TreeChunksNode : public TreeNode {
TreeChunksNode(PgfLinearizer *linearizer);
virtual bool resolve(PgfLinearizer *linearizer);
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
};
@@ -183,6 +183,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
PreStack *pre_stack;
void flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token);
bool type_error;
PgfText *wild;
public: