X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fexpr-opt.c;h=4c8fc7e12c87a44f7c777b5e05eb8dc2149bd1b0;hb=8438b8372d8c988b379fada8a882a84bbb894126;hp=8724b9e017ec58482d7fba2c466e29fb5034581a;hpb=cb4033020c8a24d573814e6ac9192046bffdccac;p=pspp-builds.git diff --git a/src/expr-opt.c b/src/expr-opt.c index 8724b9e0..4c8fc7e1 100644 --- a/src/expr-opt.c +++ b/src/expr-opt.c @@ -18,19 +18,19 @@ 02111-1307, USA. */ #include +#include "expr.h" +#include "exprP.h" #include #include #include #include #include #include "alloc.h" -#include "approx.h" #include "data-in.h" #include "error.h" -#include "expr.h" -#include "exprP.h" #include "julcal/julcal.h" #include "misc.h" +#include "pool.h" #include "stats.h" #include "str.h" #include "var.h" @@ -145,7 +145,7 @@ optimize_tree (struct nonterm_node * n) int nvar = 0; /* New node. */ - struct nonterm_node *m; + struct nonterm_node *m = NULL; /* Argument copying counter. */ int c; @@ -171,7 +171,7 @@ optimize_tree (struct nonterm_node * n) /* 0*SYSMIS=0, 0/SYSMIS=0; otherwise, SYSMIS and infinities produce SYSMIS. */ - if (approx_eq (cval, 0.0) && n->type == OP_MUL) + if (cval == 0.0 && n->type == OP_MUL) nvar = 0; else if (sysmis || !finite (cval)) { @@ -197,7 +197,7 @@ optimize_tree (struct nonterm_node * n) { /* Otherwise consolidate all the nonconstant terms. */ m = xmalloc (sizeof (struct nonterm_node) - + ((nvar + approx_ne (cval, def) - 1) + + ((nvar + (cval != def) - 1) * sizeof (union any_node *))); for (i = c = 0; i < n->n; i++) if (n->arg[i]->type != OP_NUM_CON) @@ -205,7 +205,7 @@ optimize_tree (struct nonterm_node * n) else free_node (n->arg[i]); - if (approx_ne (cval, def)) + if (cval != def) { m->arg[c] = xmalloc (sizeof (struct num_con_node)); m->arg[c]->num_con.type = OP_NUM_CON; @@ -223,7 +223,7 @@ optimize_tree (struct nonterm_node * n) { if (n->arg[1]->type == OP_NUM_CON) { - if (approx_eq (n1, 1.0)) + if (n1 == 1.0) { struct nonterm_node *m = (struct nonterm_node *) n->arg[0]; @@ -231,7 +231,7 @@ optimize_tree (struct nonterm_node * n) free (n); return m; } - else if (approx_eq (n1, 2.0)) + else if (n1 == 2.0) { n = xrealloc (n, sizeof (struct nonterm_node)); n->type = OP_SQUARE; @@ -285,7 +285,7 @@ evaluate_tree (struct nonterm_node * n) return optimize_tree (n); case OP_POW: - if (approx_eq (n0, 0.0) && approx_eq (n1, 0.0)) + if (n0 == 0.0 && n1 == 0.0) frnc (SYSMIS); else if (n0 == SYSMIS && n1 == 0.0) frnc (1.0); @@ -316,22 +316,22 @@ evaluate_tree (struct nonterm_node * n) break; case OP_EQ: - rnc (approx_eq (n0, n1)); + rnc (n0 == n1); break; case OP_GE: - rnc (approx_ge (n0, n1)); + rnc (n0 >= n1); break; case OP_GT: - rnc (approx_gt (n0, n1)); + rnc (n0 > n1); break; case OP_LE: - rnc (approx_le (n0, n1)); + rnc (n0 <= n1); break; case OP_LT: - rnc (approx_lt (n0, n1)); + rnc (n0 < n1); break; case OP_NE: - rnc (approx_ne (n0, n1)); + rnc (n0 != n1); break; /* String operators. */ @@ -413,7 +413,7 @@ evaluate_tree (struct nonterm_node * n) for (i = 1; i < n->n; i++) { ni = n->arg[i]->num_con.value; - if (approx_eq (n0, ni)) + if (n0 == ni) { frnc (1.0); goto any_done; @@ -518,7 +518,7 @@ evaluate_tree (struct nonterm_node * n) if (min == SYSMIS || max == SYSMIS) continue; sysmis = 0; - if (approx_ge (n0, min) && approx_le (n0, max)) + if (n0 >= min && n0 <= max) { frnc (1.0); goto range_done; @@ -768,7 +768,7 @@ evaluate_tree (struct nonterm_node * n) case OP_RTRIM: case OP_RTRIM_OPT: { - int c; + int c = ' '; char *cp = s0; if (n->type == OP_LTRIM_OPT || n->type == OP_RTRIM_OPT) @@ -778,7 +778,6 @@ evaluate_tree (struct nonterm_node * n) c = n->type == OP_LTRIM_OPT ? 'L' : 'R'; msg (SE, _("Second argument to %cTRIM() must be at least one " "character in length."), c); - c = ' '; } else c = s1[0]; @@ -834,6 +833,7 @@ evaluate_tree (struct nonterm_node * n) f.d = (int) n->arg[3]; v.f = n0; + assert ((formats[f.type].cat & FCAT_STRING) == 0); data_out (strbuf, &f, &v); n = repl_str_con (n, strbuf, f.w); } @@ -865,15 +865,15 @@ evaluate_tree (struct nonterm_node * n) rnc (1.0 / n0); break; case OP_MOD: - if (approx_eq (n0, 0.0) && n1 == SYSMIS) + if (n0 == 0.0 && n1 == SYSMIS) frnc (0.0); else rnc (fmod (n0, n1)); break; case OP_NUM_TO_BOOL: - if (approx_eq (n0, 0.0)) + if (n0 == 0.0) n0 = 0.0; - else if (approx_eq (n0, 1.0)) + else if (n0 == 1.0) n0 = 1.0; else if (n0 != SYSMIS) { @@ -976,41 +976,43 @@ yrmoda (double year, double month, double day) /* Expression dumper. */ -static struct expression *e; -static int nop, mop; -static int ndbl, mdbl; -static int nstr, mstr; -static int nvars, mvars; - -static void dump_node (union any_node * n); -static void emit (int); -static void emit_num_con (double); -static void emit_str_con (char *, int); -static void emit_var (struct variable *); +struct expr_dump_state + { + struct expression *expr; /* Output expression. */ + int op_cnt, op_cap; /* Number of ops, allocated space. */ + int dbl_cnt, dbl_cap; /* Number of doubles, allocated space. */ + int str_cnt, str_cap; /* Number of strings, allocated space. */ + int var_cnt, var_cap; /* Number of variables, allocated space. */ + }; + +static void dump_node (struct expr_dump_state *, union any_node * n); +static void emit (struct expr_dump_state *, int); +static void emit_num_con (struct expr_dump_state *, double); +static void emit_str_con (struct expr_dump_state *, char *, int); +static void emit_var (struct expr_dump_state *, struct variable *); void dump_expression (union any_node * n, struct expression * expr) { + struct expr_dump_state eds; unsigned char *o; - int height = 0; - int max_height = 0; - e = expr; - e->op = NULL; - e->num = NULL; - e->str = NULL; - e->var = NULL; - nop = mop = 0; - ndbl = mdbl = 0; - nstr = mstr = 0; - nvars = mvars = 0; - dump_node (n); - emit (OP_SENTINEL); + expr->op = NULL; + expr->num = NULL; + expr->str = NULL; + expr->var = NULL; + eds.expr = expr; + eds.op_cnt = eds.op_cap = 0; + eds.dbl_cnt = eds.dbl_cap = 0; + eds.str_cnt = eds.str_cap = 0; + eds.var_cnt = eds.var_cap = 0; + dump_node (&eds, n); + emit (&eds, OP_SENTINEL); /* Now compute the stack height needed to evaluate the expression. */ - for (o = e->op; *o != OP_SENTINEL; o++) + for (o = expr->op; *o != OP_SENTINEL; o++) { if (ops[*o].flags & OP_VAR_ARGS) height += 1 - o[1]; @@ -1021,33 +1023,27 @@ dump_expression (union any_node * n, struct expression * expr) max_height = height; } - /* ANSI says we have to waste space for one `value' since pointers - are not guaranteed to be able to point to a spot *before* a - block. If only all the world were a VAX... */ + /* We waste space for one `value' since pointers are not + guaranteed to be able to point to a spot before a block. */ max_height++; - e->stack = xmalloc (max_height * sizeof *e->stack); + expr->stack = xmalloc (max_height * sizeof *expr->stack); -#if PAGED_STACK - e->str_stack = e->type == EX_STRING ? xmalloc (256) : NULL; -#else - e->str_stack = xmalloc (256); - e->str_size = 256; -#endif + expr->pool = pool_create (); } static void -dump_node (union any_node * n) +dump_node (struct expr_dump_state *eds, union any_node * n) { if (n->type == OP_AND || n->type == OP_OR) { int i; - dump_node (n->nonterm.arg[0]); + dump_node (eds, n->nonterm.arg[0]); for (i = 1; i < n->nonterm.n; i++) { - dump_node (n->nonterm.arg[i]); - emit (n->type); + dump_node (eds, n->nonterm.arg[i]); + emit (eds, n->type); } return; } @@ -1055,82 +1051,85 @@ dump_node (union any_node * n) { int i; for (i = 0; i < n->nonterm.n; i++) - dump_node (n->nonterm.arg[i]); - emit (n->type); + dump_node (eds, n->nonterm.arg[i]); + emit (eds, n->type); if (ops[n->type].flags & OP_VAR_ARGS) - emit (n->nonterm.n); + emit (eds, n->nonterm.n); if (ops[n->type].flags & OP_MIN_ARGS) - emit ((int) n->nonterm.arg[n->nonterm.n]); + emit (eds, (int) n->nonterm.arg[n->nonterm.n]); if (ops[n->type].flags & OP_FMT_SPEC) { - emit ((int) n->nonterm.arg[n->nonterm.n]); - emit ((int) n->nonterm.arg[n->nonterm.n + 1]); - emit ((int) n->nonterm.arg[n->nonterm.n + 2]); + emit (eds, (int) n->nonterm.arg[n->nonterm.n]); + emit (eds, (int) n->nonterm.arg[n->nonterm.n + 1]); + emit (eds, (int) n->nonterm.arg[n->nonterm.n + 2]); } return; } - emit (n->type); + emit (eds, n->type); if (n->type == OP_NUM_CON) - emit_num_con (n->num_con.value); + emit_num_con (eds, n->num_con.value); else if (n->type == OP_STR_CON) - emit_str_con (n->str_con.s, n->str_con.len); + emit_str_con (eds, n->str_con.s, n->str_con.len); else if (n->type == OP_NUM_VAR || n->type == OP_STR_VAR || n->type == OP_STR_MIS) - emit_var (n->var.v); + emit_var (eds, n->var.v); else if (n->type == OP_NUM_LAG || n->type == OP_STR_LAG) { - emit_var (n->lag.v); - emit (n->lag.lag); + emit_var (eds, n->lag.v); + emit (eds, n->lag.lag); } else if (n->type == OP_NUM_SYS || n->type == OP_NUM_VAL) - emit (n->var.v->fv); + emit (eds, n->var.v->fv); else assert (n->type == OP_CASENUM); } static void -emit (int op) +emit (struct expr_dump_state *eds, int op) { - if (nop >= mop) + if (eds->op_cnt >= eds->op_cap) { - mop += 16; - e->op = xrealloc (e->op, mop * sizeof *e->op); + eds->op_cap += 16; + eds->expr->op = xrealloc (eds->expr->op, + eds->op_cap * sizeof *eds->expr->op); } - e->op[nop++] = op; + eds->expr->op[eds->op_cnt++] = op; } static void -emit_num_con (double dbl) +emit_num_con (struct expr_dump_state *eds, double dbl) { - if (ndbl >= mdbl) + if (eds->dbl_cnt >= eds->dbl_cap) { - mdbl += 16; - e->num = xrealloc (e->num, mdbl * sizeof *e->num); + eds->dbl_cap += 16; + eds->expr->num = xrealloc (eds->expr->num, + eds->dbl_cap * sizeof *eds->expr->num); } - e->num[ndbl++] = dbl; + eds->expr->num[eds->dbl_cnt++] = dbl; } static void -emit_str_con (char *str, int len) +emit_str_con (struct expr_dump_state *eds, char *str, int len) { - if (nstr + len + 1 > mstr) + if (eds->str_cnt + len + 1 > eds->str_cap) { - mstr += 256; - e->str = xrealloc (e->str, mstr); + eds->str_cap += 256; + eds->expr->str = xrealloc (eds->expr->str, eds->str_cap); } - e->str[nstr++] = len; - memcpy (&e->str[nstr], str, len); - nstr += len; + eds->expr->str[eds->str_cnt++] = len; + memcpy (&eds->expr->str[eds->str_cnt], str, len); + eds->str_cnt += len; } static void -emit_var (struct variable * v) +emit_var (struct expr_dump_state *eds, struct variable * v) { - if (nvars >= mvars) + if (eds->var_cnt >= eds->var_cap) { - mvars += 16; - e->var = xrealloc (e->var, mvars * sizeof *e->var); + eds->var_cap += 16; + eds->expr->var = xrealloc (eds->expr->var, + eds->var_cap * sizeof *eds->expr->var); } - e->var[nvars++] = v; + eds->expr->var[eds->var_cnt++] = v; }