As I add some test cases to the Dialog compiler, I came across this bit of weirdness.
This is an example from chapter 3 of the manual:
(program entry point)
(collect words)
Hello, world!
(into $List)
The list is: $List (line)
Printing each word:
(exhaust) {
*($Word is one of $List)
$Word
}
The expected output, per the documentation, is:
The list is: [hello , world!]
Printing each word: hello, world!
However, the most recent official release produces this on Z-machine:
The list is: [hello, world!]
Printing each word: hello, world!
What’s going on? Well, if we add a (space 1) to the printing part:
Printing each word: hello , world!
So on the Z-machine, printing a comma suppresses space before it, even when it’s being printed as part of a list.
Would you consider this a bug worth fixing in the compiler? Or should we adjust the documentation to match the compiler?
If we want to change the Z-machine’s behavior, this happens in R_PRINT_VALUE in runtime_z.c: the routine that prints a Dialog value for debugging. Right now, there are two flags that can be passed to this routine: $01 means to print a + between the recognized and unrecognized parts of a dictionary word, $02 means to print a @ before a dictionary word. When printing a list, this routine recurses on each element of the list, masking out the $02 flag as it does.
The result is that the routine thinks it’s printing ,, a bare comma in output, rather than @,, a dictionary word for debugging. At label 3 in the code, it checks if it’s printing a single character ., ,, ;, or ), and flag $01 is not set. If so, it skips the call to R_SYNC_SPACE that would print a space before it.
Except…flag $01 should be set, at this point. The recursive part masks out flag $02 but leaves flag $01 intact. So what’s going on here?
Ech, this is going to be a pain. But I think it confirms it’s definitely a compiler bug, not a documentation bug. I’ll put it on the bug tracker tomorrow.
My first thought is that the recursive part (when printing a list) should always set the $01 flag, since lists should only be printed for debugging, so there’s no reason to hide the +. Maybe that’ll fix the whole thing. We’ll see!
This seems correct behavior to me, since lists may appear in normal text (in the source code), and I think an author would be surprised if a comma suddenly gets a space before it.
I think what @Draconis is saying is that the space is being suppressed even when the author tries to explicitly add one in, which I would argue would never be expected behavior.
Yeah, this happens specifically when you’re outputting a list for debugging—it’s the same mechanism that prints object names as #object and variables as $ and so on, not something you want the player to see.
And in this context, I think making it clear how many elements are in the list (by separating them all with spaces) is more important than good typography.
Not as far as I can tell. I found this bug when I was setting up the test suite, and running it with Linus’s compiler and debugger (to set the standard to compare our compiler and debugger against). As part of this, it highlights any differences between running it on Z-machine and debugger, and one of those is that the debugger prints [hello , world!] and the Z-machine prints [hello, world!].
That’s why I’m checking if we want to change the compiler’s behavior, or change the documentation. Either way, it’s a bug.
That’s true, but again, how often are lists being printed directly for actual gameplay instead of debugging? The standard library has a predicate to print a list of words more prettily, which handles punctuation automatically.