+ return lvalue;
+
+ lossage:
+ lvalue_destroy (lvalue);
+ return NULL;
+}
+
+/* Returns the type (NUMERIC or ALPHA) of the target variable or
+ vector in LVALUE. */
+static int
+lvalue_get_type (const struct lvalue *lvalue)
+{
+ if (lvalue->vector == NULL)
+ {
+ struct variable *var
+ = dict_lookup_var (default_dict, lvalue->var_name);
+ if (var == NULL)
+ return NUMERIC;
+ else
+ return var->type;
+ }
+ else
+ return lvalue->vector->var[0]->type;
+}
+
+/* Returns nonzero if LVALUE has a vector as its target. */
+static int
+lvalue_is_vector (const struct lvalue *lvalue)
+{
+ return lvalue->vector != NULL;
+}
+
+/* Finalizes making LVALUE the target of COMPUTE, by creating the
+ target variable if necessary and setting fields in COMPUTE. */
+static void
+lvalue_finalize (struct lvalue *lvalue,
+ struct compute_trns *compute)
+{
+ if (lvalue->vector == NULL)
+ {
+ compute->variable = dict_lookup_var (default_dict, lvalue->var_name);
+ if (compute->variable == NULL)
+ compute->variable = dict_create_var_assert (default_dict,
+ lvalue->var_name, 0);
+
+ compute->fv = compute->variable->fv;
+ compute->width = compute->variable->width;
+
+ /* Goofy behavior, but compatible: Turn off LEAVE. */
+ if (dict_class_from_id (compute->variable->name) != DC_SCRATCH)
+ compute->variable->reinit = 1;
+ }
+ else
+ {
+ compute->vector = lvalue->vector;
+ compute->element = lvalue->element;
+ lvalue->element = NULL;
+ }
+
+ lvalue_destroy (lvalue);
+}
+
+/* Destroys LVALUE. */
+static void
+lvalue_destroy (struct lvalue *lvalue)
+{
+ expr_free (lvalue->element);
+ free (lvalue);