trinity icon indicating copy to clipboard operation
trinity copied to clipboard

GENERIC-WIRE-F doesn't work as intended

Open eriktorbjorn opened this issue 5 years ago • 6 comments

One trick Trinity uses in several places is that if multiple objects match the one you've typed, the GENERIC routine for those objects is set up to pick the object that matches P-IT-OBJECT, if any of them does. Usually (at least so far) it's just two objects, but with GENERIC-WIRE-F it gets a bit more complicated because it has four. This is how it does it:

	 <SET LEN <GET .TABLE 0>>
	 <COND (<ZERO? .LEN>
		<RFALSE>)
	       (<INTBL? ,P-IT-OBJECT <REST .TABLE 1> .LEN>
		<RETURN ,P-IT-OBJECT>)
	       (T
		<RFALSE>)>>

But it doesn't work. It doesn't match the "it" wire, no matter what.

<INTBL? ,P-IT-OBJECT <REST .TABLE 1> .LEN> compiles to

        ADD TABLE,1 >STACK
        INTBL? P-IT-OBJECT,STACK,LEN >STACK \FALSE

I think that means that it passes the table, minus the first byte as parameter to INTBL?. But TABLE is a word table. If I change it to <REST .TABLE 2> it works. Unfortunately, REST isn't documented in any of the original ZIL manuals, as far as I can tell, but I assume this is a bug in Trinity, not a bug in ZILF or Frotz.

eriktorbjorn avatar Sep 08 '20 14:09 eriktorbjorn

The "MDL Programming Language" (https://mdl-language.readthedocs.io/en/latest/07-structured-objects/#713-rest-1) states: <REST structured fix> evaluates to structured without its first fix elements. fix is optional, 1 by default.

From "The Zork Implementation Language" (can be found on the http://www.ifwiki.org/index.php/PAX_USB_Drive file zil.doc):

Table Operations

        GET     V       2       Returns the nth (argument-2) element of
                                argument-1
        PUT     V       3       Set the nth (argument-2) element of argument-1
                                to argument-3
        GETB    V       2)      Like NTH and PUT, but return the nth byte
        PUTB    V       3)      of a table, rather than the nth word of a table
        SIZEPT  V       1       Returns the size of a property table, which
                                was returned by GETPT.

        REST    V       2       Rest the table (argument-1) by argument-2
                                BYTES!  To rest a table by one element, the
                                second argument should be 2.
        BACK    V       2       Inverse of REST.

ZoBoRf avatar Sep 09 '20 06:09 ZoBoRf

Ok, so my guess that <REST .TABLE 1> should be <REST .TABLE 2> seems to be correct, then? I thought I had checked the PAX drive stuff, but I guess the "REST" got lost in all the "RESTART" and "RESTORE" noise when I searched for it. Thanks for the pointer!

eriktorbjorn avatar Sep 09 '20 07:09 eriktorbjorn

Ok, so my guess that <REST .TABLE 1> should be <REST .TABLE 2> seems to be correct, then? I thought I had checked the PAX drive stuff, but I guess the "REST" got lost in all the "RESTART" and "RESTORE" noise when I searched for it. Thanks for the pointer!

If .TABLE is interpreted as a table of 2-byte entries, then you need in ZIL <READ .TABLE 2> to snipp the first off. The MDL semantics differs here. Try to use 2 instead of 1 in the original code.

ZoBoRf avatar Sep 09 '20 07:09 ZoBoRf

At least in the case I tested, the table was a WORD table. I already tried changing it to <REST .TABLE 2> and it worked. I just wanted to make sure it was the Right Thing™ to do.

eriktorbjorn avatar Sep 09 '20 07:09 eriktorbjorn

From "The Zork Implementation Language" (can be found on the http://www.ifwiki.org/index.php/PAX_USB_Drive file zil.doc):

Table Operations

        GET     V       2       Returns the nth (argument-2) element of
                                argument-1
        PUT     V       3       Set the nth (argument-2) element of argument-1
                                to argument-3
        GETB    V       2)      Like NTH and PUT, but return the nth byte
        PUTB    V       3)      of a table, rather than the nth word of a table
        SIZEPT  V       1       Returns the size of a property table, which
                                was returned by GETPT.

        REST    V       2       Rest the table (argument-1) by argument-2
                                BYTES!  To rest a table by one element, the
                                second argument should be 2.
        BACK    V       2       Inverse of REST.

FWIW, I've extracted this file from the PAX USB archives and uploaded it to https://pastebin.com/htGaEuey

taradinoc avatar Sep 10 '20 04:09 taradinoc

Thanks. That's the same information ZoBoRf posted earlier, though. I found out about the PAX drive fairly recently, and spent some time following the instructions on how to decode it. But somehow I missed that zil.doc file.

By the way, just to rule out Frotz and ZILF bugs once and for all here - not that I really thought there were any - I have now verified that the same bug happens in the official Trinity release, using Infocom's DOS interpreter.

eriktorbjorn avatar Sep 10 '20 13:09 eriktorbjorn