From 7e19f14e15bfa96e2d29c7f3f830c1a1a6f71933 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 24 Dec 2021 13:10:34 -0800 Subject: [PATCH] tests --- src/language/expressions/evaluate.c | 44 +++++++++++++++++++++---- src/language/expressions/operations.def | 2 +- src/language/expressions/parse.c | 1 + tests/language/expressions/evaluate.at | 43 ++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index bdd21e1dbe..9c809fac4c 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -127,9 +127,10 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) struct expression *expr; + struct dictionary *d = NULL; + for (;;) { - struct dictionary *d = NULL; if (lex_match_id (lexer, "NOOPTIMIZE")) optimize = false; else if (lex_match_id (lexer, "OPTIMIZE")) @@ -141,7 +142,6 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) else if (lex_match (lexer, T_LPAREN)) { struct variable *v; - int width; if (!lex_force_id (lexer)) goto done; @@ -151,10 +151,25 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) if (!lex_force_match (lexer, T_EQUALS)) goto done; + union value value; + int width; if (lex_is_number (lexer)) - width = 0; + { + width = 0; + value.f = lex_number (lexer); + lex_get (lexer); + } + else if (lex_match_id (lexer, "SYSMIS")) + { + width = 0; + value.f = SYSMIS; + } else if (lex_is_string (lexer)) - width = ss_length (lex_tokss (lexer)); + { + width = ss_length (lex_tokss (lexer)); + value.s = CHAR_CAST (uint8_t *, ss_xstrdup (lex_tokss (lexer))); + lex_get (lexer); + } else { lex_error (lexer, _("expecting number or string")); @@ -171,6 +186,7 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) if (v == NULL) { msg (SE, _("Duplicate variable name %s."), name); + value_destroy (&value, width); goto done; } free (name); @@ -181,12 +197,28 @@ cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) else c = case_unshare_and_resize (c, dict_get_proto (d)); - if (!parse_value (lexer, case_data_rw (c, v), v)) - NOT_REACHED (); + *case_data_rw (c, v) = value; + + if (lex_match_id (lexer, "MISSING")) + { + struct missing_values mv; + mv_init (&mv, width); + mv_add_value (&mv, &value); + var_set_missing_values (v, &mv); + mv_destroy (&mv); + } if (!lex_force_match (lexer, T_RPAREN)) goto done; } + else if (lex_match_id (lexer, "VECTOR")) + { + struct variable **vars; + size_t n; + dict_get_vars_mutable (d, &vars, &n, 0); + dict_create_vector_assert (d, "V", vars, n); + free (vars); + } else break; } diff --git a/src/language/expressions/operations.def b/src/language/expressions/operations.def index 5c70ca00c1..e1132a5bc9 100644 --- a/src/language/expressions/operations.def +++ b/src/language/expressions/operations.def @@ -1098,7 +1098,7 @@ no_opt boolean function SYSMIS (num_var v) { return case_num (c, v) == SYSMIS; } -no_opt boolean function VALUE (num_var v) +no_opt function VALUE (num_var v) case c; { return case_num (c, v); diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index 8b62c92c4e..da027b5e7a 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -468,6 +468,7 @@ type_coercion__ (struct expression *e, struct expr_node *node, size_t arg_idx, break; case OP_format: + /* We never coerce to OP_format, only to OP_ni_format or OP_no_format. */ NOT_REACHED (); case OP_ni_format: diff --git a/tests/language/expressions/evaluate.at b/tests/language/expressions/evaluate.at index 87d480de03..cf0fdd0783 100644 --- a/tests/language/expressions/evaluate.at +++ b/tests/language/expressions/evaluate.at @@ -1554,6 +1554,49 @@ TAN('x') => error done AT_CLEANUP +AT_SETUP([expressions - MISSING NMISS NVALID SYSMIS ANY RANGE MAX MIN]) +AT_KEYWORDS([expression expressions evaluate]) +AT_DATA([evaluate-base.sps], [ +DEBUG EVALUATE SET opt. +DEBUG EVALUATE /MISSING(10). +DEBUG EVALUATE /MISSING($SYSMIS). +DEBUG EVALUATE /MISSING(ASIN(1.01)). +DEBUG EVALUATE /MISSING(ASIN(.5)). +DEBUG EVALUATE /MISSING(' '). + +DEBUG EVALUATE (x=5)/x. +DEBUG EVALUATE (x=5 MISSING)/x. +DEBUG EVALUATE (x=SYSMIS)/x. + +DEBUG EVALUATE (x=5) VECTOR/v(1). +DEBUG EVALUATE (x=5 MISSING) VECTOR/v(1). +DEBUG EVALUATE (x=SYSMIS) VECTOR/v(1). + +DEBUG EVALUATE (x=5)/VALUE(x). +DEBUG EVALUATE (x=5 MISSING)/VALUE(x). +DEBUG EVALUATE (x=SYSMIS)/VALUE(x). + +DEBUG EVALUATE (x=5) VECTOR/VALUE(v(1)). +DEBUG EVALUATE (x=5 MISSING) VECTOR/VALUE(v(1)). +DEBUG EVALUATE (x=SYSMIS) VECTOR/VALUE(v(1)). + +DEBUG EVALUATE (x=5)/MISSING(x). +DEBUG EVALUATE (x=5 MISSING)/MISSING(x). +DEBUG EVALUATE (x=SYSMIS)/MISSING(x). + +DEBUG EVALUATE (x=5)/SYSMIS(x). +DEBUG EVALUATE (x=5 MISSING)/SYSMIS(x). +DEBUG EVALUATE (x=SYSMIS)/SYSMIS(x). +]) + +for opt in OPT NOOPT; do + AS_BOX([$opt]) + sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps + AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl +]) +done +AT_CLEANUP + # FIXME: a variable name as the argument to SYSMIS is a special case # that we don't yet test. We also can't test VALUE this way. CHECK_EXPR_EVAL([missing nmiss nvalid sysmis any range max min], -- 2.30.2