Switched parsing to use C function stack

This commit is contained in:
Daniel Holden
2015-11-10 20:25:39 +00:00
parent 991a6e4156
commit 31889d86c3

478
mpc.c
View File

@@ -748,225 +748,6 @@ struct mpc_parser_t {
mpc_pdata_t data; mpc_pdata_t data;
}; };
/*
** Stack Type
*/
typedef struct {
int parsers_num;
int parsers_slots;
mpc_parser_t **parsers;
int *states;
int results_num;
int results_slots;
mpc_result_t *results;
int *returns;
mpc_err_t *err;
} mpc_stack_t;
enum {
MPC_STACK_MIN = 256
};
static mpc_stack_t *mpc_stack_new(const char *filename) {
mpc_stack_t *s = malloc(sizeof(mpc_stack_t));
s->parsers_num = 0;
s->parsers_slots = MPC_STACK_MIN;
s->parsers = malloc(sizeof(mpc_parser_t*) * MPC_STACK_MIN);
s->states = malloc(sizeof(int) * MPC_STACK_MIN);
s->results_num = 0;
s->results_slots = MPC_STACK_MIN;
s->results = malloc(sizeof(mpc_result_t) * MPC_STACK_MIN);
s->returns = malloc(sizeof(int) * MPC_STACK_MIN);
s->err = mpc_err_fail(filename, mpc_state_invalid(), "Unknown Error");
return s;
}
static void mpc_stack_err(mpc_stack_t *s, mpc_err_t* e) {
mpc_err_t *errs[2];
errs[0] = s->err;
errs[1] = e;
s->err = mpc_err_or(errs, 2);
}
static int mpc_stack_terminate(mpc_stack_t *s, mpc_result_t *r) {
int success = s->returns[0];
if (success) {
r->output = s->results[0].output;
mpc_err_delete(s->err);
} else {
mpc_stack_err(s, s->results[0].error);
r->error = s->err;
}
free(s->parsers);
free(s->states);
free(s->results);
free(s->returns);
free(s);
return success;
}
/* Stack Parser Stuff */
static void mpc_stack_set_state(mpc_stack_t *s, int x) {
s->states[s->parsers_num-1] = x;
}
static void mpc_stack_parsers_reserve_more(mpc_stack_t *s) {
if (s->parsers_num > s->parsers_slots) {
s->parsers_slots = s->parsers_num + s->parsers_num / 2;
s->parsers = realloc(s->parsers, sizeof(mpc_parser_t*) * s->parsers_slots);
s->states = realloc(s->states, sizeof(int) * s->parsers_slots);
}
}
static void mpc_stack_parsers_reserve_less(mpc_stack_t *s) {
if (s->parsers_slots > s->parsers_num + s->parsers_num / 2
&& s->parsers_slots > MPC_STACK_MIN) {
s->parsers_slots =
s->parsers_num > MPC_STACK_MIN ?
s->parsers_num : MPC_STACK_MIN;
s->parsers = realloc(s->parsers, sizeof(mpc_parser_t*) * s->parsers_slots);
s->states = realloc(s->states, sizeof(int) * s->parsers_slots);
}
}
static void mpc_stack_pushp(mpc_stack_t *s, mpc_parser_t *p) {
s->parsers_num++;
mpc_stack_parsers_reserve_more(s);
s->parsers[s->parsers_num-1] = p;
s->states[s->parsers_num-1] = 0;
}
static void mpc_stack_popp(mpc_stack_t *s, mpc_parser_t **p, int *st) {
*p = s->parsers[s->parsers_num-1];
*st = s->states[s->parsers_num-1];
s->parsers_num--;
mpc_stack_parsers_reserve_less(s);
}
static void mpc_stack_peepp(mpc_stack_t *s, mpc_parser_t **p, int *st) {
*p = s->parsers[s->parsers_num-1];
*st = s->states[s->parsers_num-1];
}
static int mpc_stack_empty(mpc_stack_t *s) {
return s->parsers_num == 0;
}
/* Stack Result Stuff */
static mpc_result_t mpc_result_err(mpc_err_t *e) {
mpc_result_t r;
r.error = e;
return r;
}
static mpc_result_t mpc_result_out(mpc_val_t *x) {
mpc_result_t r;
r.output = x;
return r;
}
static void mpc_stack_results_reserve_more(mpc_stack_t *s) {
if (s->results_num > s->results_slots) {
s->results_slots = s->results_num + s->results_num / 2;
s->results = realloc(s->results, sizeof(mpc_result_t) * s->results_slots);
s->returns = realloc(s->returns, sizeof(int) * s->results_slots);
}
}
static void mpc_stack_results_reserve_less(mpc_stack_t *s) {
if (s->results_slots > s->results_num + s->results_num / 2
&& s->results_slots > MPC_STACK_MIN) {
s->results_slots =
s->results_num > MPC_STACK_MIN ?
s->results_num : MPC_STACK_MIN;
s->results = realloc(s->results, sizeof(mpc_result_t) * s->results_slots);
s->returns = realloc(s->returns, sizeof(int) * s->results_slots);
}
}
static void mpc_stack_pushr(mpc_stack_t *s, mpc_result_t x, int r) {
s->results_num++;
mpc_stack_results_reserve_more(s);
s->results[s->results_num-1] = x;
s->returns[s->results_num-1] = r;
}
static int mpc_stack_popr(mpc_stack_t *s, mpc_result_t *x) {
int r;
*x = s->results[s->results_num-1];
r = s->returns[s->results_num-1];
s->results_num--;
mpc_stack_results_reserve_less(s);
return r;
}
static int mpc_stack_peekr(mpc_stack_t *s, mpc_result_t *x) {
*x = s->results[s->results_num-1];
return s->returns[s->results_num-1];
}
static void mpc_stack_popr_err(mpc_stack_t *s, int n) {
mpc_result_t x;
while (n) {
mpc_stack_popr(s, &x);
mpc_stack_err(s, x.error);
n--;
}
}
static void mpc_stack_popr_out(mpc_stack_t *s, int n, mpc_dtor_t *ds) {
mpc_result_t x;
while (n) {
mpc_stack_popr(s, &x);
ds[n-1](x.output);
n--;
}
}
static void mpc_stack_popr_out_single(mpc_stack_t *s, int n, mpc_dtor_t dx) {
mpc_result_t x;
while (n) {
mpc_stack_popr(s, &x);
dx(x.output);
n--;
}
}
static void mpc_stack_popr_n(mpc_stack_t *s, int n) {
mpc_result_t x;
while (n) {
mpc_stack_popr(s, &x);
n--;
}
}
static mpc_val_t *mpc_stack_merger_out(mpc_stack_t *s, int n, mpc_fold_t f) {
mpc_val_t *x = f(n, (mpc_val_t**)(&s->results[s->results_num-n]));
mpc_stack_popr_n(s, n);
return x;
}
static mpc_err_t *mpc_stack_merger_err(mpc_stack_t *s, int n) {
mpc_err_t *x = mpc_err_or((mpc_err_t**)(&s->results[s->results_num-n]), n);
mpc_stack_popr_n(s, n);
return x;
}
/* /*
** This is rather pleasant. The core parsing routine ** This is rather pleasant. The core parsing routine
** is written in about 200 lines of C. ** is written in about 200 lines of C.
@@ -977,51 +758,36 @@ static mpc_err_t *mpc_stack_merger_err(mpc_stack_t *s, int n) {
** Particularly nice are the `or` and `and` ** Particularly nice are the `or` and `and`
** types which have a broken but mirrored structure ** types which have a broken but mirrored structure
** with return value and error reflected. ** with return value and error reflected.
**
** When this function was written in recursive form
** it looked pretty nice. But I've since switched
** it around to an awkward while loop. It was an
** unfortunate change for code simplicity but it
** is noble in the name of performance (and
** not smashing the stack).
**
** But it is now a pretty ugly beast...
*/ */
#define MPC_CONTINUE(st, x) mpc_stack_set_state(stk, st); mpc_stack_pushp(stk, x); continue #define MPC_SUCCESS(x) r->output = x; return 1
#define MPC_SUCCESS(x) mpc_stack_popp(stk, &p, &st); mpc_stack_pushr(stk, mpc_result_out(x), 1); continue #define MPC_FAILURE(x) r->error = x; return 0
#define MPC_FAILURE(x) mpc_stack_popp(stk, &p, &st); mpc_stack_pushr(stk, mpc_result_err(x), 0); continue #define MPC_PRIMITIVE(x) \
#define MPC_PRIMITIVE(x, f) if (f) { MPC_SUCCESS(x); } else { MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Incorrect Input")); } if (x) { MPC_SUCCESS(r->output); } \
else { MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Incorrect Input")); }
int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) { enum {
MPC_PARSE_STACK_MIN = 8
};
/* Stack */ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r) {
int st = 0;
mpc_parser_t *p = NULL;
mpc_stack_t *stk = mpc_stack_new(i->filename);
/* Variables */ int j = 0, k = 0;
char *s; mpc_result_t results_stk[MPC_PARSE_STACK_MIN];
mpc_result_t r; mpc_result_t *results;
int results_slots = MPC_PARSE_STACK_MIN;
/* Go! */
mpc_stack_pushp(stk, init);
while (!mpc_stack_empty(stk)) {
mpc_stack_peepp(stk, &p, &st);
switch (p->type) { switch (p->type) {
/* Basic Parsers */ /* Basic Parsers */
case MPC_TYPE_ANY: MPC_PRIMITIVE(s, mpc_input_any(i, &s)); case MPC_TYPE_ANY: MPC_PRIMITIVE(mpc_input_any(i, (char**)&r->output));
case MPC_TYPE_SINGLE: MPC_PRIMITIVE(s, mpc_input_char(i, p->data.single.x, &s)); case MPC_TYPE_SINGLE: MPC_PRIMITIVE(mpc_input_char(i, p->data.single.x, (char**)&r->output));
case MPC_TYPE_RANGE: MPC_PRIMITIVE(s, mpc_input_range(i, p->data.range.x, p->data.range.y, &s)); case MPC_TYPE_RANGE: MPC_PRIMITIVE(mpc_input_range(i, p->data.range.x, p->data.range.y, (char**)&r->output));
case MPC_TYPE_ONEOF: MPC_PRIMITIVE(s, mpc_input_oneof(i, p->data.string.x, &s)); case MPC_TYPE_ONEOF: MPC_PRIMITIVE(mpc_input_oneof(i, p->data.string.x, (char**)&r->output));
case MPC_TYPE_NONEOF: MPC_PRIMITIVE(s, mpc_input_noneof(i, p->data.string.x, &s)); case MPC_TYPE_NONEOF: MPC_PRIMITIVE(mpc_input_noneof(i, p->data.string.x, (char**)&r->output));
case MPC_TYPE_SATISFY: MPC_PRIMITIVE(s, mpc_input_satisfy(i, p->data.satisfy.f, &s)); case MPC_TYPE_SATISFY: MPC_PRIMITIVE(mpc_input_satisfy(i, p->data.satisfy.f, (char**)&r->output));
case MPC_TYPE_STRING: MPC_PRIMITIVE(s, mpc_input_string(i, p->data.string.x, &s)); case MPC_TYPE_STRING: MPC_PRIMITIVE(mpc_input_string(i, p->data.string.x, (char**)&r->output));
/* Other parsers */ /* Other parsers */
@@ -1042,42 +808,35 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) {
/* Application Parsers */ /* Application Parsers */
case MPC_TYPE_EXPECT: case MPC_TYPE_EXPECT:
if (st == 0) { MPC_CONTINUE(1, p->data.expect.x); } if (mpc_parse_input(i, p->data.expect.x, r)) {
if (st == 1) { MPC_SUCCESS(r->output);
if (mpc_stack_popr(stk, &r)) {
MPC_SUCCESS(r.output);
} else { } else {
mpc_err_delete(r.error); mpc_err_delete(r->error);
MPC_FAILURE(mpc_err_new(i->filename, i->state, p->data.expect.m, mpc_input_peekc(i))); MPC_FAILURE(mpc_err_new(i->filename, i->state, p->data.expect.m, mpc_input_peekc(i)));
} }
}
case MPC_TYPE_APPLY: case MPC_TYPE_APPLY:
if (st == 0) { MPC_CONTINUE(1, p->data.apply.x); } if (mpc_parse_input(i, p->data.apply.x, r)) {
if (st == 1) { MPC_SUCCESS(p->data.apply.f(r->output));
if (mpc_stack_popr(stk, &r)) {
MPC_SUCCESS(p->data.apply.f(r.output));
} else { } else {
MPC_FAILURE(r.error); MPC_FAILURE(r->output);
}
} }
case MPC_TYPE_APPLY_TO: case MPC_TYPE_APPLY_TO:
if (st == 0) { MPC_CONTINUE(1, p->data.apply_to.x); } if (mpc_parse_input(i, p->data.apply_to.x, r)) {
if (st == 1) { MPC_SUCCESS(p->data.apply_to.f(r->output, p->data.apply_to.d));
if (mpc_stack_popr(stk, &r)) {
MPC_SUCCESS(p->data.apply_to.f(r.output, p->data.apply_to.d));
} else { } else {
MPC_FAILURE(r.error); MPC_FAILURE(r->error);
}
} }
case MPC_TYPE_PREDICT: case MPC_TYPE_PREDICT:
if (st == 0) { mpc_input_backtrack_disable(i); MPC_CONTINUE(1, p->data.predict.x); } mpc_input_backtrack_disable(i);
if (st == 1) { if (mpc_parse_input(i, p->data.predict.x, r)) {
mpc_input_backtrack_enable(i); mpc_input_backtrack_enable(i);
mpc_stack_popp(stk, &p, &st); MPC_SUCCESS(r->output);
continue; } else {
mpc_input_backtrack_enable(i);
MPC_FAILURE(r->error);
} }
/* Optional Parsers */ /* Optional Parsers */
@@ -1085,77 +844,81 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) {
/* TODO: Update Not Error Message */ /* TODO: Update Not Error Message */
case MPC_TYPE_NOT: case MPC_TYPE_NOT:
if (st == 0) { mpc_input_mark(i); MPC_CONTINUE(1, p->data.not.x); } mpc_input_mark(i);
if (st == 1) { if (mpc_parse_input(i, p->data.not.x, r)) {
if (mpc_stack_popr(stk, &r)) {
mpc_input_rewind(i); mpc_input_rewind(i);
p->data.not.dx(r.output); p->data.not.dx(r->output);
MPC_FAILURE(mpc_err_new(i->filename, i->state, "opposite", mpc_input_peekc(i))); MPC_FAILURE(mpc_err_new(i->filename, i->state, "opposite", mpc_input_peekc(i)));
} else { } else {
mpc_input_unmark(i); mpc_input_unmark(i);
mpc_stack_err(stk, r.error); mpc_err_delete(r->error);
MPC_SUCCESS(p->data.not.lf()); MPC_SUCCESS(p->data.not.lf());
} }
}
case MPC_TYPE_MAYBE: case MPC_TYPE_MAYBE:
if (st == 0) { MPC_CONTINUE(1, p->data.not.x); } if (mpc_parse_input(i, p->data.not.x, r)) {
if (st == 1) { MPC_SUCCESS(r->output);
if (mpc_stack_popr(stk, &r)) {
MPC_SUCCESS(r.output);
} else { } else {
mpc_stack_err(stk, r.error); mpc_err_delete(r->error);
MPC_SUCCESS(p->data.not.lf()); MPC_SUCCESS(p->data.not.lf());
} }
}
/* Repeat Parsers */ /* Repeat Parsers */
case MPC_TYPE_MANY: case MPC_TYPE_MANY:
if (st == 0) { MPC_CONTINUE(st+1, p->data.repeat.x); }
if (st > 0) { results = malloc(sizeof(mpc_result_t) * results_slots);
if (mpc_stack_peekr(stk, &r)) {
MPC_CONTINUE(st+1, p->data.repeat.x); while (mpc_parse_input(i, p->data.repeat.x, &results[j])) {
} else { j++;
mpc_stack_popr(stk, &r); if (j >= results_slots) {
mpc_stack_err(stk, r.error); results_slots = j + j / 2;
MPC_SUCCESS(mpc_stack_merger_out(stk, st-1, p->data.repeat.f)); results = realloc(results, sizeof(mpc_result_t) * results_slots);
} }
} }
mpc_err_delete(results[j].error);
MPC_SUCCESS(p->data.repeat.f(j, (mpc_val_t**)results); free(results));
case MPC_TYPE_MANY1: case MPC_TYPE_MANY1:
if (st == 0) { MPC_CONTINUE(st+1, p->data.repeat.x); }
if (st > 0) { results = malloc(sizeof(mpc_result_t) * results_slots);
if (mpc_stack_peekr(stk, &r)) {
MPC_CONTINUE(st+1, p->data.repeat.x); while (mpc_parse_input(i, p->data.repeat.x, &results[j])) {
} else { j++;
if (st == 1) { if (j >= results_slots) {
mpc_stack_popr(stk, &r); results_slots = j + j / 2;
MPC_FAILURE(mpc_err_many1(r.error)); results = realloc(results, sizeof(mpc_result_t) * results_slots);
} else {
mpc_stack_popr(stk, &r);
mpc_stack_err(stk, r.error);
MPC_SUCCESS(mpc_stack_merger_out(stk, st-1, p->data.repeat.f));
} }
} }
if (j == 0) {
MPC_FAILURE(mpc_err_many1(results[0].error); free(results));
} else {
mpc_err_delete(results[j].error);
MPC_SUCCESS(p->data.repeat.f(j, (mpc_val_t**)results); free(results));
} }
case MPC_TYPE_COUNT: case MPC_TYPE_COUNT:
if (st == 0) { mpc_input_mark(i); MPC_CONTINUE(st+1, p->data.repeat.x); }
if (st > 0) { results = p->data.repeat.n > MPC_PARSE_STACK_MIN
if (!mpc_stack_peekr(stk, &r)) { ? malloc(sizeof(mpc_result_t) * p->data.repeat.n)
mpc_stack_popr(stk, &r); : results_stk;
mpc_stack_popr_out_single(stk, st-1, p->data.repeat.dx);
mpc_input_rewind(i); while (mpc_parse_input(i, p->data.repeat.x, &results[j])) {
MPC_FAILURE(mpc_err_count(r.error, p->data.repeat.n)); j++;
} else { if (j == p->data.repeat.n) { break; }
if (st < p->data.repeat.n) {
MPC_CONTINUE(st+1, p->data.repeat.x);
} else {
mpc_input_unmark(i);
MPC_SUCCESS(mpc_stack_merger_out(stk, st, p->data.repeat.f));
} }
if (j == p->data.repeat.n) {
MPC_SUCCESS(p->data.repeat.f(j, (mpc_val_t**)results);
if (p->data.repeat.n > MPC_PARSE_STACK_MIN) { free(results); });
} else {
for (k = 0; k < j; k++) {
p->data.repeat.dx(results[k].output);
} }
MPC_FAILURE(mpc_err_count(results[j].error, p->data.repeat.n);
if (p->data.repeat.n > MPC_PARSE_STACK_MIN) { free(results); });
} }
/* Combinatory Parsers */ /* Combinatory Parsers */
@@ -1164,32 +927,46 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) {
if (p->data.or.n == 0) { MPC_SUCCESS(NULL); } if (p->data.or.n == 0) { MPC_SUCCESS(NULL); }
if (st == 0) { MPC_CONTINUE(st+1, p->data.or.xs[st]); } results = p->data.or.n > MPC_PARSE_STACK_MIN
if (st <= p->data.or.n) { ? malloc(sizeof(mpc_result_t) * p->data.or.n)
if (mpc_stack_peekr(stk, &r)) { : results_stk;
mpc_stack_popr(stk, &r);
mpc_stack_popr_err(stk, st-1); for (j = 0; j < p->data.or.n; j++) {
MPC_SUCCESS(r.output); if (mpc_parse_input(i, p->data.or.xs[j], &results[j])) {
for (k = 0; k < j; k++) {
mpc_err_delete(results[k].error);
} }
if (st < p->data.or.n) { MPC_CONTINUE(st+1, p->data.or.xs[st]); } MPC_SUCCESS(results[j].output;
if (st == p->data.or.n) { MPC_FAILURE(mpc_stack_merger_err(stk, p->data.or.n)); } if (p->data.or.n > MPC_PARSE_STACK_MIN) { free(results); });
} }
}
MPC_FAILURE(mpc_err_or((mpc_err_t**)results, j);
if (p->data.or.n > MPC_PARSE_STACK_MIN) { free(results); });
case MPC_TYPE_AND: case MPC_TYPE_AND:
if (p->data.and.n == 0) { MPC_SUCCESS(p->data.and.f(0, NULL)); } if (p->data.and.n == 0) { MPC_SUCCESS(NULL); }
if (st == 0) { mpc_input_mark(i); MPC_CONTINUE(st+1, p->data.and.xs[st]); } results = p->data.or.n > MPC_PARSE_STACK_MIN
if (st <= p->data.and.n) { ? malloc(sizeof(mpc_result_t) * p->data.or.n)
if (!mpc_stack_peekr(stk, &r)) { : results_stk;
mpc_input_mark(i);
for (j = 0; j < p->data.and.n; j++) {
if (!mpc_parse_input(i, p->data.and.xs[j], &results[j])) {
mpc_input_rewind(i); mpc_input_rewind(i);
mpc_stack_popr(stk, &r); for (k = 0; k < j; k++) {
mpc_stack_popr_out(stk, st-1, p->data.and.dxs); p->data.and.dxs[k](results[k].output);
MPC_FAILURE(r.error);
} }
if (st < p->data.and.n) { MPC_CONTINUE(st+1, p->data.and.xs[st]); } MPC_FAILURE(results[j].error;
if (st == p->data.and.n) { mpc_input_unmark(i); MPC_SUCCESS(mpc_stack_merger_out(stk, p->data.and.n, p->data.and.f)); } if (p->data.or.n > MPC_PARSE_STACK_MIN) { free(results); });
} }
}
mpc_input_unmark(i);
MPC_SUCCESS(p->data.and.f(j, (mpc_val_t**)results);
if (p->data.or.n > MPC_PARSE_STACK_MIN) { free(results); });
/* End */ /* End */
@@ -1197,13 +974,11 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) {
MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Unknown Parser Type Id!")); MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Unknown Parser Type Id!"));
} }
}
return mpc_stack_terminate(stk, final); return 0;
} }
#undef MPC_CONTINUE
#undef MPC_SUCCESS #undef MPC_SUCCESS
#undef MPC_FAILURE #undef MPC_FAILURE
#undef MPC_PRIMITIVE #undef MPC_PRIMITIVE
@@ -2011,7 +1786,7 @@ static mpc_val_t *mpcf_re_range(mpc_val_t *x) {
start = s[i-1]+1; start = s[i-1]+1;
end = s[i+1]-1; end = s[i+1]-1;
for (j = start; j <= end; j++) { for (j = start; j <= end; j++) {
range = realloc(range, strlen(range) + 1 + 1); range = realloc(range, strlen(range) + 1 + 1 + 1);
range[strlen(range) + 1] = '\0'; range[strlen(range) + 1] = '\0';
range[strlen(range) + 0] = j; range[strlen(range) + 0] = j;
} }
@@ -2230,7 +2005,7 @@ static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char
while (output[i]) { while (output[i]) {
if ((*(s+0)) == output[i][0] && if ((*(s+0)) == output[i][0] &&
(*(s+1)) == output[i][1]) { (*(s+1)) == output[i][1]) {
y = realloc(y, strlen(y) + 2); y = realloc(y, strlen(y) + 1 + 1);
buff[0] = input[i]; buff[1] = '\0'; buff[0] = input[i]; buff[1] = '\0';
strcat(y, buff); strcat(y, buff);
found = 1; found = 1;
@@ -2241,7 +2016,7 @@ static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char
} }
if (!found) { if (!found) {
y = realloc(y, strlen(y) + 2); y = realloc(y, strlen(y) + 1 + 1);
buff[0] = *s; buff[1] = '\0'; buff[0] = *s; buff[1] = '\0';
strcat(y, buff); strcat(y, buff);
} }
@@ -3363,7 +3138,6 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
int i, n, m; int i, n, m;
mpc_parser_t *t; mpc_parser_t *t;
mpc_parser_t swp;
if (p->retained && !force) { return; } if (p->retained && !force) { return; }
@@ -3428,10 +3202,11 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
&& p->data.and.xs[0]->type == MPC_TYPE_PASS && p->data.and.xs[0]->type == MPC_TYPE_PASS
&& !p->data.and.xs[0]->retained && !p->data.and.xs[0]->retained
&& p->data.and.f == mpcf_fold_ast) { && p->data.and.f == mpcf_fold_ast) {
memcpy(&swp, p->data.and.xs[1], sizeof(mpc_parser_t)); t = p->data.and.xs[1];
mpc_delete(p->data.and.xs[0]); mpc_delete(p->data.and.xs[0]);
free(p->data.and.xs); free(p->data.and.dxs); free(p->data.and.xs); free(p->data.and.dxs); free(p->name);
memcpy(p, &swp, sizeof(mpc_parser_t)); memcpy(p, t, sizeof(mpc_parser_t));
free(t);
continue; continue;
} }
@@ -3477,10 +3252,11 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
&& p->data.and.xs[0]->data.lift.lf == mpcf_ctor_str && p->data.and.xs[0]->data.lift.lf == mpcf_ctor_str
&& !p->data.and.xs[0]->retained && !p->data.and.xs[0]->retained
&& p->data.and.f == mpcf_strfold) { && p->data.and.f == mpcf_strfold) {
memcpy(&swp, p->data.and.xs[1], sizeof(mpc_parser_t)); t = p->data.and.xs[1];
mpc_delete(p->data.and.xs[0]); mpc_delete(p->data.and.xs[0]);
free(p->data.and.xs); free(p->data.and.dxs); free(p->data.and.xs); free(p->data.and.dxs); free(p->name);
memcpy(p, &swp, sizeof(mpc_parser_t)); memcpy(p, t, sizeof(mpc_parser_t));
free(t);
continue; continue;
} }