You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
#include "private.h"
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 *);
\f
/* Public functions. */
/* 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
case OP_ni_format:
if ((*node)->type == OP_format
- && check_input_specifier (&(*node)->format.f, 0))
+ && check_input_specifier (&(*node)->format.f, false)
+ && check_specifier_type (&(*node)->format.f, NUMERIC, false))
{
if (do_coercion)
(*node)->type = OP_ni_format;
case OP_no_format:
if ((*node)->type == OP_format
- && check_output_specifier (&(*node)->format.f, 0))
+ && check_output_specifier (&(*node)->format.f, false)
+ && check_specifier_type (&(*node)->format.f, NUMERIC, false))
{
if (do_coercion)
(*node)->type = OP_no_format;
}
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;
}
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.
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);
}
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. */
/* 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. */
static const struct operator ops[] =
{
{ '+', OP_ADD, "addition (\"+\")" },
- { '-', OP_SUB, "subtraction (\"-\")-" },
+ { '-', OP_SUB, "subtraction (\"-\")" },
};
return parse_binary_operators (e, parse_mul (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
{
}
break;
- case T_NUM:
+ case T_POS_NUM:
+ case T_NEG_NUM:
{
union any_node *node = expr_allocate_number (e, tokval);
lex_get ();
return expr_allocate_binary (e, (vector->var[0]->type == NUMERIC
? OP_VEC_ELEM_NUM : OP_VEC_ELEM_STR),
- expr_allocate_vector (e, vector), element);
+ element, expr_allocate_vector (e, vector));
}
\f
/* Individual function parsing. */
}
else
{
- ds_create (&s, _("Function invocation "));
+ ds_puts (&s, _("Function invocation "));
put_invocation (&s, func_name, args, arg_cnt);
ds_puts (&s, _(" does not match any known function. Candidates are:"));
for (f = first; f < last; f++)
- {
- ds_printf (&s, "\n%s", f->prototype);
- }
+ ds_printf (&s, "\n%s", f->prototype);
}
ds_putc (&s, '.');
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
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));
+}