backend: revamp the handling of symbol types

Currently it is the front end that passes the symbol types to the
backend.  For instance:

  %token <ival> NUM
  %type <ival> exp1 exp2
  exp1: NUM { $$ = $1; }
  exp2: NUM { $<ival>$ = $<ival>1; }

In both cases, $$ and $1 are passed to the backend as having type
'ival' resulting in code like `val.ival`.  This is troublesome in the
case of api.value.type=union, since in that the case the code this:

  %define api.value.type union
  %token <int> NUM
  %type <int> exp1 exp2
  exp1: NUM { $$ = $1; }
  exp2: NUM { $<int>$ = $<int>1; }

because in this case, since the backend does not know the symbol being
processed, it is forced to generate casts in both cases: *(int*)(&val)`.
This is unfortunate in the first case (exp1) where there is no reason
at all to use a cast instead of `val.NUM` and `val.exp1`.

So instead delegate the computation of the actual value type to the
backend: pass $<ival>$ as `symbol-number, ival` and $$ as
`symbol-number, MULL`, instead of passing `ival` before.

* src/scan-code.l (handle_action_dollar): Find the symbol the action
is about, not just its tyye.  Pass both symbol-number, and explicit
type tag ($<tag>n when there is one) to b4_lhs_value and b4_rhs_value.

* data/bison.m4 (b4_symbol_action): adjust to the new signature to
b4_dollar_pushdef.

* data/c-like.m4 (_b4_dollar_dollar, b4_dollar_pushdef): Accept the
symbol-number as new argument.

* data/c.m4 (b4_symbol_value): Accept the symbol-number as new
argument, and use it.
(b4_symbol_value_union): Accept the symbol-number as new
argument, and use it to prefer ready a union member rather than
casting the union.
* data/yacc.c (b4_lhs_value, b4_rhs_value): Accept the new
symbol-number argument.
Adjust uses of b4_dollar_pushdef.
* data/glr.c (b4_lhs_value, b4_rhs_value): Adjust.

* data/lalr1.cc (b4_symbol_value_template, b4_lhs_value): Adjust
to the new symbol-number argument.
* data/variant.hh (b4_symbol_value, b4_symbol_value_template): Accept
the new symbol-number argument.

* data/java.m4 (b4_symbol_value, b4_rhs_data): New.
(b4_rhs_value): Use them.
* data/lalr1.java: Adjust to b4_dollar_pushdef, and use b4_rhs_data.
This commit is contained in:
Akim Demaille
2018-12-03 07:03:29 +01:00
parent e40db8976c
commit c44a782a4e
10 changed files with 151 additions and 86 deletions

View File

@@ -468,8 +468,8 @@ m4_define([b4_symbol_action_location],
m4_define([b4_symbol_action], m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2], [b4_symbol_if([$1], [has_$2],
[b4_dollar_pushdef([(*yyvaluep)], [b4_dollar_pushdef([(*yyvaluep)],
b4_symbol_if([$1], [has_type], [$1],
[m4_dquote(b4_symbol([$1], [type]))]), [],
[(*yylocationp)])dnl [(*yylocationp)])dnl
_b4_symbol_case([$1])[]dnl _b4_symbol_case([$1])[]dnl
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])]) b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])

View File

@@ -39,25 +39,26 @@ m4_define([b4_comment],
# _b4_dollar_dollar(VALUE, FIELD, DEFAULT-FIELD) # _b4_dollar_dollar(VALUE, SYMBOL-NUM, FIELD, DEFAULT-FIELD)
# ---------------------------------------------- # ----------------------------------------------------------
# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD", # If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
# otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a # otherwise just VALUE. Be sure to pass "(VALUE)" if VALUE is a
# pointer. # pointer.
m4_define([_b4_dollar_dollar], m4_define([_b4_dollar_dollar],
[b4_symbol_value([$1], [b4_symbol_value([$1],
m4_if([$2], [[]], [$2],
[[$3]], [[$2]]))]) m4_if([$3], [[]],
[[$4]], [[$3]]))])
# b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION) # b4_dollar_pushdef(VALUE-POINTER, SYMBOL-NUM, [TYPE_TAG], LOCATION)
# b4_dollar_popdef # b4_dollar_popdef
# --------------------------------------------------------- # ------------------------------------------------------------------
# Define b4_dollar_dollar for VALUE and DEFAULT-FIELD, # Define b4_dollar_dollar for VALUE-POINTER and DEFAULT-FIELD,
# and b4_at_dollar for LOCATION. # and b4_at_dollar for LOCATION.
m4_define([b4_dollar_pushdef], m4_define([b4_dollar_pushdef],
[m4_pushdef([b4_dollar_dollar], [m4_pushdef([b4_dollar_dollar],
[_b4_dollar_dollar([$1], m4_dquote($][1), [$2])])dnl [_b4_dollar_dollar([$1], [$2], m4_dquote($][1), [$3])])dnl
m4_pushdef([b4_at_dollar], [$3])dnl m4_pushdef([b4_at_dollar], [$4])dnl
]) ])
m4_define([b4_dollar_popdef], m4_define([b4_dollar_popdef],
[m4_popdef([b4_at_dollar])dnl [m4_popdef([b4_at_dollar])dnl

View File

@@ -373,15 +373,28 @@ m4_define([b4_token_enums_defines],
## ----------------- ## ## ----------------- ##
# b4_symbol_value(VAL, [TYPE]) # b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
# ---------------------------- # ----------------------------------------------
# Given a semantic value VAL ($$, $1 etc.), extract its value of type # Expansion of $$, $1, $<TYPE-TAG>3, etc.
# TYPE if TYPE is given, otherwise just return VAL. The result can be #
# used safely, it is put in parens to avoid nasty precedence issues. # The semantic value from a given VAL.
# TYPE is *not* put in braces, provide some if needed. #
# VAL: some semantic value storage (typically a union).
# e.g., yylval
# SYMBOL-NUM: the symbol number from which we extract the
# type tag.
# TYPE-TAG, the user forced the <TYPE-TAG>.
#
# The result can be used safely, it is put in parens to avoid nasty
# precedence issues.
m4_define([b4_symbol_value], m4_define([b4_symbol_value],
[($1[]m4_ifval([$2], [.$2]))]) [m4_ifval([$3],
[($1.$3)],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[($1.b4_symbol([$2], [type]))],
[$1])],
[$1])])])
## ---------------------- ## ## ---------------------- ##
@@ -604,14 +617,17 @@ m4_define([b4_type_define_tag],
]) ])
# b4_symbol_value_union(VAL, [TYPE]) # b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
# ---------------------------------- # ----------------------------------------------
# Same of b4_symbol_value, but when api.value.type=union. # Same of b4_symbol_value, but when api.value.type=union.
m4_define([b4_symbol_value_union], m4_define([b4_symbol_value_union],
[m4_ifval([$2], [m4_ifval([$3],
[(*($2*)(&$1))], [(*($3*)(&$1))],
[$1])]) [m4_ifval([$2],
]) [b4_symbol_if([$2], [has_type],
[($1.b4_symbol([$2], [type_tag]))],
[$1])],
[$1])])])
# b4_value_type_setup_union # b4_value_type_setup_union

View File

@@ -112,11 +112,11 @@ m4_define([b4_locuser_args],
## ----------------- ## ## ----------------- ##
# b4_lhs_value([TYPE]) # b4_lhs_value(SYMBOL-NUM, [TYPE])
# -------------------- # --------------------------------
# Expansion of $<TYPE>$. # Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value], m4_define([b4_lhs_value],
[b4_symbol_value([(*yyvalp)], [$1])]) [b4_symbol_value([(*yyvalp)], [$1], [$2])])
# b4_rhs_data(RULE-LENGTH, POS) # b4_rhs_data(RULE-LENGTH, POS)
@@ -127,12 +127,12 @@ m4_define([b4_rhs_data],
[((yyGLRStackItem const *)yyvsp)@{YYFILL (b4_subtract([$2], [$1]))@}.yystate]) [((yyGLRStackItem const *)yyvsp)@{YYFILL (b4_subtract([$2], [$1]))@}.yystate])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# -------------------------------------- # --------------------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH # Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS. # symbols on RHS.
m4_define([b4_rhs_value], m4_define([b4_rhs_value],
[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3])]) [b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])])
@@ -2265,7 +2265,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
yylval = yyval_default;]b4_locations_if([ yylval = yyval_default;]b4_locations_if([
yylloc = yyloc_default;])[ yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef])[]dnl b4_dollar_popdef])[]dnl
[ [

View File

@@ -219,21 +219,56 @@ m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])
## ----------------- ## ## ----------------- ##
# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
# ----------------------------------------------
# Expansion of $$, $1, $<TYPE-TAG>3, etc.
#
# The semantic value from a given VAL.
#
# VAL: some semantic value storage (typically a union).
# e.g., yylval
# SYMBOL-NUM: the symbol number from which we extract the
# type tag.
# TYPE-TAG, the user forced the <TYPE-TAG>.
#
# The result can be used safely, it is put in parens to avoid nasty
# precedence issues.
m4_define([b4_symbol_value],
[m4_ifval([$3],
[(($3)($1))],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[((b4_symbol([$2], [type]))($1))],
[$1])],
[$1])])])
# b4_lhs_value([TYPE]) # b4_lhs_value([TYPE])
# -------------------- # --------------------
# Expansion of $<TYPE>$. # Expansion of $<TYPE>$.
m4_define([b4_lhs_value], [yyval]) m4_define([b4_lhs_value], [yyval])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # b4_rhs_data(RULE-LENGTH, POS)
# -------------------------------------- # -----------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH # Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
#
# In this simple implementation, %token and %type have class names
# between the angle brackets.
m4_define([b4_rhs_data],
[yystack.valueAt ($1-($2))])
# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# --------------------------------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS. # symbols on RHS.
# #
# In this simple implementation, %token and %type have class names # In this simple implementation, %token and %type have class names
# between the angle brackets. # between the angle brackets.
m4_define([b4_rhs_value], m4_define([b4_rhs_value],
[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))]) [b4_symbol_value([b4_rhs_data([$1], [$2])], [$3], [$4])])
# b4_lhs_location() # b4_lhs_location()
# ----------------- # -----------------

View File

@@ -41,20 +41,20 @@ m4_define([b4_integral_parser_table_define],
};dnl };dnl
]) ])
# b4_symbol_value_template(VAL, [TYPE]) # b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# ------------------------------------- # -------------------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes # Same as b4_symbol_value, but used in a template method. It makes
# a difference when using variants. Note that b4_value_type_setup_union # a difference when using variants. Note that b4_value_type_setup_union
# overrides b4_symbol_value, so we must override it again. # overrides b4_symbol_value, so we must override it again.
m4_copy([b4_symbol_value], [b4_symbol_value_template]) m4_copy([b4_symbol_value], [b4_symbol_value_template])
m4_append([b4_value_type_setup_union], m4_append([b4_value_type_setup_union],
[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])]) [m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
# b4_lhs_value([TYPE]) # b4_lhs_value(SYMBOL-NUM, SYMBOL-NUM, [TYPE])
# -------------------- # --------------------------------------------
# Expansion of $<TYPE>$. # Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value], m4_define([b4_lhs_value],
[b4_symbol_value([yylhs.value], [$1])]) [b4_symbol_value([yylhs.value], [$1], [$2])])
# b4_lhs_location() # b4_lhs_location()
@@ -80,12 +80,12 @@ m4_define([b4_rhs_state],
[b4_rhs_data([$1], [$2]).state]) [b4_rhs_data([$1], [$2]).state])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# -------------------------------------- # --------------------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH # Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS. # symbols on RHS.
m4_define([_b4_rhs_value], m4_define([_b4_rhs_value],
[b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])]) [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3], [$4])])
m4_define([b4_rhs_value], m4_define([b4_rhs_value],
[b4_percent_define_ifdef([api.value.automove], [b4_percent_define_ifdef([api.value.automove],
@@ -109,9 +109,9 @@ m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2], [b4_symbol_if([$1], [has_$2],
[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl [m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
b4_dollar_pushdef([yysym.value], b4_dollar_pushdef([yysym.value],
b4_symbol_if([$1], [has_type], [$1],
[m4_dquote(b4_symbol([$1], [type]))]), [],
[yysym.location])dnl [yysym.location])dnl
_b4_symbol_case([$1]) _b4_symbol_case([$1])
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])]) b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
b4_symbol([$1], [$2]) b4_symbol([$1], [$2])
@@ -780,7 +780,7 @@ m4_if(b4_prefix, [yy], [],
YYCDEBUG << "Starting parse\n"; YYCDEBUG << "Starting parse\n";
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yyla.value], [], [yyla.location])dnl b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef])[]dnl b4_dollar_popdef])[]dnl

View File

@@ -584,7 +584,7 @@ b4_define_state])[
/* Initialize the stack. */ /* Initialize the stack. */
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[); yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef[]dnl b4_dollar_popdef[]dnl
])[ ])[
@@ -594,7 +594,7 @@ b4_dollar_popdef[]dnl
{ {
push_parse_initialize (); push_parse_initialize ();
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef[]dnl b4_dollar_popdef[]dnl
])[ ])[
@@ -1033,7 +1033,7 @@ b4_both_if([[
for (int yyi = 0; yyi < yynrhs; yyi++) for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (" $" + (yyi + 1) + " =", yy_symbol_print (" $" + (yyi + 1) + " =",
yystos_[yystack.stateAt(yynrhs - (yyi + 1))], yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, ]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[); b4_rhs_location(yynrhs, yyi + 1)])[);
} }

View File

@@ -304,20 +304,28 @@ m4_define([b4_value_type_declare],
# How the semantic value is extracted when using variants. # How the semantic value is extracted when using variants.
# b4_symbol_value(VAL, [TYPE]) # b4_symbol_value(VAL, SYMBOL-NUM, [TYPE])
# ---------------------------- # ----------------------------------------
m4_define([b4_symbol_value], m4_define([b4_symbol_value],
[m4_ifval([$2], [m4_ifval([$3],
[$1.as< $2 > ()], [$1.as< $3 > ()],
[$1])]) [m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[$1.as < b4_symbol([$2], [type]) > ()],
[$1])],
[$1])])])
# b4_symbol_value_template(VAL, [TYPE]) # b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# ------------------------------------- # -------------------------------------------------
# Same as b4_symbol_value, but used in a template method. # Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template], m4_define([b4_symbol_value_template],
[m4_ifval([$2], [m4_ifval([$3],
[$1.template as< $2 > ()], [$1.template as< $3 > ()],
[$1])]) [m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[$1.template as < b4_symbol([$2], [type]) > ()],
[$1])],
[$1])])])

View File

@@ -128,19 +128,19 @@ m4_define([b4_int_type],
## ----------------- ## ## ----------------- ##
# b4_lhs_value([TYPE]) # b4_lhs_value(SYMBOL-NUM, [TYPE])
# -------------------- # --------------------------------
# Expansion of $<TYPE>$. # Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value], m4_define([b4_lhs_value],
[b4_symbol_value(yyval, [$1])]) [b4_symbol_value(yyval, [$1], [$2])])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# -------------------------------------- # --------------------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH # Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS. # symbols on RHS.
m4_define([b4_rhs_value], m4_define([b4_rhs_value],
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])]) [b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3], [$4])])
## ----------- ## ## ----------- ##
@@ -1426,7 +1426,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
yynerrs = 0; yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */ yychar = YYEMPTY; /* Cause a token to be read. */
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl [b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef[]dnl b4_dollar_popdef[]dnl

View File

@@ -627,10 +627,9 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
case LHS_REF: case LHS_REF:
{ {
if (!type_name) symbol_list *sym = symbol_list_n_get (rule, 0);
type_name = symbol_list_n_type_name_get (rule, 0); if (!type_name
&& !sym->content.sym->content->type_name)
if (!type_name)
{ {
if (union_seen | tag_seen) if (union_seen | tag_seen)
{ {
@@ -649,7 +648,8 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
untyped_var_seen = true; untyped_var_seen = true;
} }
obstack_sgrow (&obstack_for_string, "]b4_lhs_value("); obstack_printf (&obstack_for_string, "]b4_lhs_value(%d, ",
sym->content.sym->content->number);
obstack_quote (&obstack_for_string, type_name); obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")["); obstack_sgrow (&obstack_for_string, ")[");
rule->action_props.is_value_used = true; rule->action_props.is_value_used = true;
@@ -661,9 +661,9 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{ {
if (max_left_semantic_context < 1 - n) if (max_left_semantic_context < 1 - n)
max_left_semantic_context = 1 - n; max_left_semantic_context = 1 - n;
if (!type_name && 0 < n) symbol_list *sym = 0 < n ? symbol_list_n_get (effective_rule, n) : NULL;
type_name = symbol_list_n_type_name_get (effective_rule, n); if (!type_name
if (!type_name) && (!sym || !sym->content.sym->content->type_name))
{ {
if (union_seen | tag_seen) if (union_seen | tag_seen)
complain (&dollar_loc, complaint, complain (&dollar_loc, complaint,
@@ -674,12 +674,17 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
} }
obstack_printf (&obstack_for_string, obstack_printf (&obstack_for_string,
"]b4_rhs_value(%d, %d, ", effective_rule_length, n); "]b4_rhs_value(%d, %d, ",
effective_rule_length, n);
if (sym)
obstack_printf (&obstack_for_string, "%d, ", sym->content.sym->content->number);
else
obstack_sgrow (&obstack_for_string, "[], ");
obstack_quote (&obstack_for_string, type_name); obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")["); obstack_sgrow (&obstack_for_string, ")[");
if (0 < n) if (0 < n)
{ {
symbol_list *sym = symbol_list_n_get (effective_rule, n);
if (muscle_percent_define_ifdef ("api.value.automove") if (muscle_percent_define_ifdef ("api.value.automove")
&& sym->action_props.is_value_used) && sym->action_props.is_value_used)
complain (&dollar_loc, Wother, complain (&dollar_loc, Wother,