X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fexpressions%2Fevaluate.c;h=5395384a8197c5be1c2276787bddc3c9f975e488;hb=e5675aa578a919a051f4de276d5f7e4df5ea8819;hp=9398b41cd239b285061cffca4522e87f806d15ca;hpb=b74d09af5e07f954c18e7cdb8aca3af47fa10208;p=pspp diff --git a/src/language/expressions/evaluate.c b/src/language/expressions/evaluate.c index 9398b41cd2..5395384a81 100644 --- a/src/language/expressions/evaluate.c +++ b/src/language/expressions/evaluate.c @@ -1,5 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. Written by Ben Pfaff . This program is free software; you can redistribute it and/or @@ -22,6 +22,7 @@ #include #include +#include #include #include "helpers.h" #include "evaluate.h" @@ -31,12 +32,19 @@ static void expr_evaluate (struct expression *e, const struct ccase *c, int case_idx, void *result) { + struct dataset *ds = e->ds; union operation_data *op = e->ops; double *ns = e->number_stack; struct substring *ss = e->string_stack; - assert ((c != NULL) == (e->dict != NULL)); + /* Without a dictionary/dataset, the expression can't refer to variables, + and you don't need to specify a case when you evaluate the + expression. With a dictionary/dataset, the expression can refer + to variables, so you must specify a case when you evaluate the + expression. */ + assert ((c != NULL) == (e->ds != NULL)); + pool_clear (e->eval_pool); for (;;) @@ -67,7 +75,7 @@ expr_evaluate (struct expression *e, const struct ccase *c, int case_idx, #include "evaluate.inc" default: - abort (); + NOT_REACHED (); } } } @@ -82,8 +90,6 @@ expr_evaluate_num (struct expression *e, const struct ccase *c, int case_idx) return d; } - - void expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx, char *dst, size_t dst_size) @@ -101,55 +107,61 @@ expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx, #include int -cmd_debug_evaluate (void) +cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED) { bool optimize = true; int retval = CMD_FAILURE; bool dump_postfix = false; - struct dictionary *d = NULL; + struct ccase *c = NULL; + struct dataset *ds = NULL; + struct expression *expr; for (;;) { - if (lex_match_id ("NOOPTIMIZE")) + struct dictionary *d = NULL; + if (lex_match_id (lexer, "NOOPTIMIZE")) optimize = 0; - else if (lex_match_id ("POSTFIX")) + else if (lex_match_id (lexer, "POSTFIX")) dump_postfix = 1; - else if (lex_match ('(')) + else if (lex_match (lexer, '(')) { char name[LONG_NAME_LEN + 1]; struct variable *v; size_t old_value_cnt; int width; - if (!lex_force_id ()) + if (!lex_force_id (lexer)) goto done; - strcpy (name, tokid); + strcpy (name, lex_tokid (lexer)); - lex_get (); - if (!lex_force_match ('=')) + lex_get (lexer); + if (!lex_force_match (lexer, '=')) goto done; - if (lex_is_number ()) + if (lex_is_number (lexer)) { width = 0; - fprintf (stderr, "(%s = %.2f)", name, tokval); + fprintf (stderr, "(%s = %.2f)", name, lex_tokval (lexer)); } - else if (token == T_STRING) + else if (lex_token (lexer) == T_STRING) { - width = ds_length (&tokstr); - fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (&tokstr)); + width = ds_length (lex_tokstr (lexer)); + fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (lex_tokstr (lexer))); } else { - lex_error (_("expecting number or string")); + lex_error (lexer, _("expecting number or string")); goto done; } - - if (d == NULL) - d = dict_create (); + + if ( ds == NULL ) + { + ds = create_dataset (); + d = dataset_dict (ds); + } old_value_cnt = dict_get_next_value_idx (d); v = dict_create_var (d, name, width); @@ -162,35 +174,37 @@ cmd_debug_evaluate (void) if (c == NULL) { c = xmalloc (sizeof *c); - case_nullify (c); + case_create (c, dict_get_next_value_idx (d)); } - case_resize (c, old_value_cnt, dict_get_next_value_idx (d)); + else + case_resize (c, old_value_cnt, dict_get_next_value_idx (d)); - if (lex_is_number ()) - case_data_rw (c, v->fv)->f = tokval; + if (lex_is_number (lexer)) + case_data_rw (c, v->fv)->f = lex_tokval (lexer); else - memcpy (case_data_rw (c, v->fv)->s, ds_data (&tokstr), + memcpy (case_data_rw (c, v->fv)->s, ds_data (lex_tokstr (lexer)), v->width); - lex_get (); + lex_get (lexer); - if (!lex_force_match (')')) + if (!lex_force_match (lexer, ')')) goto done; } else break; } - if (token != '/') + if (lex_token (lexer) != '/') { - lex_force_match ('/'); + lex_force_match (lexer, '/'); goto done; } - if (d != NULL) - fprintf (stderr, "; "); - fprintf (stderr, "%s => ", lex_rest_of_line (NULL)); - lex_get (); - expr = expr_parse_any (d, optimize); - if (!expr || lex_end_of_command () != CMD_SUCCESS) + if ( ds != NULL ) + fprintf(stderr, "; "); + fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL)); + lex_get (lexer); + + expr = expr_parse_any (lexer, ds, optimize); + if (!expr || lex_end_of_command (lexer) != CMD_SUCCESS) { if (expr != NULL) expr_free (expr); @@ -233,19 +247,22 @@ cmd_debug_evaluate (void) } default: - assert (0); + NOT_REACHED (); } expr_free (expr); retval = CMD_SUCCESS; done: + if (ds) + destroy_dataset (ds); + if (c != NULL) { case_destroy (c); free (c); } - dict_destroy (d); + return retval; } @@ -285,9 +302,11 @@ expr_debug_print_postfix (const struct expression *e) op->string.string != NULL ? op->string.string : ""); break; case OP_format: - fprintf (stderr, "f<%s%d.%d>", - formats[op->format->type].name, - op->format->w, op->format->d); + { + char str[FMT_STRING_LEN_MAX + 1]; + fmt_to_string (op->format, str); + fprintf (stderr, "f<%s>", str); + } break; case OP_variable: fprintf (stderr, "v<%s>", op->variable->name); @@ -299,7 +318,7 @@ expr_debug_print_postfix (const struct expression *e) fprintf (stderr, "i<%d>", op->integer); break; default: - abort (); + NOT_REACHED (); } } fprintf (stderr, "\n");