Monday, March 11, 2019

Chapter 8. PARSER: New Commands and Routines (Part 2)

8.5 OOPS!

The OOPS command was an important innovation in the era before copy and paste were invented. Previously any commands with errors would have to be completely re-typed with the correction. This was especially painful for long or multiple commands. The user could correct any errors with
OOPS <replacement token>
If an unknown token is found, various values are calculated and stored in OOPS-TABLE:
Word 0
Word 1
Word 2
Word 3
Offset to unknown token in AGAIN-LEXV
Offset to start of command with unknown token in AGAIN-LEXV
Length of all token data  in command with the unknown token
Offset to byte after the end of OOPS-INBUF
PARSER will grab the Vocabulary address of the replacement token (after OOPS) and replace it with the empty address in the unknown token’s entry in AGAIN-LEXV. Only the first token after OOPS is checked. An error message is display if more tokens are given. INBUF-ADD is called to appended the replacement token to the end of the OOPS-INBUF. That routine will also store the replacement token’s length and updated pointer in OOPS-INBUF in the unknown token’s entry in AGAIN-LEXV. Finally the  modified OOPS-INBUF and AGAIN-LEXV are copied back into the INBUF and LEXV, respectively. PARSER then resumes parsing the command as it normally does. If there is another unknown word error in this just correct command, another OOPS can be used to correct the next error. This can go on until all the errors are fixed.
This feature has been present in all version 3 games since Sorcerer-R18, and all version 4 and 5 games since its introduction.

8.6 INBUF-ADD

  • Arguments: length of replacement token, ptr of replacement token in INBUF, offset of unknown token in OOPS-INBUF
  • Returns: TRUE

INBUF-ADD is slightly more sophisticated. The characters for the referred token in the first two arguments in appended to the end of OOPS-INBUF. The pointer to the end of OOPS-INBUF is retrieved from the OOPS-TABLE (or calculated using the data from the last token if it is not in the OOPS-TABLE). The length of this replacement token and pointer to it in OOPS-INBUF are copied back into the unknown token’s entry in AGAIN-LEXV.

8.7 UNDO

Finally an UNDO command was introduced with Beyond Zork which would restore the game state before the last command was executed. While this capability was available since version 1 of Z-machines, it was never implemented because of the need for more internal memory (a limited quantity back then) or having to constantly save the data onto an external memory storage device, likely a disk drive, which would slow the execution of the game down. But the requirements of XZIP called for ZIP emulators with higher memory capacities, the necessary game state data could be saved into a different part of the internal memory. Only Beyond Zork and Sherlock had this function.
The saving of the current game state was done in the PARSER routine after the check for a GO command. The save_undo operation is used to copy the contents of dynamic memory (everything before the Syntax data) which is essentially the header information, all OBJECT data, global variables, tables, and buffers. Also the call stack is saved. If the player uses the UNDO command, it would call a separate routine that would attempt to restore the saved gate state data  and continue with the execution of the command after the save_undo operation in PARSER. If an error occurs, the appropriate error message is displayed.

8.8 Update: Other Minor Changes in PARSER

EZIP and XZIP games only added slight modifications to PARSER. Most of these revolved around setting or clearing certain global variables such as XNAM. Others would search for unimportant tokens such as “please” and skip over them.

8.9 Update: ReplaceToken routine


With the advent of  the AGAIN command in AMFV and its use of the AGAIN-LEXV buffer, the replacing of tokens in PARSER and CLAUSE required changes in both those buffers. So a new routine was created, ReplaceToken. But it also including a way to copy the length and pointer information for the token before the replaced one into the location of the replaced one. The dictionary address for the replaced token will then be modified as normal.

No comments:

Post a Comment