[I6] clearing punctuation from a player's command

Hello everyone,

I’ve been using the following I7 code, or some variation on it, for a while now:

after reading the player's command:
	if the player's command matches the regular expression "^\p" or the player's command matches the regular expression "^<\*;>":
		say "Noted.";
		reject the player's command;
	if the player's command matches the regular expression "-":
		if dash-nag is false, say "(NOTE: you never need to use a dash, which can be replaced with a space. You should always be able to use either half of a dashed name.)";
		now dash-nag is true;
		now XX is the player's command;
		replace the text "-" in XX with " ";
		change the text of the player's command to XX;
	if the player's command matches the regular expression "'":
		if apost-nag is false, say "(NOTE: you never need to use an apostrophe, which is eliminated)";
		now apost-nag is true;
		now XX is the player's command;
		replace the text "'" in XX with "";
		change the text of the player's command to XX;

But Inform 7 is slow with regular expressions, especially with a debug build. This starts to matter once I have lots of tests to run. So with the help of Inform 6 entry point functions not recognized? I tried an I6 solution,

"Sandbox test" by Andrew Schultz

include (-

Global dashwarn = 0;
Global aposwarn = 0;

[
	isComment;
	if ((buffer->WORDSIZE == '*') || (buffer->WORDSIZE == ';'))
	{
		print "Comment noted.^^";
		rtrue;
	}
	rfalse;
];

[
	ParsePunc   ix iy li found;

	found = 0;

	for (ix=0 : ix<buffer-->0 : ix++)
		if (buffer->(WORDSIZE+ix) == '-')
		{
			buffer->(WORDSIZE+ix) = ' ';
			found++;
		}
	if ((found > 0) && (dashwarn == 0))
	{
		dashwarn = 1;
		print "NOTE: found a dash and replaced it with a space. You never need to use dashes in commands. ", (string) Story, " will replace dashes without nagging you in the future.^" ;
	}
	found = 0;
	iy = 0;
	for (ix=0 : ix<buffer-->0 : ix++)
	{
		if (iy ~= ix)
		{
			print "Shifting ", ix, " to ", iy , "^", ;
			buffer->(WORDSIZE+iy) = buffer->(WORDSIZE+ix);
		}
		if (buffer->(WORDSIZE+ix) == 39)
		{
			found++;
		}
		else
		{
			iy++;
		}
	}
	if (found > 0)
	{
		if (aposwarn == 0)
		{
			aposwarn = 1;
			print "NOTE: found an apostrophe and removed it. You never need to use apostrophes in commands. ", (string) Story, " will eliminate apostrophes without nagging you in the future.^";
		}
		buffer-->0 = iy;
		buffer->(WORDSIZE+iy) = 0;
		print "New command: ";
		for (ix = 0 : ix < buffer-->0 : ix++) print (char) buffer->(WORDSIZE+ix);
		print ".^";
	}
	VM_Tokenise(buffer, parse);
	rtrue;
];

-)

to decide whether is-comment: (- isComment() -)

to parse-continue: (- ParsePunc(); -)

this is the punctuation-munge rule:
	if is-comment, reject the player's command;
	parse-continue;

after reading a command:
	abide by the punctuation-munge rule;
	say "OK, now on to other parser checks ...";

I hope it’s relatively OK to ask for general tips here. A full code review is unnecessary … but I want to make sure I’m not making any big mistakes.

I’m less concerned with how to, say, delete a question mark as well as an apostrophe. (I can do that.) And I think I could also convert the code so it works for the ZMachine as well. I just wanted to keep it relatively simple. I’m just wondering if I’m committing any big or easily fixable I6 sins, and if so, how to fix them.

For instance, if anyone knows how to replace “39” with a non-magic number I’d be grateful. “’” and such, which I tried, didn’t work.

Thanks, whoever can help! I’m probably not going to post code review requests regularly, but since I will probably want to reuse this (or do general BeforeParsing/after reading a command work,) I wanted to ask.

I can answer this bit at least: it’s the ASCII value for the apostrophe. Normally you’d write a single character value in single-quotes, like '?', but that doesn’t work for the apostrophe itself, and I6 doesn’t have backslash escaping (in C you could write it as '\''). So 39 is the most readable way to write that.

(Or you could define Constant APOSTROPHE = 39; if you really want.)

1 Like

Actually I’m pretty sure you can write ''' in I6. I’ve got a lot of that in the French extension, and the DM4 seems to agree (see for example solution of exercice 94 at page 491).

I guess since you cannot have an empty character '', Inform understands that ''' is the apostrophe character. The issue is that it often wrecks the syntax colouring (which thinks you just closed and reopened the quotes).

2 Likes