X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fexpr-evl.c;h=3c7433753197d08caf4a7801da771409cbfa1cb7;hb=3e66793381d0eaee26bd980c9a5479129fa44386;hp=0699e86b0b4c1d03a3260f37626f72eb661296ab;hpb=7b98b3a4f58f6dc5a8e9cbc188b627966d5e652d;p=pspp-builds.git diff --git a/src/expr-evl.c b/src/expr-evl.c index 0699e86b..3c743375 100644 --- a/src/expr-evl.c +++ b/src/expr-evl.c @@ -33,33 +33,26 @@ #include #include "expr.h" #include "exprP.h" -#include +#include "error.h" #include #include #include -#include "approx.h" #include "data-in.h" #include "error.h" #include "julcal/julcal.h" #include "magic.h" +#include "misc.h" +#include "moments.h" #include "pool.h" #include "random.h" -#include "stats.h" #include "str.h" #include "var.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. */ - double -expr_evaluate (struct expression *e, struct ccase *c, union value *v) +expr_evaluate (const struct expression *e, const struct ccase *c, int case_num, + union value *v) { unsigned char *op = e->op; double *dbl = e->num; @@ -76,61 +69,56 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) { switch (*op++) { - case OP_PLUS: - sp -= *op - 1; - if (sp->f != SYSMIS) - for (i = 1; i < *op; i++) - { - if (sp[i].f == SYSMIS) - { - sp->f = SYSMIS; - break; - } - else - sp->f += sp[i].f; - } - op++; + case OP_ADD: + sp--; + if (sp[1].f == SYSMIS) + sp[0].f = SYSMIS; + else if (sp[0].f != SYSMIS) + sp[0].f += sp[1].f; + break; + case OP_SUB: + sp--; + if (sp[1].f == SYSMIS) + sp[0].f = SYSMIS; + else if (sp[0].f != SYSMIS) + sp[0].f -= sp[1].f; break; case OP_MUL: - sp -= *op - 1; - if (sp->f != SYSMIS) - for (i = 1; i < *op; i++) - { - if (sp[i].f == SYSMIS) - { - sp->f = SYSMIS; - break; - } - else - sp->f *= sp[i].f; - } - op++; + sp--; + if (sp[1].f == SYSMIS) + sp[0].f = SYSMIS; + else if (sp[0].f != SYSMIS) + sp[0].f *= sp[1].f; + break; + case OP_DIV: + sp--; + if (sp[1].f == SYSMIS || sp[1].f == 0.) + sp[0].f = SYSMIS; + else if (sp[0].f != SYSMIS) + sp[0].f /= sp[1].f; break; case OP_POW: 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) { if (sp[0].f == 0.0) - /* SYSMIS**0 */ sp->f = 0.0; 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): @@ -201,7 +189,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: @@ -211,7 +199,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: @@ -221,7 +209,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: @@ -231,7 +219,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: @@ -241,7 +229,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: @@ -251,37 +239,37 @@ 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; /* String operators. */ - case OP_STRING_EQ: + case OP_EQ_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) == 0; break; - case OP_STRING_GE: + case OP_GE_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) >= 0; break; - case OP_STRING_GT: + case OP_GT_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) > 0; break; - case OP_STRING_LE: + case OP_LE_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) <= 0; break; - case OP_STRING_LT: + case OP_LT_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) < 0; break; - case OP_STRING_NE: + case OP_NE_STRING: sp--; sp[0].f = st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[1].c[1], sp[1].c[0]) != 0; @@ -344,7 +332,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) if (sp->f != SYSMIS) { errno = 0; - sp->f = log10 (sp->f); + sp->f = log (sp->f); if (errno) sp->f = SYSMIS; } @@ -403,8 +391,8 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp -= n_args - 1; if (sp->f == SYSMIS) break; - for (i = 1; i <= n_args; i++) - if (approx_eq (sp[0].f, sp[i].f)) + for (i = 1; i < n_args; i++) + if (sp[0].f == sp[i].f) { sp->f = 1.0; goto main_loop; @@ -417,37 +405,34 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) case OP_ANY_STRING: { int n_args = *op++; + int result = 0.0; sp -= n_args - 1; - for (i = 1; i <= n_args; i++) + for (i = 1; i < n_args; i++) if (!st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[i].c[1], sp[i].c[0])) { - sp->f = 1.0; - goto main_loop; + result = 1.0; + break; } - sp->f = 0.0; + sp->f = result; } break; case OP_CFVAR: { int n_args = *op++; - int nv = 0; - double sum[2] = - {0.0, 0.0}; + double weight, mean, variance; sp -= n_args - 1; - for (i = 0; i < n_args; i++) - if (sp[i].f != SYSMIS) - { - nv++; - sum[0] += sp[i].f; - sum[1] += sp[i].f * sp[i].f; - } - if (nv < *op++) + + moments_of_values (sp, n_args, + &weight, &mean, &variance, NULL, NULL); + + if (weight < *op++ || mean == SYSMIS + || mean == 0 || variance == SYSMIS) sp->f = SYSMIS; else - sp->f = calc_cfvar (sum, nv); + sp->f = sqrt (variance) / mean; } break; case OP_MAX: @@ -470,24 +455,29 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f = max; } break; + case OP_MAX_STRING: + { + int n_args = *op++; + int max_idx = 0; + + sp -= n_args - 1; + for (i = 1; i < n_args; i++) + if (st_compare_pad (&sp[i].c[1], sp[i].c[0], + &sp[max_idx].c[1], sp[max_idx].c[0]) > 0) + max_idx = i; + sp[0].c = sp[max_idx].c; + } + break; case OP_MEAN: { int n_args = *op++; - int nv = 0; - double sum[1] = - {0.0}; + double weight, mean; sp -= n_args - 1; - for (i = 0; i < n_args; i++) - if (sp[i].f != SYSMIS) - { - nv++; - sum[0] += sp[i].f; - } - if (nv < *op++) - sp->f = SYSMIS; - else - sp->f = calc_mean (sum, nv); + + moments_of_values (sp, n_args, + &weight, &mean, NULL, NULL, NULL); + sp->f = weight < *op++ ? SYSMIS : mean; } break; case OP_MIN: @@ -510,6 +500,19 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f = min; } break; + case OP_MIN_STRING: + { + int n_args = *op++; + int min_idx = 0; + + sp -= n_args - 1; + for (i = 1; i < n_args; i++) + if (st_compare_pad (&sp[i].c[1], sp[i].c[0], + &sp[min_idx].c[1], sp[min_idx].c[0]) < 0) + min_idx = i; + sp[0].c = sp[min_idx].c; + } + break; case OP_NMISS: { int n_args = *op++; @@ -542,11 +545,10 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp -= n_args - 1; if (sp->f == SYSMIS) break; - for (i = 1; i <= n_args; i += 2) + 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; @@ -561,7 +563,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) int n_args = *op++; sp -= n_args - 1; - for (i = 1; i <= n_args; i += 2) + for (i = 1; i < n_args; i += 2) if (st_compare_pad (&sp[0].c[1], sp[0].c[0], &sp[i].c[1], sp[i].c[0]) >= 0 && st_compare_pad (&sp[0].c[1], sp[0].c[0], @@ -576,23 +578,12 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) case OP_SD: { int n_args = *op++; - int nv = 0; - double sum[2]; - - sum[0] = sum[1] = 0.0; + double weight, variance; sp -= n_args - 1; - for (i = 0; i < n_args; i++) - if (sp[i].f != SYSMIS) - { - nv++; - sum[0] += sp[i].f; - sum[1] += sp[i].f * sp[i].f; - } - if (nv < *op++) - sp->f = SYSMIS; - else - sp->f = calc_stddev (calc_variance (sum, nv)); + moments_of_values (sp, n_args, + &weight, NULL, &variance, NULL, NULL); + sp->f = weight < *op++ ? SYSMIS : sqrt (variance); } break; case OP_SUM: @@ -617,34 +608,54 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) case OP_VARIANCE: { int n_args = *op++; - int nv = 0; - double sum[2]; - - sum[0] = sum[1] = 0.0; + double weight, variance; sp -= n_args - 1; - for (i = 0; i < n_args; i++) - if (sp[i].f != SYSMIS) - { - nv++; - sum[0] += sp[i].f; - sum[1] += sp[i].f * sp[i].f; - } - if (nv < *op++) - sp->f = SYSMIS; - else - sp->f = calc_variance (sum, nv); + moments_of_values (sp, n_args, + &weight, NULL, &variance, NULL, NULL); + sp->f = weight < *op++ ? SYSMIS : variance; } break; /* Time construction function. */ - case OP_TIME_HMS: - sp -= 2; - if (sp[0].f == SYSMIS || sp[1].f == SYSMIS || sp[2].f == SYSMIS) - sp->f = SYSMIS; - else - sp->f = 60. * (60. * sp[0].f + sp[1].f) + sp[2].f; + case OP_TIME_HMS: + sp -= 2; + if (sp[0].f == SYSMIS || sp[1].f == SYSMIS || sp[2].f == SYSMIS) + sp->f = SYSMIS; + else + { + double min, max; + min = min (sp[0].f, min (sp[1].f, sp[2].f)); + max = max (sp[0].f, max (sp[1].f, sp[2].f)); + if (min < 0. && max > 0.) + { + msg (SW, _("TIME.HMS cannot mix positive and negative " + "in its arguments.")); + sp->f = SYSMIS; + } + else + sp->f = 60. * (60. * sp[0].f + sp[1].f) + sp[2].f; + } + break; + case OP_CTIME_DAYS: + if (sp->f != SYSMIS) + sp->f /= 60. * 60. * 24.; break; + case OP_CTIME_HOURS: + if (sp->f != SYSMIS) + sp->f /= 60. * 60; + break; + case OP_CTIME_MINUTES: + if (sp->f != SYSMIS) + sp->f /= 60.; + break; + case OP_TIME_DAYS: + if (sp->f != SYSMIS) + sp->f *= 60. * 60. * 24.; + break; + case OP_CTIME_SECONDS: + /* No-op. */ + break; /* Date construction functions. */ case OP_DATE_DMY: @@ -678,14 +689,19 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; case OP_DATE_WKYR: sp--; - if (sp[0].f == SYSMIS) + if (sp[0].f == SYSMIS || sp[1].f == SYSMIS) sp->f = SYSMIS; - else + else if (sp[0].f < 0. || sp[0].f > 53.) + { + msg (SW, _("Week argument to WKYR must be in range 0 to 53.")); + sp->f = SYSMIS; + } + else { - sp[1].f = yrmoda (sp[1].f, 1, 1); - if (sp->f != SYSMIS) - sp[1].f = 60. * 60. * 24. * (sp[1].f + 7. * (floor (sp[0].f) - 1.)); - sp->f = sp[1].f; + double result = yrmoda (sp[1].f, 1, 1); + if (result != SYSMIS) + result = 60. * 60. * 24. * (result + 7. * (sp->f - 1.)); + sp->f = result; } break; case OP_DATE_YRDAY: @@ -802,83 +818,116 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp[0].c = dest; } break; - case OP_INDEX: + case OP_INDEX_2: sp--; if (sp[1].c[0] == 0) sp->f = SYSMIS; else { int last = sp[0].c[0] - sp[1].c[0]; + int result = 0; for (i = 0; i <= last; i++) - if (!memcmp (&sp[0].c[i + 1], &sp[0].c[1], sp[0].c[0])) + if (!memcmp (&sp[0].c[i + 1], &sp[1].c[1], sp[1].c[0])) { - sp->f = i + 1; - goto main_loop; + result = i + 1; + break; } - sp->f = 0.0; + sp->f = result; } break; - case OP_INDEX_OPT: - { - /* Length of each search string. */ - int part_len = sp[2].f; - - sp -= 2; - if (sp[1].c[0] == 0 || part_len <= 0 || sp[2].f == SYSMIS - || sp[1].c[0] % part_len != 0) - sp->f = SYSMIS; - else - { - /* Last possible index. */ - int last = sp[0].c[0] - part_len; - - for (i = 0; i <= last; i++) - for (j = 0; j < sp[1].c[0]; j += part_len) - if (!memcmp (&sp[0].c[i], &sp[1].c[j], part_len)) - { - sp->f = i + 1; - goto main_loop; - } - sp->f = 0.0; - } - } - break; - case OP_RINDEX: + case OP_INDEX_3: + sp -= 2; + if (sp[1].c[0] == 0) + { + sp->f = SYSMIS; + break; + } + else if (sp[2].f == SYSMIS) + { + msg (SW, _("Argument 3 of RINDEX may not be system-missing.")); + sp->f = SYSMIS; + } + else + { + int part_len = sp[2].f; + int result = 0; + if (part_len < 0 || part_len > sp[1].c[0] + || sp[1].c[0] % part_len != 0) + { + msg (SW, _("Argument 3 of RINDEX must be between 1 and " + "the length of argument 2, and it must " + "evenly divide the length of argument 2.")); + sp->f = SYSMIS; + break; + } + else + { + int last = sp[0].c[0] - part_len; + for (i = 0; i <= last; i++) + for (j = 0; j < sp[1].c[0]; j += part_len) + if (!memcmp (&sp[0].c[i + 1], &sp[1].c[j + 1], part_len)) + { + result = i + 1; + goto index_3_out; + } + index_3_out: + sp->f = result; + } + } + break; + case OP_RINDEX_2: sp--; if (sp[1].c[0] == 0) sp->f = SYSMIS; else { + int result = 0; for (i = sp[0].c[0] - sp[1].c[0]; i >= 0; i--) - if (!memcmp (&sp[0].c[i + 1], &sp[0].c[1], sp[0].c[0])) + if (!memcmp (&sp[0].c[i + 1], &sp[1].c[1], sp[1].c[0])) { - sp->f = i + 1; - goto main_loop; + result = i + 1; + break; } - sp->f = 0.0; + sp->f = result; } break; - case OP_RINDEX_OPT: - { - /* Length of each search string. */ - int part_len = sp[2].f; - - sp -= 2; - if (sp[1].c[0] == 0 || part_len <= 0 || sp[2].f == SYSMIS - || sp[1].c[0] % part_len != 0) - sp->f = SYSMIS; - else - { - for (i = sp[0].c[0] - part_len; i >= 0; i--) - for (j = 0; j < sp[1].c[0]; j += part_len) - if (!memcmp (&sp[0].c[i], &sp[1].c[j], part_len)) - { - sp->f = i + 1; - goto main_loop; - } - sp->f = 0.0; - } - } + case OP_RINDEX_3: + sp -= 2; + if (sp[1].c[0] == 0) + { + sp->f = SYSMIS; + break; + } + else if (sp[2].f == SYSMIS) + { + msg (SW, _("Argument 3 of RINDEX may not be system-missing.")); + sp->f = SYSMIS; + } + else + { + int part_len = sp[2].f; + int result = 0; + if (part_len < 0 || part_len > sp[1].c[0] + || sp[1].c[0] % part_len != 0) + { + msg (SW, _("Argument 3 of RINDEX must be between 1 and " + "the length of argument 2, and it must " + "evenly divide the length of argument 2.")); + sp->f = SYSMIS; + } + else + { + for (i = sp[0].c[0] - part_len; i >= 0; i--) + for (j = 0; j < sp[1].c[0]; j += part_len) + if (!memcmp (&sp[0].c[i + 1], &sp[1].c[j + 1], part_len)) + { + result = i + 1; + goto rindex_3_out; + } + rindex_3_out: + sp->f = result; + } + } break; case OP_LENGTH: sp->f = sp[0].c[0]; @@ -892,25 +941,6 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp[0].c[i] = toupper ((unsigned char) (sp[0].c[i])); break; case OP_LPAD: - { - int len; - sp--; - len = sp[1].f; - if (sp[1].f == SYSMIS || len < 0 || len > 255) - sp->c[0] = 0; - else if (len > sp[0].c[0]) - { - unsigned char *dest; - - 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]); - sp->c = dest; - } - } - break; - case OP_LPAD_OPT: { int len; sp -= 2; @@ -930,25 +960,6 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) } break; case OP_RPAD: - { - int len; - sp--; - len = sp[1].f; - if (sp[1].f == SYSMIS || len < 0 || len > 255) - sp->c[0] = 0; - else if (len > sp[0].c[0]) - { - unsigned char *dest; - - 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]); - sp->c = dest; - } - } - break; - case OP_RPAD_OPT: { int len; sp -= 2; @@ -968,20 +979,6 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) } break; case OP_LTRIM: - { - int len = sp[0].c[0]; - - i = 1; - while (i <= len && sp[0].c[i] == ' ') - i++; - if (--i) - { - sp[0].c[i] = sp[0].c[0] - i; - sp->c = &sp[0].c[i]; - } - } - break; - case OP_LTRIM_OPT: { sp--; if (sp[1].c[0] != 1) @@ -1003,50 +1000,30 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) } break; case OP_RTRIM: - assert (' ' != 0); - while (sp[0].c[sp[0].c[0]] == ' ') - sp[0].c[0]--; - break; - case OP_RTRIM_OPT: sp--; if (sp[1].c[0] != 1) sp[0].c[0] = 0; else { - /* Note that NULs are not allowed in strings. This code - needs to change if this decision is changed. */ int cmp = sp[1].c[1]; - while (sp[0].c[sp[0].c[0]] == cmp) + while (sp[0].c[0] > 0 && sp[0].c[sp[0].c[0]] == cmp) sp[0].c[0]--; } break; case OP_NUMBER: { struct data_in di; - - di.s = &sp->c[1]; - di.e = &sp->c[1] + sp->c[0]; - di.v = sp; - di.flags = DI_IGNORE_ERROR; - di.f1 = 1; - di.format.type = FMT_F; - di.format.w = sp->c[0]; - di.format.d = 0; - data_in (&di); - } - break; - case OP_NUMBER_OPT: - { - struct data_in di; + union value out; di.s = &sp->c[1]; - di.e = &sp->c[1] + sp->c[0]; - di.v = sp; - di.flags = DI_IGNORE_ERROR; + di.v = &out; + di.flags = 0; di.f1 = 1; di.format.type = *op++; di.format.w = *op++; di.format.d = *op++; + di.e = &sp->c[1] + min (sp->c[0], di.format.w); data_in (&di); + sp->f = out.f; } break; case OP_STRING: @@ -1061,11 +1038,12 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) 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; } break; - case OP_SUBSTR: + case OP_SUBSTR_2: { int index; @@ -1081,7 +1059,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) } } break; - case OP_SUBSTR_OPT: + case OP_SUBSTR_3: { int index; int n; @@ -1107,18 +1085,14 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; /* Artificial. */ - case OP_INV: - if (sp->f != SYSMIS) - sp->f = 1. / sp->f; - break; case OP_SQUARE: if (sp->f != SYSMIS) 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) { @@ -1137,7 +1111,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 @@ -1153,10 +1127,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f *= rng_get_double (pspp_rng ()); break; case OP_SYSMIS: - if (sp[0].f == SYSMIS || !finite (sp[0].f)) - sp->f = 1.0; - else - sp->f = 0.0; + sp->f = sp->f == SYSMIS || !finite (sp->f); break; case OP_VEC_ELEM_NUM: { @@ -1176,6 +1147,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp->f = SYSMIS; break; } + assert (c != NULL); sp->f = c->data[v->var[rindx - 1]->fv].f; } break; @@ -1204,6 +1176,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) v = vect->var[rindx - 1]; sp->c = pool_alloc (e->pool, v->width + 1); sp->c[0] = v->width; + assert (c != NULL); memcpy (&sp->c[1], c->data[v->fv].s, v->width); } break; @@ -1221,6 +1194,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; case OP_NUM_VAR: sp++; + assert (c != NULL); sp->f = c->data[(*vars)->fv].f; if (is_num_user_missing (sp->f, *vars)) sp->f = SYSMIS; @@ -1233,6 +1207,7 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) sp++; sp->c = pool_alloc (e->pool, width + 1); sp->c[0] = width; + assert (c != NULL); memcpy (&sp->c[1], &c->data[(*vars)->fv], width); vars++; } @@ -1272,39 +1247,30 @@ expr_evaluate (struct expression *e, struct ccase *c, union value *v) break; case OP_NUM_SYS: sp++; + assert (c != NULL); sp->f = c->data[*op++].f == SYSMIS; break; - case OP_STR_MIS: - sp++; - sp->f = is_str_user_missing (c->data[(*vars)->fv].s, *vars); - vars++; - break; case OP_NUM_VAL: sp++; + assert (c != NULL); sp->f = c->data[*op++].f; break; case OP_CASENUM: sp++; - sp->f = vfm_sink_info.ncases + 1; + sp->f = case_num; break; case OP_SENTINEL: goto finished; 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); } main_loop: ; } finished: - if (e->type != EX_STRING) + if (e->type != EXPR_STRING) { double value = sp->f; if (!finite (value))