Reliably finding the first non-dictionary word

I’m trying to use some old code I once swiped from somewhere to tell me which word in a player’s command was the first unrecognized one. However, in a few cases this straightforward-seeming routine is producing odd results. Here’s the test case.

x is room. Bob is here. A cup is here.

To decide which number is the position of first bad word: (- GetFirstNonDictWord() -).

[From DM4: NextWordStopped()
Finds the next dictionary word in the player’s input, that is, the word at position wn in the input, moving the word number wn on by one. (The first word is at position 1.) Routine returns The dictionary value, or 0 if the word is not in the dictionary, or the constant THEN1__WD if the ‘‘word’’ was a full stop, or the constant COMMA_WORD if it was a comma, or −1 if the word stream has run out.]

Include (-

[ GetFirstNonDictWord myword   twn;
	twn=wn;
	wn = 1;
	myword = 0;
	while (myword ~= -1) {
		myword = NextWordStopped();
		if (myword == 0) {
			myword=wn-1;
			wn=twn;
			return wn-1;
		}
	}
	myword=wn-1;
	wn=twn;
	return -1;	
];

-).

First before printing a parser error: showme position of first bad word. Every turn: showme position of first bad word.

test me with "look / asdf / get asdf / take inventory asdf / insert me into asdf / look asdf / look look look look asdf / x bob / x bob's cup / get bob's asdf".

This produces the following output… anomalies highlighted in bold:

In the first case, why is the second “look” being identified as not a dictionary word? Something to do with the difference between actions and objects, maybe?

In the second case, why is “bob’s” correctly identified as the first unrecognized word when the noun is valid, but skipped over in the bolded case when the noun is invalid? I thought for a minute this might have something to do with some sneaky internal code automatically recognizing the word “bob’s” if a “bob” is in scope, but it behaves the same even if there’s no Bob in the game.

Update: okay, so in the second case it seems to be the difference between the verbs “x” and “get”. With “x,” “Bob’s” is always successfully identified; with “get”, it’s not. Hrm.

Could it be that the parser during this phase simply ignores repetitions, so that “look look look” is considered one word, while “jump look” would be two?

“look look” by itself gives you the “You can’t see any such thing” error, so I think the second “look” may in fact be unrecognized because the parser is expecting a noun and not a verb there.

Have you thought about going through the parse buffer manually? I don’t know what NextWordStopped() does, but the parse buffer should be reliable. (Though you will have to account for all custom word delimiters.)

Surely you want return myword; in place of return wn-1; no?

Yeah, what EmacsUser said. You’re returning the original wn value (-1).

Oh hey, that does the trick. Thanks!! I guess the fact that it seemed to be working most of the time fooled me into not squinting at that bit closely enough.

I think this might be the same bug I fixed when I updated Unknown Word Error. I thought I had submitted the update to the I7 site but maybe I never did, because it’s not there. Maybe I was waiting to hear from Neil Cerutti. It was a few weeks ago and I don’t remember what I did, but I think I’m actually using this in my WIP with good results:

eyeballsun.org/i/Unknown%20Word%20Error.i7x