Sunday, March 17, 2019

Chapter 10. ORPHAN-MERGE: Fix What Is Broken (part 1)

  • Arguments: None
  • Return: TRUE if orphaned command is corrected, FALSE if unable to correct the orphaned command

10.1 Introduction

Now that the major parts of the command have been identified (if they exist) and stored in ITBL, PARSER will first see if the given command corrects an orphaned command, a previous command that had ambiguous or missing necessary information. Originally, only nouns could be ambiguous. So the clarifying token had be an adjective. If an adjective could refer to more than one object in a location, an error was given.
For example, the user enters:

        IGNITE CANDLE

in an empty room. An orphaned command will be created as no indirect object is given (the candle needs to be ignited with something). The game will respond that it does not know what the user wants to ignite the touch with. This could be correct by then typing:

        TORCH or WITH THE TORCH

A new command IGNITE CANDLE WITH TORCH would be created and replace the previous command TORCH (or WITH THE TORCH) and then processed by PARSER.
In another example, a room contains a red card, red flower, and blue flower. If the command was

GET FLOWER

it would be considered ambiguous as it could be the red or blue flower. This could be corrected by typing:

RED

which would then lead to a newly created command:

GET RED FLOWER

If the command was

GET BLUE

GET-OBJECT which matches the token with an object would be able to figure out you meant the blue flower as there is only one object with the BLUE adjective. If the command was

GET RED

then GET-OBJECT would display a missing noun error as the game will not create an orphaned command from an ambiguous adjective.
Starting with HGTG, ambiguous adjectives could be used to create an orphaned command be later clarified with a noun. So the previous example would prompt the game to ask you for clarification on which RED object. These examples could be corrected by typing just CARD or FLOWER. So a clarifying noun could also refer to more than one object in the same room which would then trigger another orphan command. The game would then use the new information to match a single specific object and process the newly completed command.

10.2 Fixing Orphans with ORPHAN-MERGE

ORPHAN-MERGE is called by PARSER if the P-OFLAG has been set in 2 possible situations:
  • SYNTAX-CHECK is in unable to match even one syntax entries for the given verb because of a missing object clause
  • GET-OBJECT is matches more than one object for the given noun, adjective, or GWIM bit
Regardless of the outcome of the routine call, P-OFLAG will be cleared. So the user only has one chance to supply missing or clarifying tokens to an orphaned command. The orphaned command data is stored in OTBL (a mirror of ITBL) and OCLAUSE (a mirror of LEXV).
ORPHAN-MERGE first validates the given input through various checks. Only the missing or clarifying token is required. If any extra information is given (like prepositions or verbs) are given, then they must match the ones in the orphaned command to be accepted. ORPHAN-MERGE checks two aspects of the given input:
  • Verb - To be a valid response to an orphan command, the new input must have the same verb as the orphaned command or must have no verb. If the verb is different, the new input is likely a new command, and ORPHAN-MERGE will return with FALSE.
  • Number of noun clause - Only one noun clause is allowed to clarify an ambiguous or supply a missing noun clause. If two are given in the new input, then ORPHAN-MERGE will return with FALSE.

ORPHAN-MERGE then checks if the orphaned command has a missing clause by looking for $01 in the starting address of the noun clauses in OTBL. If both object clauses have starting addresses equal to $01, then only the direct object clause is processed. PARSER will then attempt to process this partially completed command and again discover this partially incomplete command can satisfy a syntax entry. If this new command is again unable to be matched with a syntax, it will be orphaned with the indirect object clause missing, The user can then input another clarifying command for the indirect object clause.
Once a missing object clause is found, ORPHAN-MERGE will see ensure that the preposition in the given input (if entered) matches the one in the orphaned command (stored in OTBL). Finally, the routine will copy the start and end addresses of the clarifying noun clause (the single adjective) from LEXV into the appropriate start and end address in OTBL. If the missing object clause is the indirect one, the number of noun clauses will also be set to 2. ORPHAN-MERGE will then skip checking if the given input clarifies an ambiguous noun.

10.3 Clearing up Ambiguity

