X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fexpressions%2Fparse.c;h=5e917a0e80386e65b936078ebe6090175b7dfb7f;hb=4848cff524922cc77ed21662406807471e96a68e;hp=2288d5277b6afb3e362ef00d979967219b09bc3e;hpb=d807ad29cc0d3caa4f0e04ee4b75c70a225cfeaf;p=pspp-builds.git diff --git a/src/expressions/parse.c b/src/expressions/parse.c index 2288d527..5e917a0e 100644 --- a/src/expressions/parse.c +++ b/src/expressions/parse.c @@ -56,6 +56,8 @@ static struct expression *finish_expression (union any_node *, struct expression *); static bool type_check (struct expression *, union any_node **, enum expr_type expected_type); +static union any_node *allocate_unary_variable (struct expression *, + struct variable *); /* Public functions. */ @@ -66,7 +68,7 @@ static bool type_check (struct expression *, union any_node **, Returns the new expression if successful or a null pointer otherwise. */ struct expression * -expr_parse (struct dictionary *dict, atom_type type) +expr_parse (struct dictionary *dict, enum expr_type type) { union any_node *n; struct expression *e; @@ -267,13 +269,12 @@ type_check (struct expression *e, /* Considers whether *NODE may be coerced to type REQUIRED_TYPE. Returns true if possible, false if disallowed. - If DO_COERCION is zero, then *NODE is not modified and there + If DO_COERCION is false, then *NODE is not modified and there are no side effects. - Otherwise, DO_COERCION is nonzero. In this case, we perform - the coercion if possible, possibly modifying *NODE. If the - coercion is not possible then we free *NODE and set *NODE to - a null pointer. + If DO_COERCION is true, we perform the coercion if possible, + modifying *NODE if necessary. If the coercion is not possible + then we free *NODE and set *NODE to a null pointer. This function's interface is somewhat awkward. Use one of the wrapper functions type_coercion(), type_coercion_assert(), or @@ -387,10 +388,13 @@ type_coercion_core (struct expression *e, } if (do_coercion) - msg (SE, _("Type mismatch while applying %s operator: " - "cannot convert %s to %s."), - operator_name, - atom_type_name (actual_type), atom_type_name (required_type)); + { + msg (SE, _("Type mismatch while applying %s operator: " + "cannot convert %s to %s."), + operator_name, + atom_type_name (actual_type), atom_type_name (required_type)); + *node = NULL; + } return false; } @@ -402,7 +406,7 @@ type_coercion (struct expression *e, atom_type required_type, union any_node **node, const char *operator_name) { - return type_coercion_core (e, required_type, node, operator_name, 1); + return type_coercion_core (e, required_type, node, operator_name, true); } /* Coerces *NODE to type REQUIRED_TYPE. @@ -411,7 +415,7 @@ static void type_coercion_assert (struct expression *e, atom_type required_type, union any_node **node) { - int success = type_coercion_core (e, required_type, node, NULL, 1); + int success = type_coercion_core (e, required_type, node, NULL, true); assert (success); } @@ -421,7 +425,7 @@ static bool is_coercible (atom_type required_type, union any_node *const *node) { return type_coercion_core (NULL, required_type, - (union any_node **) node, NULL, 0); + (union any_node **) node, NULL, false); } /* How to parse an operator. */ @@ -517,7 +521,7 @@ parse_binary_operators (struct expression *e, union any_node *node, /* Convert the left-hand side to type OPERAND_TYPE. */ if (!type_coercion (e, operand_type, &node, operator->name)) - return node; + return NULL; /* Parse the right-hand side and coerce to type OPERAND_TYPE. */ @@ -651,7 +655,7 @@ parse_add (struct expression *e) static const struct operator ops[] = { { '+', OP_ADD, "addition (\"+\")" }, - { '-', OP_SUB, "subtraction (\"-\")-" }, + { '-', OP_SUB, "subtraction (\"-\")" }, }; return parse_binary_operators (e, parse_mul (e), @@ -783,12 +787,7 @@ parse_primary (struct expression *e) /* It looks like a user variable. (It could be a format specifier, but we'll assume it's a variable unless proven otherwise. */ - struct variable *v = parse_dict_variable (e->dict); - assert (v != NULL); - return expr_allocate_unary (e, - (v->type == NUMERIC - ? OP_NUM_VAR : OP_STR_VAR), - expr_allocate_variable (e, v)); + return allocate_unary_variable (e, parse_dict_variable (e->dict)); } else { @@ -803,7 +802,8 @@ parse_primary (struct expression *e) } break; - case T_NUM: + case T_POS_NUM: + case T_NEG_NUM: { union any_node *node = expr_allocate_number (e, tokval); lex_get (); @@ -1159,7 +1159,7 @@ parse_function (struct expression *e) goto fail; for (i = 0; i < var_cnt; i++) add_arg (&args, &arg_cnt, &arg_cap, - expr_allocate_variable (e, vars[i])); + allocate_unary_variable (e, vars[i])); free (vars); } else @@ -1422,3 +1422,13 @@ expr_allocate_format (struct expression *e, const struct fmt_spec *format) n->format.f = *format; return n; } + +/* Allocates a unary composite node that represents the value of + variable V in expression E. */ +static union any_node * +allocate_unary_variable (struct expression *e, struct variable *v) +{ + assert (v != NULL); + return expr_allocate_unary (e, v->type == NUMERIC ? OP_NUM_VAR : OP_STR_VAR, + expr_allocate_variable (e, v)); +}