02111-1307, USA. */
#include <config.h>
+#include "dictionary.h"
#include "expr.h"
#include "exprP.h"
#include "error.h"
static algo_compare_func compare_functions;
static void init_func_tab (void);
-
-#if DEBUGGING
-static void debug_print_tree (union any_node *, int);
-#endif
\f
/* Public functions. */
expr_parse (enum expr_type expected_type)
{
struct expression *e;
- union any_node *n;
+ union any_node *n=0;
enum expr_type actual_type;
int optimize = (expected_type & EXPR_NO_OPTIMIZE) == 0;
case T_STRING:
{
- *n = allocate_str_con (ds_value (&tokstr), ds_length (&tokstr));
+ *n = allocate_str_con (ds_c_str (&tokstr), ds_length (&tokstr));
lex_get ();
return EXPR_STRING;
}
type = parse_or (&(*n)->nonterm.arg[(*n)->nonterm.n]);
if (type == EXPR_ERROR)
goto fail;
+ (*n)->nonterm.n++;
if (type != EXPR_STRING)
{
msg (SE, _("Argument %d to CONCAT is type %s. All arguments "
(*n)->nonterm.n + 1, expr_type_name (type));
goto fail;
}
- (*n)->nonterm.n++;
if (!lex_match (','))
break;
goto fail;
else if (actual_type == EXPR_BOOLEAN)
actual_type = EXPR_NUMERIC;
+ nonterm->n++;
if (actual_type != wanted_type)
{
msg (SE, _("Argument %d to %s was expected to be of %s type. "
expr_type_name (actual_type), expr_type_name (wanted_type));
goto fail;
}
- nonterm->n++;
}
else if (*cp == 'f')
{
}
ds_truncate (&tokstr, 31);
- strcpy (fname, ds_value (&tokstr));
+ strcpy (fname, ds_c_str (&tokstr));
cp = strrchr (fname, '.');
if (cp && isdigit ((unsigned char) cp[1]))
{
\f
/* Debug output. */
-#if DEBUGGING
-static void
-print_type (union any_node * n)
-{
- const char *s;
- size_t len;
-
- s = ops[n->type].name;
- len = strlen (s);
- if (ops[n->type].flags & OP_MIN_ARGS)
- printf ("%s.%d\n", s, (int) n->nonterm.arg[n->nonterm.n]);
- else if (ops[n->type].flags & OP_FMT_SPEC)
- {
- struct fmt_spec f;
-
- f.type = (int) n->nonterm.arg[n->nonterm.n + 0];
- f.w = (int) n->nonterm.arg[n->nonterm.n + 1];
- f.d = (int) n->nonterm.arg[n->nonterm.n + 2];
- printf ("%s(%s)\n", s, fmt_to_string (&f));
- }
- else
- printf ("%s\n", s);
-}
-
-static void
-debug_print_tree (union any_node * n, int level)
-{
- int i;
- for (i = 0; i < level; i++)
- printf (" ");
- if (n->type < OP_TERMINAL)
- {
- print_type (n);
- for (i = 0; i < n->nonterm.n; i++)
- debug_print_tree (n->nonterm.arg[i], level + 1);
- }
- else
- {
- switch (n->type)
- {
- case OP_TERMINAL:
- printf (_("!!TERMINAL!!"));
- break;
- case OP_NUM_CON:
- if (n->num_con.value == SYSMIS)
- printf ("SYSMIS");
- else
- printf ("%f", n->num_con.value);
- break;
- case OP_STR_CON:
- printf ("\"%.*s\"", n->str_con.len, n->str_con.s);
- break;
- case OP_NUM_VAR:
- case OP_STR_VAR:
- printf ("%s", n->var.v->name);
- break;
- case OP_NUM_LAG:
- case OP_STR_LAG:
- printf ("LAG(%s,%d)", n->lag.v->name, n->lag.lag);
- break;
- case OP_NUM_SYS:
- printf ("SYSMIS(%s)", n->var.v->name);
- break;
- case OP_NUM_VAL:
- printf ("VALUE(%s)", n->var.v->name);
- break;
- case OP_SENTINEL:
- printf (_("!!SENTINEL!!"));
- break;
- default:
- printf (_("!!ERROR%d!!"), n->type);
- assert (0);
- }
- printf ("\n");
- }
-}
-#endif /* DEBUGGING */
-
void
expr_debug_print_postfix (const struct expression *e)
{
{
#include "expr.def"
};
+\f
+#include "command.h"
+
+int
+cmd_debug_evaluate (void)
+{
+ struct expression *expr;
+ union value value;
+ enum expr_type expr_flags;
+ int dump_postfix = 0;
+
+ discard_variables ();
+
+ expr_flags = 0;
+ if (lex_match_id ("NOOPTIMIZE"))
+ expr_flags |= EXPR_NO_OPTIMIZE;
+ if (lex_match_id ("POSTFIX"))
+ dump_postfix = 1;
+ if (token != '/')
+ {
+ lex_force_match ('/');
+ return CMD_FAILURE;
+ }
+ fprintf (stderr, "%s => ", lex_rest_of_line (NULL));
+ lex_get ();
+
+ expr = expr_parse (EXPR_ANY | expr_flags);
+ if (!expr || token != '.')
+ {
+ if (expr != NULL)
+ expr_free (expr);
+ fprintf (stderr, "error\n");
+ return CMD_FAILURE;
+ }
+
+ if (dump_postfix)
+ expr_debug_print_postfix (expr);
+ else
+ {
+ expr_evaluate (expr, NULL, 0, &value);
+ switch (expr_get_type (expr))
+ {
+ case EXPR_NUMERIC:
+ if (value.f == SYSMIS)
+ fprintf (stderr, "sysmis\n");
+ else
+ fprintf (stderr, "%.2f\n", value.f);
+ break;
+
+ case EXPR_BOOLEAN:
+ if (value.f == SYSMIS)
+ fprintf (stderr, "sysmis\n");
+ else if (value.f == 0.0)
+ fprintf (stderr, "false\n");
+ else
+ fprintf (stderr, "true\n");
+ break;
+
+ case EXPR_STRING:
+ fputc ('"', stderr);
+ fwrite (value.c + 1, value.c[0], 1, stderr);
+ fputs ("\"\n", stderr);
+ break;
+
+ default:
+ assert (0);
+ }
+ }
+
+ expr_free (expr);
+ return CMD_SUCCESS;
+}