support for Int,Float and String

This commit is contained in:
krangelov
2021-12-01 15:54:34 +01:00
parent 15c03816ea
commit 9ca68b1b4b
2 changed files with 81 additions and 69 deletions

View File

@@ -2,12 +2,13 @@
#include "printer.h" #include "printer.h"
#include "linearizer.h" #include "linearizer.h"
PgfLinearizer::TreeNode::TreeNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin) { PgfLinearizer::TreeNode::TreeNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin, PgfText *lit) {
this->next = NULL; this->next = NULL;
this->next_arg = NULL; this->next_arg = NULL;
this->args = linearizer->args; this->args = linearizer->args;
this->lin = lin; this->lin = lin;
this->literal = lit;
this->lin_index = 0; this->lin_index = 0;
this->value = 0; this->value = 0;
@@ -60,81 +61,83 @@ bool PgfLinearizer::resolve()
{ {
TreeNode *node = first; TreeNode *node = first;
while (node != NULL) { while (node != NULL) {
size_t n_args = node->lin->args->len / node->lin->res->len; if (node->literal == NULL) {
size_t n_args = node->lin->args->len / node->lin->res->len;
while (node->lin_index < node->lin->res->len) { while (node->lin_index < node->lin->res->len) {
size_t offset = node->lin_index*n_args; size_t offset = node->lin_index*n_args;
ref<PgfPResult> pres = *vector_elem(node->lin->res, node->lin_index); ref<PgfPResult> pres = *vector_elem(node->lin->res, node->lin_index);
int i = 0; int i = 0;
TreeNode *arg = node->args; TreeNode *arg = node->args;
while (arg != NULL) { while (arg != NULL) {
ref<PgfPArg> parg = vector_elem(node->lin->args, offset+i); ref<PgfPArg> parg = vector_elem(node->lin->args, offset+i);
if (arg->value < parg->param->i0) if (arg->value < parg->param->i0)
break; break;
size_t value = arg->value - parg->param->i0; size_t value = arg->value - parg->param->i0;
for (size_t j = 0; j < parg->param->n_terms; j++) { for (size_t j = 0; j < parg->param->n_terms; j++) {
size_t factor = parg->param->terms[j].factor; size_t factor = parg->param->terms[j].factor;
size_t var = parg->param->terms[j].var; size_t var = parg->param->terms[j].var;
size_t var_value; size_t var_value;
if (var < node->var_count && node->var_values[var] != (size_t) -1) { if (var < node->var_count && node->var_values[var] != (size_t) -1) {
// The variable already has a value // The variable already has a value
var_value = node->var_values[var]; var_value = node->var_values[var];
} else { } else {
// The variable is not assigned yet // The variable is not assigned yet
var_value = value / factor; var_value = value / factor;
// find the range for the variable // find the range for the variable
size_t range = 0; size_t range = 0;
for (size_t k = 0; k < pres->vars->len; k++) { for (size_t k = 0; k < pres->vars->len; k++) {
ref<PgfVariableRange> var_range = vector_elem(pres->vars, k); ref<PgfVariableRange> var_range = vector_elem(pres->vars, k);
if (var_range->var == var) { if (var_range->var == var) {
range = var_range->range; range = var_range->range;
break;
}
}
if (range == 0)
throw pgf_error("Unknown variable in resolving a linearization");
if (var_value > range)
break; break;
}
}
if (range == 0)
throw pgf_error("Unknown variable in resolving a linearization");
if (var_value > range) // Assign the variable;
break; if (var >= node->var_count) {
node->var_values = (size_t*)
// Assign the variable; realloc(node->var_values, (var+1)*sizeof(size_t));
if (var >= node->var_count) { while (node->var_count < var) {
node->var_values = (size_t*) node->var_values[node->var_count++] = (size_t) -1;
realloc(node->var_values, (var+1)*sizeof(size_t)); }
while (node->var_count < var) { node->var_count++;
node->var_values[node->var_count++] = (size_t) -1;
} }
node->var_count++; node->var_values[var] = var_value;
} }
node->var_values[var] = var_value;
value -= var_value * factor;
} }
value -= var_value * factor; if (value != 0)
break;
arg = arg->next_arg;
i++;
} }
if (value != 0) node->lin_index++;
if (arg == NULL) {
node->value = node->eval_param(&pres->param);
break; break;
}
arg = arg->next_arg; // Unbind all variables
i++; for (size_t j = 0; j < node->var_count; j++) {
} node->var_values[j] = (size_t) -1;
}
node->lin_index++;
if (arg == NULL) {
node->value = node->eval_param(&pres->param);
break;
}
// Unbind all variables
for (size_t j = 0; j < node->var_count; j++) {
node->var_values[j] = (size_t) -1;
} }
} }
@@ -228,9 +231,13 @@ void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node,
void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, size_t lindex) void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, size_t lindex)
{ {
size_t n_seqs = node->lin->seqs->len / node->lin->res->len; if (node->literal == NULL) {
ref<Vector<PgfSymbol>> syms = *vector_elem(node->lin->seqs, (node->lin_index-1)*n_seqs + lindex); size_t n_seqs = node->lin->seqs->len / node->lin->res->len;
linearize(out, node, syms); ref<Vector<PgfSymbol>> syms = *vector_elem(node->lin->seqs, (node->lin_index-1)*n_seqs + lindex);
linearize(out, node, syms);
} else {
out->symbol_token(node->literal);
}
} }
PgfExpr PgfLinearizer::eabs(PgfBindType btype, PgfText *name, PgfExpr body) PgfExpr PgfLinearizer::eabs(PgfBindType btype, PgfText *name, PgfExpr body)
@@ -262,7 +269,7 @@ PgfExpr PgfLinearizer::emeta(PgfMetaId meta)
PgfExpr PgfLinearizer::efun(PgfText *name) PgfExpr PgfLinearizer::efun(PgfText *name)
{ {
ref<PgfConcrLin> lin = namespace_lookup(concr->lins, name); ref<PgfConcrLin> lin = namespace_lookup(concr->lins, name);
TreeNode *node = new TreeNode(this, lin); TreeNode *node = new TreeNode(this, lin, NULL);
return (PgfExpr) node; return (PgfExpr) node;
} }
@@ -283,17 +290,21 @@ PgfExpr PgfLinearizer::eimplarg(PgfExpr expr)
PgfLiteral PgfLinearizer::lint(size_t size, uintmax_t *v) PgfLiteral PgfLinearizer::lint(size_t size, uintmax_t *v)
{ {
return 0; PgfPrinter printer(NULL,0,NULL);
printer.lint(size,v);
return (PgfExpr) new TreeNode(this, 0, printer.get_text());
} }
PgfLiteral PgfLinearizer::lflt(double v) PgfLiteral PgfLinearizer::lflt(double v)
{ {
return 0; PgfPrinter printer(NULL,0,NULL);
printer.lflt(v);
return (PgfExpr) new TreeNode(this, 0, printer.get_text());
} }
PgfLiteral PgfLinearizer::lstr(PgfText *v) PgfLiteral PgfLinearizer::lstr(PgfText *v)
{ {
return 0; return (PgfExpr) new TreeNode(this, 0, textdup(v));
} }
PgfType PgfLinearizer::dtyp(size_t n_hypos, PgfTypeHypo *hypos, PgfType PgfLinearizer::dtyp(size_t n_hypos, PgfTypeHypo *hypos,

View File

@@ -32,15 +32,16 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
TreeNode *next_arg; TreeNode *next_arg;
TreeNode *args; TreeNode *args;
ref<PgfConcrLin> lin; PgfText *literal; // != NULL if literal
ref<PgfConcrLin> lin; // != 0 if function
size_t lin_index; size_t lin_index;
size_t value; size_t value;
size_t var_count; size_t var_count;
size_t *var_values; size_t *var_values;
TreeNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin); TreeNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin, PgfText *lit);
~TreeNode() { free(var_values); }; ~TreeNode() { free(literal); free(var_values); };
size_t eval_param(PgfLParam *param); size_t eval_param(PgfLParam *param);
}; };