Yay ZIL questions!
First, some background: when you use a noun phrase to refer to an object that isn’t present, Infocom’s games repeat the noun phrase in the message, like You can't see any shiny metal sword here.
ZILF’s library gives the generic message You don't see that here.
The message is printed by MATCH-NOUN-PHRASE
, which reads a structure generated by PARSE-NOUN-PHRASE
and tries to find a matching object in scope.
One approach to reproduce Infocom’s style would be to make PARSE-NOUN-PHRASE
store the span of words it used, and make MATCH-NOUN-PHRASE
print those words out of the input buffer using PRINT-WORD
. (Word length shouldn’t be an issue there, since the input buffer has the full command; the interpreter just ignores the ends of the words when searching the dictionary.)
That much is straightforward: add new fields for start and end word to the NOUN-PHRASE
structure (and update the routines that work with it). In PARSE-NOUN-PHRASE
, fill them in: the first word number is passed in as .WN
, and the last is .SPEC-WN
at the end of the routine. In MATCH-NOUN-PHRASE
, just loop between those numbers.
You might find that that doesn’t work during orphaning (a.k.a. disambiguation), because the original command is no longer in the buffer. I think you can see this bug in some Infocom games:
>get shiny metal sword
You can't see any shiny metal sword here.
>put shiny metal sword
What do you want to put the shiny metal sword in?
>lantern
You can't see any here.
You could try saving the buffer, but then you might run into the same problem when the second noun phrase (entered after the question) is the one that doesn’t match. ZILF never actually combines the two halves of the command in the same buffer.
So instead, during orphaning, you could fall back to printing an adjective/noun pair (from the NOUN-PHRASE
's YSPEC
), or a generic message if it isn’t clear which pair to print. I think that would still be consistent with at least some Infocom games. But that’s when you’re going to notice the 6 character limit.
The easy way around that limit is to add the <LONG-WORDS?>
directive, which generates the LONG-WORD-TABLE
mapping words to strings. If the word is listed in the table, PRINT
the corresponding string; otherwise PRINTB
the word.