Interaction of variables q and c_style in WriteMultiClassGroup()?

I’m trying to understand one aspect of the intended function of WriteMultiClassGroup() (from ListWriter.i6t). Here’s the 6M62 version:

WriteMultiClassGroup
[ WriteMultiClassGroup cl memb depth partition_class_sizes pv q k2 l;
	! Save the style, because the activity below is allowed to change it
	q = c_style;
	if (c_style & INDENT_BIT ~= 0) PrintSpaces(2*(depth+c_margin));

	BeginActivity(GROUPING_TOGETHER_ACT, memb);

	if (ForActivity(GROUPING_TOGETHER_ACT, memb)) {
		c_style = c_style &~ NEWLINE_BIT; ! <-- disables NEWLINE_BIT if set by activity rule
	} else {
		pv = memb.list_together;
		if (TEXT_TY_IsSubstituted(pv) == false) {
			inventory_stage = 1;
			parser_one = memb; parser_two = depth + c_margin;
			if ((pv-->1)() == 1) jump Omit__Sublist2;
		} else if (pv) { ! <-- this block entered if "group X together as <text>" used
			! Set k2 to the number of objects covered by the group
			k2 = 0;
			for (l=0 : l<listing_size : l++) k2 = k2 + partition_class_sizes->(l+cl);
			EnglishNumber(k2); print " ";
			print (TEXT_TY_Say) pv;
			if (c_style & ENGLISH_BIT ~= 0) print " (";	! <-- c_style checked to decide whether to open parenthesized list
			if (c_style & INDENT_BIT ~= 0)  print ":^";
		}

		c_margin++;
		@push lt_value; @push listing_together; @push listing_size;
		
		lt_value = memb.list_together; listing_together = memb;
		#Ifdef DBLW; print "^^DOWN lt_value = ", lt_value, " listing_together = ", memb, "^^";
		@push DBLW_no_classes; @push DBLW_no_objs; #Endif;
		WriteListR(memb, depth, false); 
		#Ifdef DBLW; print "^^UP^^"; @pull DBLW_no_objs; @pull DBLW_no_classes; #Endif;

		@pull listing_size; @pull listing_together; @pull lt_value;
		c_margin--;
		
		pv = memb.list_together;
		if (TEXT_TY_IsSubstituted(pv) == false) {
			inventory_stage = 2;
			parser_one = memb; parser_two = depth+c_margin;
			(pv-->1)();
		} else if (LT_Compare(pv, EMPTY_TEXT_VALUE) ~= 0) {
			if (q & ENGLISH_BIT ~= 0) print ")";	! <-- q checked to decide whether to close parenthesized list?
		}
		.Omit__Sublist2;
	}
  
	EndActivity(GROUPING_TOGETHER_ACT, memb);

	! If the NEWLINE_BIT has been forced by the activity, act now
	! before it vanishes...
	if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0) ! <-- c_style already has NEWLINE_BIT unset above if activity interceded?
		new_line;

	! ...when the original style is restored again:
	c_style = q;
];

I can’t quite follow what’s going on with local variable q and global variable c_style. It seems like the code is treating the meaning of them differently than would be expected from the comments.

The sequence of events that I’m looking at specifically is:

  1. current value of c_style is saved to q at start of routine
  2. if a for grouping together... rule applies, then after that rule is done the NEWLINE_BIT of c_style is forcibly unset
  3. under certain conditions (such as those seen when a group together <desc> as <text> is used), the value of c_style is checked to decide whether to print an open parenthesis
  4. when deciding whether to print a close parenthesis, the value of q is checked (not c_style)
  5. at the end of the routine, the logic to decide whether to print a newline has a comment implying that the value of c_style should drive the decision but it is the value of q that seems to be checked by the condition

Items 3 and 4 seem to drive an issue that I ran into when trying to get an inventory listing in the following style:

You are carrying:
  five candies (three jelly beans, a dented candy corn and a chipped candy corn)

The example code:

Candies
"Candies"

Place is a room.

Candy is a kind of thing.
A jelly bean is a kind of candy.
A candy corn is a kind of candy.

To set candy style:
(-
	c_style = c_style & (~(NEWLINE_BIT+INDENT_BIT));
	c_style = c_style | (ENGLISH_BIT);
-).

Before listing contents:
	group candy together as "candies".

Before grouping together candies:
	set candy style.

After grouping together candies: [this rule should not be necessary?]
	say ")".

The player carries three jelly beans.
The player carries a candy corn called a dented candy corn.
The player carries a candy corn called a chipped candy corn.

Test me with "i".

By default, the close parenthesis is left out, so the output is:

You are carrying:
  five candies (three jelly beans, a dented candy corn and a chipped candy corn

The sample code compensates with a rule:

After grouping together candies:
	say ")".

but it does not seem like that rule should be necessary.

If in WriteMultiClassGroup() the line

			if (q & ENGLISH_BIT ~= 0) print ")";

is modified to

			if (c_style & ENGLISH_BIT ~= 0) print ")";	! MODIFIED

then the compensating rule is not needed.

2 Likes

I think this is definitely a typo/mistake in WriteMultiClassGroup, both for the reasons you’ve outlined (it seems to be inconsistent with the rest of the code as well as contrary to the commented explanation for the reason for q in the first place) as well as the anomalous behavior in your example.

If so, it goes back at least as far as 6F95, however, it was probably never noticed because, under normal circumstances ENGLISH_BIT would be unchanged during the execution of WriteMultiClassGroup and therefore, wouldn’t have different values when checking either c_style or q.

Your addition of the “set candy style” phrase, while perfectly valid, changes that.