If no missing noun clause found in OTBL (start address with $01), the given input could clarify an ambiguous noun. ORPHAN-MERGE checks if P-ACLAUSE was set (by GET-OBJECTS) to the element of the clause’s start address in OTBL with the ambiguous noun ($06 for direct object and $08 for indirect object clause). ORPHAN-MERGE will then proceed:
  • Check that there is only one noun clause in the given input. If there are more, than clear P-ACLAUSE and return with a FALSE.
  • Loop through the tokens in the noun clause indicated by P-ACLAUSE and check their word types.
  • If the token’s word type is an adjective, then temporarily save the vocabulary address of that token. If an adjective has already been found, the new one will override the old one. So only the last given adjective is used for clarification.
  • If the token’s word type is a noun, then ORPHAN-MERGE ensures that the token is the same as the ambiguous noun (P-NAM) or is “ONE”. In the above example, “BLUE ONE” or “RED FLOWER” are both valid for the ambiguous FLOWER. It will then stop checking tokens and call ACLAUSE-WIN (to create a new noun clause)
  • All other word types or mismatched nouns will cause ORPHAN-MERGE to stop checking tokens and return FALSE.
  • If no nouns are given after checking all the tokens in the given noun clause, ORPHAN-MERGE will also call ACLAUSE-WIN using the last found adjective in the given noun clause.
  • If no adjective is given after checking all those tokens, ORPHAN-MERGE will return false.
Once any missing noun clause is replaced or an ambiguous word is clarified, ORPHAN-MERGE will copy the data from OTBL into ITBL for PARSER to continue to processing as if the complete command had just been entered. So an clarified orphaned command will use tokens located in LEXV and OCLAUSE.

10.4 ACLAUSE-WIN

  • Arguments: Vocabulary address for Adjective
  • Return: TRUE
ACLAUSE-WIN setups up parameters for CLAUSE-COPY using ACLAUSE (element number of a clause’s start address such as $06), ACLAUSE + 1 (element number of clause’s end address such as $07), and the clarifying adjective. By setting the parse table that CLAUSE-COPY should use (CC-TBL) to OTBL, CLAUSE-COPY will copy the tokens from OCLAUSE back to OCLAUSE and insert a clarifying adjective before the ambiguous noun (P-NAM). The routine will also ensure the P-NCN is set to the correct number of noun clauses. ACLAUSE is cleared to indicate the ambiguous noun was clarified.

10.5 Using CLAUSE-COPY

  • Arguments: Element number of start address of clause in ITBL, Element number of end address of clause in ITBL, INSERT adjective (optional)
  • Return: TRUE
CLAUSE-COPY copies tokens from LEXV to the end of OCLAUSE using the addresses in one of the parse table (ITBL or OTBL) referred by a global variable (official name is not known). CLAUSE-COPY is called with two arguments, the element numbers that identify the start and end addresses for the noun clause to copy. These element values are $06 and $07 for the direct object clause or $08 and $09 for the indirect object clause. It will then append the requested tokens to the end of OCLAUSE.
  • Find the offset to the end of OCLAUSE using the value in element 0.
  • Calculate the new start address of the orphaned noun clause by finding the end address of OCLAUSE as it is the start address for the newly appended tokens.
  • Store this new start address in the appropriate element (start address for DO or IO clause) in OTBL ($06 or $08).
  • CLAUSE-COPY will repeatedly call CLAUSE-ADD to copy the tokens located in the requested noun clause to the end of OCLAUSE. These new tokens have their byte pointer to the input buffer and length set to zero.
  • If a clarifying token (usually an adjective) is given while copying these tokens, CLAUSE-COPY will check if the copied token matches the current ambiguous token, P-ANAM (a vocabulary address for the ambiguous noun). If a match is found, CLAUSE-ADD is called with the vocabulary address of ths clarifying token and a new token with the clarifying token is added to OCLAUSE. Then the P-ANAM is also added to OCLAUSE with CLAUSE-ADD.
  • Once all the remaining tokens in the requested noun clause are appended to OCLAUSE, CLAUSE-COPY will calculate the new end address of OCLAUSE and save it into the proper element (end address of noun clause) in OTBL.
Starting with Zork 1, there was a bug with this setup. Each time an orphaned noun clause was created, it was appended to OCLAUSE. Since the end of OCLAUSE was never reset back to $00, it was possible OCLAUSE would grow outside of its 100 byte size limit and spill over into the memory locations of other variables.  This was correct with Zork 3 by setting the size of OCLAUSE to zero in the OPRHAN routine.

10.6 CLAUSE-ADD

  • Arguments: Vocabulary address to token
  • Return: True
CLAUSE-ADD takes the given Vocabulary address and creates a new token add the end of OCLAUSE. Originally, the destination token buffer defaulted to OCLAUSE. In Moonmist, the P-CCTBL was used to stored the address of the destination token buffer in element 2. More information about P-CCTBL in Section 10.10. In Bureaucracy (and later Beyond Zork), the address of the destination token buffer was passed as the 2nd argument instead of using P-CCTBL.

No comments:

Post a Comment