I6: Truncating a line of input

I recently rediscovered that some modern interpreters will truncate a question mark from the command line while others won’t. Frotz will not. This leads to differences in behavior for several Infocom games that allow for asking questions of the game itself. For instance, “WHAT IS A GRUE?” when typed into Zork 1 using Infocom’s DOS interpreter will work correctly by describing a grue. Run Zork 1 under Frotz and the game will complain that it doesn’t know what a “grue?” is. According to the Z-machine spec, the interpreter is not supposed to monkey with what’s typed on the command line and leave it to the game to make sense of it. However, Infocom did exactly that by truncating question marks from commands to allow questions followed by question marks to work. I’m going to deal with this in Frotz by having it truncate question marks for the games that expect it.

Then I started wondering about how to implement questions like this for Inform6. I’ve succeeded with this code:

[ WhatSub;
        if (noun provides what) {
                PrintOrRun(noun, what);
                return;
        }
        "I don't know what that is.";
];

Verb 'what'
        * 'is' 'a' noun         -> What
        * 'is' 'an' noun        -> What
        * 'is' noun             -> What;

So then, what’s the best way to check if the line ends in a question mark and remove it? One route I’m exploring is to hack Keyboard() in parserm.h and allow the author to turn on this behavior at compile time. Is there a way I can do this without altering the Library?

This is a typical job for the BeforeParsing hook. (Which became the “after reading a command” activity in I7, in case anyone’s curious.)

[ BeforeParsing   ix;
    #ifdef TARGET_ZCODE;
    for (ix=0 : ix<buffer->1 : ix++)
        if (buffer->(WORDSIZE+ix) == '?')
            buffer->(WORDSIZE+ix) = ' ';
    #ifnot;
    for (ix=0 : ix<buffer-->0 : ix++)
        if (buffer->(WORDSIZE+ix) == '?')
            buffer->(WORDSIZE+ix) = ' ';
    #endif;

    Tokenise__(buffer, parse);
];

This converts every question mark in the input to a space. That’s more than you asked for, but there’s no reason not to.

(Just checking the last typed character is easy. But you really want to check the last characters which are punctuation or whitespace, to catch inputs like " WHAT IS A GRUE? " – that’s easy for a player to type by accident. Given that, you might as well go all the way and check every character.)

As for the “what is…” grammar, see the DM4 chapter 32 – this is an example in the main text, and winds up in Ruins. (The code there explicitly does not handle question marks.)

Note that you don’t need to include the ‘a’ and ‘an’ cases in your grammar. The parser handles those automatically when parsing nouns.

1 Like

Hi,
rather than removing question mark, you can insert space before it:

[code][ BeforeParsing ix;
#ifdef TARGET_ZCODE;
for (ix=0 : ix1 : ix++)
if (buffer->(WORDSIZE+ix) == ‘?’)
LTI_Insert(WORDSIZE+ix++,’ ‘);
#ifnot;
for (ix=0 : ix0 : ix++)
if (buffer->(WORDSIZE+ix) == ‘?’)
LTI_Insert(WORDSIZE+ix++,’ ');
#endif;

Tokenise__(buffer, parse);

];

[ WhatSub;
if (noun provides what) {
PrintOrRun(noun, what);
return;
}
“I don’t know what that is.”;
];

Verb ‘what’
* ‘is’ noun -> What
* ‘is’ noun ‘?’ -> What[/code]

1 Like