Run-time problem P39 when changing the number of input words in Counterfeit Monkey

When that calculation is made, wn == 5. Consult_Grammar_1434() forcibly sets wn to 5 as its first operation, and the invoking routine SnippetIncludes() makes no effort to save it and restore a previous value.

As far as I can tell, the contents of parse and buffer are as desired (i.e. reflecting >ASK WHAT IS WORTH SEEING) when the action moves to ParseTokenStopped(). ParseTokenStopped() does not halt early because it sees the request as in-bounds for the current contents.

The particular logical fault seems to be within TryGivenObject(), which has the block:

!  If input has run out then always match, with only quality 0 (this saves
!  time).

	if (wn > num_words) {	! stale value of num_words for some reason
		if (nomatch) return 0;
	    if (indef_mode ~= 0)
	        dict_flags_of_noun = $$01110000;  ! Reject "plural" bit
	    MakeMatch(obj,0);
	    #Ifdef DEBUG;
	    if (parser_trace >= 5) print "    Matched (0)^";
	    #Endif; ! DEBUG
	    return 1;
	}

If the comparison condition is changed to

	if (wn > WordCount()) {	! check current parse array value

then the RTP does not occur.

Here’s the inclusion for 6M62:

TryGiveObject (modified)
Include (-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Parser.i6t: TryGivenObject
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====


[ TryGivenObject obj nomatch threshold k w j;
	#Ifdef DEBUG;
	if (parser_trace >= 5) print "    Trying ", (the) obj, " (", obj, ") at word ", wn, "^";
	#Endif; ! DEBUG

	if (nomatch && obj == 0) return 0;

! if (nomatch) print "*** TryGivenObject *** on ", (the) obj, " at wn = ", wn, "^";

	dict_flags_of_noun = 0;

!  If input has run out then always match, with only quality 0 (this saves
!  time).

	if (wn > WordCount()) {	! MODIFIED
		if (nomatch) return 0;
	    if (indef_mode ~= 0)
	        dict_flags_of_noun = $$01110000;  ! Reject "plural" bit
	    MakeMatch(obj,0);
	    #Ifdef DEBUG;
	    if (parser_trace >= 5) print "    Matched (zero)^";
	    #Endif; ! DEBUG
	    return 1;
	}

!  Ask the object to parse itself if necessary, sitting up and taking notice
!  if it says the plural was used:

	if (obj.parse_name~=0) {
	    parser_action = NULL; j=wn;
	    k = RunRoutines(obj,parse_name);
	    if (k > 0) {
	        wn=j+k;

	      .MMbyPN;

	        if (parser_action == ##PluralFound)
	            dict_flags_of_noun = dict_flags_of_noun | 4;

	        if (dict_flags_of_noun & 4) {
	            if (~~allow_plurals) k = 0;
	            else {
	                if (indef_mode == 0) {
	                    indef_mode = 1; indef_type = 0; indef_wanted = 0;
	                }
	                indef_type = indef_type | PLURAL_BIT;
	                if (indef_wanted == 0) indef_wanted = INDEF_ALL_WANTED;
	            }
	        }

	        #Ifdef DEBUG;
	        if (parser_trace >= 5) print "    Matched (", k, ")^";
	        #Endif; ! DEBUG
	        if (nomatch == false) MakeMatch(obj,k);
	        return k;
	    }
	    if (k == 0) jump NoWordsMatch;
	}

	! The default algorithm is simply to count up how many words pass the
	! Refers test:

	parser_action = NULL;

	w = NounWord();

	if (w == 1 && player == obj) { k=1; jump MMbyPN; }

	if (w >= 2 && w < 128 && (LanguagePronouns-->w == obj)) { k = 1; jump MMbyPN; }

	if (Refers(obj, wn-1) == 0) {
	    .NoWordsMatch;
	    if (indef_mode ~= 0) { k = 0; parser_action = NULL; jump MMbyPN; }
	    rfalse;
	}

	threshold = 1;
	dict_flags_of_noun = (w->#dict_par1) & $$01110100;
	w = NextWord();
	while (Refers(obj, wn-1)) {
		threshold++;
		if (w)
		   dict_flags_of_noun = dict_flags_of_noun | ((w->#dict_par1) & $$01110100);
		w = NextWord();
	}

	k = threshold;
	jump MMbyPN;
];

-) instead of "TryGivenObject" in "Parser.i6t".

None of the other code from previous posts matters for resolving the issue.

I think this does qualify as an actual bug… you could argue that it’s a consequence of the particular path to TryGivenObject(), but really the routine is relying on a cached value that it doesn’t cost much to refresh or read directly.

3 Likes