X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fexpr-evl.c;h=a1b540e4974d984f78036eb8305be6ed285c5682;hb=e22db86f67a3b77124af022bbd734922c62c424c;hp=15b4434c9bee0e3d789f56c4b1192e776ef37101;hpb=4944c86a9318bc5b5578ab145a95c116ffd2c9fd;p=pspp diff --git a/src/expr-evl.c b/src/expr-evl.c index 15b4434c9b..a1b540e497 100644 --- a/src/expr-evl.c +++ b/src/expr-evl.c @@ -17,23 +17,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* AIX requires this to be the first thing in the file. */ #include -#if __GNUC__ -#define alloca __builtin_alloca -#else -#if HAVE_ALLOCA_H -#include -#else -#ifdef _AIX -#pragma alloca -#else -#ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -#endif -#endif -#endif -#endif #if TIME_WITH_SYS_TIME #include @@ -47,81 +31,39 @@ char *alloca (); #endif #include +#include "expr.h" +#include "exprP.h" #include #include #include #include -#include "approx.h" #include "data-in.h" #include "error.h" -#include "expr.h" -#include "exprP.h" #include "julcal/julcal.h" #include "magic.h" +#include "misc.h" +#include "pool.h" #include "random.h" #include "stats.h" #include "str.h" #include "var.h" -#include "vector.h" #include "vfm.h" #include "vfmP.h" -/* FIXME: This could be even more efficient if we caught SYSMIS when - it first reared its ugly head, then threw it into an entirely new - switch that handled SYSMIS aggressively like all the code does now. - But I've spent a couple of weeks on the expression code, and that's - enough to make anyone sick. For that matter, it could be more - efficient if I hand-coded it in assembly for a dozen processors, - but I'm not going to do that either. */ - -/* These macros are defined differently depending on the way that - the stack is managed. (i.e., I have to adapt the code to inferior - environments.) - - void CHECK_STRING_SPACE(int x): Assure that at least X+1 bytes of - space are available in the string evaluation stack. - - unsigned char *ALLOC_STRING_SPACE(int x): Return a pointer to X+1 - bytes of space. CHECK_STRING_SPACE must have previously been - called with an argument of at least X. */ - -#if PAGED_STACK -#define CHECK_STRING_SPACE(X) /* nothing to do! */ -#define ALLOC_STRING_SPACE(X) \ - alloca((X) + 1) -#else /* !PAGED_STACK */ -#define CHECK_STRING_SPACE(X) \ - do \ - { \ - if (str_stk + X >= str_end) \ - { \ - e->str_size += 1024; \ - e->str_stk = xrealloc (e->str_stk, e->str_size); \ - str_end = e->str_stk + e->str_size - 1; \ - } \ - } \ - while (0) - -#define ALLOC_STRING_SPACE(X) \ - (str_stk += X + 1, str_stk - X - 1) -#endif /* !PAGED_STACK */ - double expr_evaluate (struct expression *e, struct ccase *c, union value *v) { unsigned char *op = e->op; double *dbl = e->num; unsigned char *str = e->str; -#if !PAGED_STACK - unsigned char *str_stk = e->str_stk; - unsigned char *str_end = e->str_stk + e->str_size - 1; -#endif struct variable **vars = e->var; int i, j; /* Stack pointer. */ union value *sp = e->stack; + pool_clear (e->pool); + for (;;) { switch (*op++) @@ -160,7 +102,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp--; if (sp[0].f == SYSMIS) { - if (approx_eq (sp[1].f, 0.0)) + if (sp[1].f == 0.0) sp->f = 1.0; } else if (sp[1].f == SYSMIS) @@ -171,16 +113,14 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) else sp->f = SYSMIS; } - else if (approx_eq (sp[0].f, 0.0) && approx_eq (sp[1].f, 0.0)) + else if (sp[0].f == 0.0 && sp[1].f == 0.0) sp->f = SYSMIS; else sp->f = pow (sp[0].f, sp[1].f); break; case OP_AND: - /* Note that the equality operator (==) may be used here - (instead of approx_eq) because booleans are always - *exactly* 0, 1, or SYSMIS. + /* Note that booleans are always one of 0, 1, or SYSMIS. Truth table (in order of detection): @@ -251,7 +191,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_eq (sp[0].f, sp[1].f); + sp->f = sp[0].f == sp[1].f; } break; case OP_GE: @@ -261,7 +201,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_ge (sp[0].f, sp[1].f); + sp->f = sp[0].f >= sp[1].f; } break; case OP_GT: @@ -271,7 +211,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_gt (sp[0].f, sp[1].f); + sp->f = sp[0].f > sp[1].f; } break; case OP_LE: @@ -281,7 +221,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_le (sp[0].f, sp[1].f); + sp->f = sp[0].f <= sp[1].f; } break; case OP_LT: @@ -291,7 +231,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_lt (sp[0].f, sp[1].f); + sp->f = sp[0].f < sp[1].f; } break; case OP_NE: @@ -301,7 +241,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp[1].f == SYSMIS) sp->f = SYSMIS; else - sp->f = approx_ne (sp[0].f, sp[1].f); + sp->f = sp[0].f != sp[1].f; } break; @@ -454,7 +394,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp->f == SYSMIS) break; for (i = 1; i <= n_args; i++) - if (approx_eq (sp[0].f, sp[i].f)) + if (sp[0].f == sp[i].f) { sp->f = 1.0; goto main_loop; @@ -595,8 +535,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) for (i = 1; i <= n_args; i += 2) if (sp[i].f == SYSMIS || sp[i + 1].f == SYSMIS) continue; - else if (approx_ge (sp[0].f, sp[i].f) - && approx_le (sp[0].f, sp[i + 1].f)) + else if (sp[0].f >= sp[i].f && sp[0].f <= sp[i + 1].f) { sp->f = 1.0; goto main_loop; @@ -710,7 +649,8 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f *= 60. * 60. * 24.; break; case OP_DATE_MOYR: - (--sp)->f = yrmoda (sp[1].f, sp[0].f, 1); + sp--; + sp->f = yrmoda (sp[1].f, sp[0].f, 1); if (sp->f != SYSMIS) sp->f *= 60. * 60. * 24.; break; @@ -829,8 +769,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) int n_args = *op++; unsigned char *dest; - CHECK_STRING_SPACE (255); - dest = ALLOC_STRING_SPACE (255); + dest = pool_alloc (e->pool, 256); dest[0] = 0; sp -= n_args - 1; @@ -952,8 +891,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { unsigned char *dest; - CHECK_STRING_SPACE (len); - dest = ALLOC_STRING_SPACE (len); + dest = pool_alloc (e->pool, len + 1); dest[0] = len; memset (&dest[1], ' ', len - sp->c[0]); memcpy (&dest[len - sp->c[0] + 1], &sp->c[1], sp->c[0]); @@ -972,8 +910,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { unsigned char *dest; - CHECK_STRING_SPACE (len); - dest = ALLOC_STRING_SPACE (len); + dest = pool_alloc (e->pool, len + 1); dest[0] = len; memset (&dest[1], sp[2].c[1], len - sp->c[0]); memcpy (&dest[len - sp->c[0] + 1], &sp->c[1], sp->c[0]); @@ -992,8 +929,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { unsigned char *dest; - CHECK_STRING_SPACE (len); - dest = ALLOC_STRING_SPACE (len); + dest = pool_alloc (e->pool, len + 1); dest[0] = len; memcpy (&dest[1], &sp->c[1], sp->c[0]); memset (&dest[sp->c[0] + 1], ' ', len - sp->c[0]); @@ -1012,8 +948,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { unsigned char *dest; - CHECK_STRING_SPACE (len); - dest = ALLOC_STRING_SPACE (len); + dest = pool_alloc (e->pool, len + 1); dest[0] = len; memcpy (&dest[1], &sp->c[1], sp->c[0]); memset (&dest[sp->c[0] + 1], sp[2].c[1], len - sp->c[0]); @@ -1112,10 +1047,10 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) f.w = *op++; f.d = *op++; - CHECK_STRING_SPACE (f.w); - dest = ALLOC_STRING_SPACE (f.w); + dest = pool_alloc (e->pool, f.w + 1); dest[0] = f.w; + assert ((formats[f.type].cat & FCAT_STRING) == 0); data_out (&dest[1], &f, sp); sp->c = dest; } @@ -1171,9 +1106,9 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f *= sp->f; break; case OP_NUM_TO_BOOL: - if (approx_eq (sp->f, 0.0)) + if (sp->f == 0.0) sp->f = 0.0; - else if (approx_eq (sp->f, 1.0)) + else if (sp->f == 1.0) sp->f = 1.0; else if (sp->f != SYSMIS) { @@ -1192,7 +1127,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { if (sp[1].f == SYSMIS) { - if (approx_ne (sp[0].f, 0.0)) + if (sp[0].f != 0.0) sp->f = SYSMIS; } else @@ -1201,11 +1136,11 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; case OP_NORMAL: if (sp->f != SYSMIS) - sp->f = rand_normal (sp->f); + sp->f *= rng_get_double_normal (pspp_rng ()); break; case OP_UNIFORM: if (sp->f != SYSMIS) - sp->f = rand_uniform (sp->f); + sp->f *= rng_get_double (pspp_rng ()); break; case OP_SYSMIS: if (sp[0].f == SYSMIS || !finite (sp[0].f)) @@ -1216,9 +1151,9 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) case OP_VEC_ELEM_NUM: { int rindx = sp[0].f + EPSILON; - struct vector *v = &vec[*op++]; + const struct vector *v = dict_get_vector (default_dict, *op++); - if (sp[0].f == SYSMIS || rindx < 1 || rindx > v->nv) + if (sp[0].f == SYSMIS || rindx < 1 || rindx > v->cnt) { if (sp[0].f == SYSMIS) msg (SE, _("SYSMIS is not a valid index value for vector " @@ -1231,16 +1166,16 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f = SYSMIS; break; } - sp->f = c->data[v->v[rindx - 1]->fv].f; + sp->f = c->data[v->var[rindx - 1]->fv].f; } break; case OP_VEC_ELEM_STR: { int rindx = sp[0].f + EPSILON; - struct vector *vect = &vec[*op++]; + const struct vector *vect = dict_get_vector (default_dict, *op++); struct variable *v; - if (sp[0].f == SYSMIS || rindx < 1 || rindx > vect->nv) + if (sp[0].f == SYSMIS || rindx < 1 || rindx > vect->cnt) { if (sp[0].f == SYSMIS) msg (SE, _("SYSMIS is not a valid index value for vector " @@ -1251,15 +1186,13 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) msg (SE, _("%g is not a valid index value for vector %s. " "The result will be set to the empty string."), sp[0].f, vect->name); - CHECK_STRING_SPACE (0); - sp->c = ALLOC_STRING_SPACE (0); + sp->c = pool_alloc (e->pool, 1); sp->c[0] = 0; break; } - v = vect->v[rindx - 1]; - CHECK_STRING_SPACE (v->width); - sp->c = ALLOC_STRING_SPACE (v->width); + v = vect->var[rindx - 1]; + sp->c = pool_alloc (e->pool, v->width + 1); sp->c[0] = v->width; memcpy (&sp->c[1], c->data[v->fv].s, v->width); } @@ -1272,8 +1205,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; case OP_STR_CON: sp++; - CHECK_STRING_SPACE (*str); - sp->c = ALLOC_STRING_SPACE (*str); + sp->c = pool_alloc (e->pool, *str + 1); memcpy (sp->c, str, *str + 1); str += *str + 1; break; @@ -1289,8 +1221,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) int width = (*vars)->width; sp++; - CHECK_STRING_SPACE (width); - sp->c = ALLOC_STRING_SPACE (width); + sp->c = pool_alloc (e->pool, width + 1); sp->c[0] = width; memcpy (&sp->c[1], &c->data[(*vars)->fv], width); vars++; @@ -1318,8 +1249,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) int width = (*vars)->width; sp++; - CHECK_STRING_SPACE (width); - sp->c = ALLOC_STRING_SPACE (width); + sp->c = pool_alloc (e->pool, width + 1); sp->c[0] = width; if (c == NULL) @@ -1351,19 +1281,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) case OP_SENTINEL: goto finished; -#if __CHECKER__ - /* This case prevents Checker from choking. */ - case 42000: - assert (0); -#endif - default: -#if GLOBAL_DEBUGGING - printf (_("evaluate_expression(): not implemented: %s\n"), - ops[op[-1]].name); -#else - printf (_("evaluate_expression(): not implemented: %d\n"), op[-1]); -#endif assert (0); } @@ -1383,12 +1301,7 @@ finished: { assert (v); -#if PAGED_STACK - memcpy (e->str_stack, sp->c, sp->c[0] + 1); - v->c = e->str_stack; -#else v->c = sp->c; -#endif return 0.0; }