"PARSER for WITNESS
Copyright (C) 1983 Infocom, Inc. All rights reserved."
"Parser global variable convention: All parser globals will
begin with 'P-'. Local variables are not restricted in any
way.
"
<SETG SIBREAKS ".,\"!?">
"<GLOBAL ALWAYS-LIT <>>"
"<GLOBAL GWIM-DISABLE <>>"
<GLOBAL PRSA 0>
<GLOBAL PRSI 0>
<GLOBAL PRSO 0>
<GLOBAL P-TABLE 0>
<GLOBAL P-ONEOBJ 0>
The grammar line found when the most recent command was parsed. (Except for simple direction commands, which are a special case.) See the Grammar tab.
<GLOBAL P-SYNTAX 0>
<GLOBAL P-CCSRC 0>
<GLOBAL P-LEN 0>
<GLOBAL P-DIR 0>
WINNER is the actor in the current command.
WINNER is usually PLAYER, but for a command like PHONG, GO EAST it briefly shifts to the named NPC.
<GLOBAL WINNER 0>
<GLOBAL P-LEXV <ITABLE BYTE 120>>
<GLOBAL P-INBUF <ITABLE BYTE 100>>
<GLOBAL P-CONT <>>
<GLOBAL P-IT-OBJECT <>>
<GLOBAL P-IT-LOC <>>
<GLOBAL P-HIM-HER <>>
<GLOBAL P-HIM-HER-LOC <>>
<ROUTINE THIS-IS-S-HE (PERSON)
<GLOBAL P-OFLAG <>>
<GLOBAL P-MERGED <>>
<GLOBAL P-ACLAUSE <>>
<GLOBAL P-ANAM <>>
<GLOBAL P-AADJ <>>
<CONSTANT P-PHRLEN 3>
<CONSTANT P-ORPHLEN 7>
<CONSTANT P-RTLEN 3>
<CONSTANT P-LEXWORDS 1>
<CONSTANT P-LEXSTART 1>
<CONSTANT P-LEXELEN 2>
<CONSTANT P-WORDLEN 4>
<CONSTANT P-PSOFF 4>
<CONSTANT P-P1OFF 5>
<CONSTANT P-P1BITS 3>
<CONSTANT P-ITBLLEN 9>
<GLOBAL P-ITBL <TABLE 0 0 0 0 0 0 0 0 0 0>>
<GLOBAL P-OTBL <TABLE 0 0 0 0 0 0 0 0 0 0>>
<GLOBAL P-VTBL <TABLE 0 0 0 0>>
<GLOBAL P-NCN 0>
<CONSTANT P-VERB 0>
<CONSTANT P-VERBN 1>
<CONSTANT P-PREP1 2>
<CONSTANT P-PREP1N 3>
<CONSTANT P-PREP2 4>
<CONSTANT P-PREP2N 5>
<CONSTANT P-NC1 6>
<CONSTANT P-NC1L 7>
<CONSTANT P-NC2 8>
<CONSTANT P-NC2L 9>
<GLOBAL QUOTE-FLAG <>>
Unlike other Infocom games (and nearly all modern IF), The Witness pays attention to some adverbs. You can EXAMINE an object, or you can EXAMINE it CAREFULLY or CLOSELY. The parser will also take note of the words QUIETLY, SLOWLY, QUICKLY, and BRIEFLY.
EXAMINE CAREFULLY takes several minutes instead of one, but in a few cases it reveals more information. See CLOCK-F, MONICA-TABLE-F.
You can also COMPARE things CAREFULLY to verify a match. STILES-SHOES-F, MUDDY-SHOES-F, INSIDE-GUN-F, SPOOL-OF-WIRE-F.
<GLOBAL P-ADVERB <>>
" Grovel down the input finding the verb, prepositions, and noun clauses.
If the input is <direction> or <walk> <direction>, fall out immediately
setting PRSA to ,V?WALK and PRSO to <direction>. Otherwise, perform
all required orphaning, syntax checking, and noun clause lookup."
<GLOBAL P-PROMPT "What should you, the detective, do now?">
<ROUTINE I-PROMPT-1 ()
<RFALSE>>
<ROUTINE I-PROMPT-2 ()
<TELL CR "(Aren't you getting tired of seeing ">
<TELL
"\"What next?\" and \"You are now in the ....\"? From here on, the
prompt will be much shorter.)" CR>
<COND (<VERB? WAIT WAIT-FOR WAIT-UNTIL> <CRLF>)>
<DISABLE <INT I-PROMPT-2>>
<RFALSE>)>>
<GLOBAL X-IS-LISTENING <>>
<ROUTINE PARSER ("AUX" (PTR ,P-LEXSTART) WRD (VAL 0) (VERB <>) (OF-FLAG <>)
LEN (DIR <>) (NW 0) (LW 0) NUM SCNT (CNT -1))
<REPEAT ()
<COND (<G? <SET CNT <+ .CNT 1>> ,P-ITBLLEN> <RETURN>)
<COND (<NOT <VERB? TELL>> <CRLF>)>)
(T
<REPEAT ()
<COND (<L? <SET SCNT <- .SCNT 1>> 0> <RETURN>)
(T <CRLF>)>>
<TELL "(" D ,QCONTEXT " is listening.)" CR>)>
<TELL ">">
<COND (<0? ,P-LEN> <TELL "What?" CR> <RFALSE>)
(<OR <EQUAL? <SET WRD<GET ,P-LEXV .PTR>> ,W?WHY ,W?HOW ,W?WHEN>
<EQUAL? .WRD ,W?IS ,W?DID ,W?ARE>>
<TELL
"(Sorry, but this program can't handle questions like that.
You should stick to questions like \"WHAT IS ...\" and \"WHERE IS ....\"
Maybe you'd like to review your instruction manual.)"
CR>
<RFALSE>)>
<REPEAT ()
<RETURN>)
(<OR <SET WRD <GET ,P-LEXV .PTR>>
<COND (<AND <==? .WRD ,W?TO>
<EQUAL? .VERB ,ACT?TELL ,ACT?ASK>>
<SET WRD ,W?QUOTE>)
(<AND <==? .WRD ,W?THEN>
<NOT .VERB>>
<SET WRD ,W?QUOTE>)>
<COND (<AND <EQUAL? .WRD ,W?PERIOD>
<EQUAL? .LW ,W?MRS ,W?MR >>
<SET LW 0>)
(<OR <EQUAL? .WRD ,W?THEN ,W?PERIOD>
<EQUAL? .WRD ,W?QUOTE>>
<COND (<EQUAL? .WRD ,W?QUOTE>
<RETURN>)
(<AND <SET VAL
,PS?DIRECTION
,P1?DIRECTION>>
<OR <==? .LEN 1>
<AND <==? .LEN 2><==? .VERB ,ACT?WALK>>
<AND <EQUAL? <SET NW
,W?THEN
,W?QUOTE>
<G? .LEN 2>>
<AND <EQUAL? .NW ,W?PERIOD>
<G? .LEN 1>>
<==? .LEN 2>
<EQUAL? .NW ,W?QUOTE>>
<AND <G? .LEN 2>
<EQUAL? .NW ,W?COMMA ,W?AND>>>>
<SET DIR .VAL>
<COND (<EQUAL? .NW ,W?COMMA ,W?AND>
,W?THEN>)>
<COND (<NOT <G? .LEN 2>>
<RETURN>)>)
(<AND <SET VAL <WT? .WRD ,PS?VERB ,P1?VERB>>
<OR <NOT .VERB>
<EQUAL? .VERB ,ACT?WHAT>>>
<SET VERB .VAL>
<SET NUM
<+ <* .PTR 2> 2>>>>
(<OR <SET VAL <WT? .WRD ,PS?PREPOSITION 0>>
<AND <OR <EQUAL? .WRD ,W?ONE ,W?A>
>>
<COND (<AND <G? ,P-LEN 1 >
,W?OF>
<NOT <EQUAL? .VERB
,ACT?ACCUSE
,ACT?MAKE>>
<0? .VAL>
<NOT <EQUAL? .WRD
,W?ONE ,W?A>>>
<SET OF-FLAG T>)
(<AND <NOT <0? .VAL>>
<EQUAL? <GET ,P-LEXV <+ .PTR 2>>
,W?THEN ,W?PERIOD>>>
<TELL
"(I found more than two nouns in that sentence!)" CR>
<RFALSE>)
(T
<OR <SET PTR <CLAUSE .PTR .VAL .WRD>>
<RFALSE>>
<COND (<L? .PTR 0>
<RETURN>)>)>)
(<==? .WRD ,W?CLOSELY>
Unlike other Infocom games (and nearly all modern IF), The Witness pays attention to some adverbs. See P-ADVERB.
(<OR <EQUAL? .WRD
,W?CAREFULLY ,W?QUIETLY>
<EQUAL? .WRD
,W?SLOWLY ,W?QUICKLY ,W?BRIEFLY>>
(<EQUAL? .WRD ,W?OF>
<COND (<OR <NOT .OF-FLAG>
<EQUAL?
,W?PERIOD ,W?THEN>>
<RFALSE>)
(T
<SET OF-FLAG <>>)>)
(<WT? .WRD ,PS?BUZZ-WORD>)
(T
<RFALSE>)>)
(T
<RFALSE>)>
<SET LW .WRD>
<COND (.DIR <SETG PRSA ,V?WALK> <SETG PRSO .DIR> <RETURN T>)>
T)>>
<ROUTINE WT? (PTR BIT "OPTIONAL" (B1 5) "AUX" (OFFSET ,P-P1OFF) TYP)
<COND (<BTST <SET TYP <GETB .PTR ,P-PSOFF>> .BIT>
<COND (<G? .B1 4> <RTRUE>)
(T
<COND (<NOT <==? .TYP .B1>> <SET OFFSET <+ .OFFSET 1>>)>
<GETB .PTR .OFFSET>)>)>>
<ROUTINE CLAUSE (PTR VAL WRD "AUX" OFF NUM (ANDFLG <>) (FIRST?? T) NW (LW 0))
#DECL ((PTR VAL OFF NUM) FIX (WRD NW) <OR FALSE FIX TABLE>
(ANDFLG FIRST??) <OR ATOM FALSE>)
<SET OFF <* <- ,P-NCN 1> 2>>
<COND (<NOT <==? .VAL 0>>
<COND (<EQUAL? <GET ,P-LEXV .PTR> ,W?THE ,W?A ,W?AN>
<REPEAT ()
<RETURN -1>)>
<COND (<OR <SET WRD <GET ,P-LEXV .PTR>>
<COND (<0? ,P-LEN> <SET NW 0>)
<COND (<AND <==? .WRD ,W?OF>
,ACT?ACCUSE ,ACT?MAKE>>
<SET WRD ,W?WITH>)>
<COND (<AND <EQUAL? .WRD ,W?PERIOD>
<EQUAL? .LW ,W?MRS ,W?MR >>
<SET LW 0>)
(<EQUAL? .WRD ,W?AND ,W?COMMA> <SET ANDFLG T>)
(<EQUAL? .WRD ,W?ONE>
<COND (<==? .NW ,W?OF>
(<OR <EQUAL? .WRD ,W?THEN ,W?PERIOD>
<AND <WT? .WRD ,PS?PREPOSITION>
<NOT .FIRST??>>>
<+ .NUM 1>
(<AND .ANDFLG
<OR
<SET PTR <- .PTR 4>>
<PUT ,P-LEXV <+ .PTR 2> ,W?THEN>
,PS?ADJECTIVE
,P1?ADJECTIVE>
<NOT <==? .NW 0>>
(<AND <NOT .ANDFLG>
<NOT <EQUAL? .NW ,W?BUT ,W?EXCEPT>>
<NOT <EQUAL? .NW ,W?AND ,W?COMMA>>>
<+ .NUM 1>
<REST ,P-LEXV <* <+ .PTR 2> 2>>>
<RETURN .PTR>)
(T <SET ANDFLG <>>)>)
(<OR <WT? .WRD ,PS?ADJECTIVE>
<WT? .WRD ,PS?BUZZ-WORD>>)
(<WT? .WRD ,PS?PREPOSITION> T)
(T
<RFALSE>)>)
<SET LW .WRD>
<SET FIRST?? <>>
<ROUTINE NUMBER? (PTR "AUX" CNT BPTR CHR (SUM 0) (TIM <>))
<SET CNT <GETB <REST ,P-LEXV <* .PTR 2>> 2>>
<SET BPTR <GETB <REST ,P-LEXV <* .PTR 2>> 3>>
<REPEAT ()
<COND (<L? <SET CNT <- .CNT 1>> 0> <RETURN>)
(T
<COND (<==? .CHR 58>
<SET TIM .SUM>
<SET SUM 0>)
(<G? .SUM 9999> <RFALSE>)
(<AND <L? .CHR 58> <G? .CHR 47>>
<SET SUM <+ <* .SUM 10> <- .CHR 48>>>)
(T <RFALSE>)>
<SET BPTR <+ .BPTR 1>>)>>
<COND (<G? .SUM 9999> <RFALSE>)
(.TIM
<COND (<G? .TIM 23> <RFALSE>)
(<G? .TIM 19> T)
(<G? .TIM 12> <RFALSE>)
(<G? .TIM 7> T)
(T <SET TIM <+ 12 .TIM>>)>
<SET SUM <+ .SUM <* .TIM 60>>>)>
,W?INTNUM>
<GLOBAL P-NUMBER 0>
<ROUTINE ORPHAN-MERGE ("AUX" (CNT -1) TEMP VERB BEG END (ADJ <>) WRD)
#DECL ((CNT TEMP VERB) FIX (BEG END) <PRIMTYPE VECTOR> (WRD) TABLE)
<COND
<RFALSE>)
<RFALSE>)
<0? .TEMP>>
<COND (.ADJ
(T
(T <RFALSE>)>)
<0? .TEMP>>
(T <RFALSE>)>)
<COND
(T
<REPEAT ()
<COND (<==? .BEG .END>
<COND (.ADJ
<RETURN>)
(T
<RFALSE>)>)
(<AND <NOT .ADJ>
<BTST <GETB <SET WRD <GET .BEG 0>> ,P-PSOFF>
,PS?ADJECTIVE>>
<SET ADJ .WRD>)
(<OR <BTST <GETB .WRD ,P-PSOFF> ,PS?OBJECT>
<==? .WRD ,W?ONE>>
<COND (<NOT <EQUAL? .WRD ,P-ANAM ,W?ONE>> <RFALSE>)
(T
<RETURN>)>)>
<REPEAT ()
<RTRUE>)
T>
<ROUTINE ACLAUSE-WIN (ADJ)
<RTRUE>>
<ROUTINE WORD-PRINT (CNT BUF)
<REPEAT ()
<COND (<DLESS? CNT 0> <RETURN>)
(ELSE
<SET BUF <+ .BUF 1>>)>>>
<GLOBAL UNKNOWN-MSGS
<PLTABLE
<PTABLE "(I don't know the word \""
"\".)">
<PTABLE "(Sorry, but the word \""
"\" is not in the vocabulary that you can use.)">
<PTABLE "(You don't need to use the word \""
"\" to solve this mystery.)">
<PTABLE "(Sorry, but the program doesn't recognize the word \""
"\".)">>>
<ROUTINE UNKNOWN-WORD (PTR "AUX" BUF MSG)
#DECL ((PTR BUF) FIX)
<TELL <GET .MSG 0>>
<TELL <GET .MSG 1> CR>
<ROUTINE CANT-USE (PTR "AUX" BUF)
#DECL ((PTR BUF) FIX)
<TELL "(Sorry, but you can't use the word \"">
<TELL "\" in that sense.)" CR>
<GLOBAL P-SLOCBITS 0>
<CONSTANT P-SYNLEN 8>
<CONSTANT P-SBITS 0>
<CONSTANT P-SPREP1 1>
<CONSTANT P-SPREP2 2>
<CONSTANT P-SFWIM1 3>
<CONSTANT P-SFWIM2 4>
<CONSTANT P-SLOC1 5>
<CONSTANT P-SLOC2 6>
<CONSTANT P-SACTION 7>
<CONSTANT P-SONUMS 3>
<ROUTINE SYNTAX-CHECK ("AUX" SYN LEN NUM OBJ (DRIVE1 <>) (DRIVE2 <>)
PREP VERB)
#DECL ((DRIVE1 DRIVE2) <OR FALSE <PRIMTYPE VECTOR>>
(SYN) <PRIMTYPE VECTOR> (LEN NUM VERB PREP) FIX
(OBJ) <OR FALSE OBJECT>)
<TELL "(I couldn't find a verb in that sentence!)" CR>
<RFALSE>)>
<SET SYN <GET ,VERBS <- 255 .VERB>>>
<SET LEN <GETB .SYN 0>>
<SET SYN <REST .SYN>>
<REPEAT ()
<COND (<G? ,P-NCN .NUM> T)
(<AND <NOT <L? .NUM 1>>
<SET DRIVE1 .SYN>)
<COND (<AND <==? .NUM 2> <==? ,P-NCN 1>>
<SET DRIVE2 .SYN>)
<RTRUE>)>)>
<COND (<DLESS? LEN 1>
<COND (<OR .DRIVE1 .DRIVE2> <RETURN>)
(T
<TELL
"(Sorry, but English is my second language. Please rephrase that.)"
CR>
<RFALSE>)>)
<COND (<AND .DRIVE1
<SET OBJ
(<AND .DRIVE2
<SET OBJ
(<EQUAL? .VERB ,ACT?FIND ,ACT?WHAT>
<TELL "(Sorry, but I can't answer that question.)" CR>
<RFALSE>)
(T
<TELL "(What do you want to ">)
(T
<TELL
"(Your request was incomplete. Next time, say what you want " D ,WINNER
" to ">)>
<COND (.DRIVE2
<TELL "?)" CR>)
(T
<TELL ".)" CR>)>
<RFALSE>)>>
<ROUTINE VERB-PRINT ("AUX" TMP)
<COND (<==? .TMP 0> <TELL "tell">)
<PRINTB <GET .TMP 0>>)
(T
<ROUTINE ORPHAN (D1 D2 "AUX" (CNT -1))
#DECL ((D1 D2) <OR FALSE <PRIMTYPE VECTOR>>)
<REPEAT ()
<COND (.D1
(.D2
<ROUTINE CLAUSE-PRINT (BPTR EPTR "OPTIONAL" (THE? T))
<ROUTINE BUFFER-PRINT (BEG END CP "AUX" (NOSP <>) WRD (FIRST?? T) (PN <>))
#DECL ((BEG END) <PRIMTYPE VECTOR> (CP) <OR FALSE ATOM>)
<REPEAT ()
<COND (<==? .BEG .END> <RETURN>)
(T
<COND (.NOSP <SET NOSP <>>)
(T <TELL " ">)>
<COND (<==? <SET WRD <GET .BEG 0>> ,W?PERIOD>
<SET NOSP T>)
(<==? .WRD ,W?MRS> <TELL "Mrs."> <SET PN T>)
(<==? .WRD ,W?MR> <TELL "Mr."> <SET PN T>)
(<OR <EQUAL? .WRD ,W?LINDER ,W?MONICA ,W?PHONG>
<EQUAL? .WRD ,W?STILES ,W?DUFFY>>
<SET PN T>)
(T
<COND (<AND .FIRST?? <NOT .PN> .CP>
<TELL "the ">)>
(<AND <==? .WRD ,W?IT>
(<AND <EQUAL? .WRD ,W?HIM ,W?HER>
(T
<GETB .BEG 3>>)>
<SET FIRST?? <>>)>)>
<ROUTINE CAPITALIZE (PTR)
<PRINTC <- <GETB ,P-INBUF <GETB .PTR 3>> 32>>
<WORD-PRINT <- <GETB .PTR 2> 1> <+ <GETB .PTR 3> 1>>>
<ROUTINE PREP-PRINT (PREP "AUX" WRD)
#DECL ((PREP) FIX)
<COND (<NOT <0? .PREP>>
<TELL " ">
<COND (<==? .WRD ,W?AGAINST> <TELL "against">)
(T <PRINTB .WRD>)>
<==? ,W?DOWN .WRD>>
<TELL " on">)>)>>
<ROUTINE CLAUSE-COPY (BPTR EPTR "OPTIONAL" (INSERT <>) "AUX" BEG END)
#DECL ((BPTR EPTR) FIX (BEG END) <PRIMTYPE VECTOR>
(INSERT) <OR FALSE TABLE>)
.BPTR
<REPEAT ()
<COND (<==? .BEG .END>
.EPTR
2>>>
<RETURN>)
(T
<COND (<AND .INSERT <==? ,P-ANAM <GET .BEG 0>>>
<ROUTINE CLAUSE-ADD (WRD "AUX" PTR)
#DECL ((WRD) TABLE (PTR) FIX)
<ROUTINE PREP-FIND (PREP "AUX" (CNT 0) SIZE)
#DECL ((PREP CNT SIZE) FIX)
<SET SIZE <* <GET ,PREPOSITIONS 0> 2>>
<REPEAT ()
<COND (<IGRTR? CNT .SIZE> <RFALSE>)
(<==? <GET ,PREPOSITIONS .CNT> .PREP>
<RETURN <GET ,PREPOSITIONS <- .CNT 1>>>)>>>
<ROUTINE SYNTAX-FOUND (SYN)
#DECL ((SYN) <PRIMTYPE VECTOR>)
<GLOBAL P-GWIMBIT 0>
<ROUTINE GWIM (GBIT LBIT PREP "AUX" OBJ)
#DECL ((GBIT LBIT) FIX (OBJ) OBJECT)
<TELL "(">
<COND (<NOT <0? .PREP>>
<TELL " ">
)>
<COND (<AND <FSET? .OBJ ,PERSON>
<TELL "the " <GETP .OBJ ,P?XDESC> ")" CR>)
(T <TELL D .OBJ ")" CR>)>
.OBJ)>)
<ROUTINE SNARF-OBJECTS ("AUX" PTR)
#DECL ((PTR) <OR FIX <PRIMTYPE VECTOR>>)
<RTRUE>>
<ROUTINE BUT-MERGE (TBL "AUX" LEN BUTLEN (CNT 1) (MATCHES 0) OBJ NTBL)
#DECL ((TBL NTBL) TABLE (LEN BUTLEN MATCHES) FIX (OBJ) OBJECT)
<REPEAT ()
<COND (<DLESS? LEN 0> <RETURN>)
(T
<SET MATCHES <+ .MATCHES 1>>)>
<SET CNT <+ .CNT 1>>>
.NTBL>
<GLOBAL P-NAM <>>
<GLOBAL P-XNAM <>>
<GLOBAL P-ADJ <>>
<GLOBAL P-XADJ <>>
<GLOBAL P-ADJN <>>
<GLOBAL P-XADJN <>>
<GLOBAL P-PRSO <ITABLE NONE 50>>
<GLOBAL P-PRSI <ITABLE NONE 50>>
<GLOBAL P-BUTS <ITABLE NONE 50>>
<GLOBAL P-MERGE <ITABLE NONE 50>>
<GLOBAL P-OCLAUSE <ITABLE NONE 50>>
<GLOBAL P-MATCHLEN 0>
<GLOBAL P-GETFLAGS 0>
<CONSTANT P-ALL 1>
<CONSTANT P-ONE 2>
<CONSTANT P-INHIBIT 4>
<GLOBAL P-CSPTR <>>
<GLOBAL P-CEPTR <>>
<ROUTINE SNARFEM (PTR EPTR TBL "AUX" (AND <>) (BUT <>) LEN WV WRD NW)
#DECL ((TBL) TABLE (PTR EPTR) <PRIMTYPE VECTOR> (AND) <OR ATOM FALSE>
(BUT) <OR FALSE TABLE> (WV) <OR FALSE FIX>)
<SET WRD <GET .PTR 0>>
<REPEAT ()
<COND (<==? .PTR .EPTR> <RETURN <GET-OBJECT <OR .BUT .TBL>>>)
(T
<COND
(<EQUAL? .WRD ,W?BUT ,W?EXCEPT>
(<EQUAL? .WRD ,W?A ,W?ONE>
<COND (<==? .NW ,W?OF>
(T
<AND <0? .NW> <RTRUE>>)>)
(<AND <EQUAL? .WRD ,W?AND ,W?COMMA>
<NOT <EQUAL? .NW ,W?AND ,W?COMMA>>>
T)
(<WT? .WRD ,PS?BUZZ-WORD>)
(<EQUAL? .WRD ,W?AND ,W?COMMA>)
(<==? .WRD ,W?OF>
(<AND <SET WV <WT? .WRD ,PS?ADJECTIVE ,P1?ADJECTIVE>>
(<WT? .WRD ,PS?OBJECT ,P1?OBJECT>
<COND (<NOT <==? .PTR .EPTR>>
<SET WRD .NW>)>>>
<CONSTANT SH 128>
<CONSTANT SC 64>
<CONSTANT SIR 32>
<CONSTANT SOG 16>
<CONSTANT STAKE 8>
<CONSTANT SMANY 4>
<CONSTANT SHAVE 2>
<ROUTINE GET-OBJECT (TBL
"OPTIONAL" (VRB T)
"AUX" BITS LEN XBITS TLEN (GCHECK <>) (OLEN 0) OBJ)
#DECL ((TBL) TABLE (XBITS BITS TLEN LEN) FIX (GWIM) <OR FALSE FIX>
(VRB GCHECK) <OR ATOM FALSE>)
<COND (.VRB
<TELL "(I couldn't find enough nouns in that sentence!)" CR>)>
<RFALSE>)>
<PROG ()
(T
<NOT <0? .LEN>>>
<COND (<NOT <==? .LEN 1>>
<PUT .TBL 1 <GET .TBL <RANDOM .LEN>>>
<TELL "(How about the ">
<PRINTD <GET .TBL 1>>
<TELL "?)" CR>)>
(<OR <G? .LEN 1>
<SET OLEN .LEN>
<AGAIN>)
(T
<COND (<0? .LEN> <SET LEN .OLEN>)>
<VERB? ASK-ABOUT ASK-CONTEXT-ABOUT TELL-ME WHAT
GIVE SGIVE ASK-FOR ASK-CONTEXT-FOR TAKE
FIND SEARCH SEARCH-OBJECT-FOR
MAKE DISEMBARK>
<SET OBJ <GET .TBL <+ .TLEN 1>>>
<SET OBJ <APPLY <GETP .OBJ ,P?GENERIC> .OBJ>>>
<PUT .TBL 1 .OBJ>
<RTRUE>)
(.VRB
<TELL
"(I couldn't find enough nouns in that sentence!)"
CR>)>
<RFALSE>)>)
(<AND <0? .LEN> .GCHECK>
<COND (.VRB
<RTRUE>)
(T <TELL "(It's too dark to see!)" CR>)>)>
<RFALSE>)
(<0? .LEN> <SET GCHECK T> <AGAIN>)>
<RTRUE>>>
<ROUTINE MOBY-FIND (TBL "AUX" FOO LEN)
<SET FOO <FIRST? ,ROOMS>>
<REPEAT ()
<COND (<NOT .FOO> <RETURN>)
(T
<SET FOO <NEXT? .FOO>>)>>
<COND (<EQUAL? <SET LEN <GET .TBL ,P-MATCHLEN>> 0>
<COND (<EQUAL? <SET LEN <GET .TBL ,P-MATCHLEN>> 0>
<COND (<EQUAL? <SET LEN <GET .TBL ,P-MATCHLEN>> 1>
.LEN>
<GLOBAL P-MOBY-FOUND <>>
<ROUTINE WHICH-PRINT (TLEN LEN TBL "AUX" OBJ RLEN)
<SET RLEN .LEN>
<TELL "(Which">
<TELL " do you mean,">
<REPEAT ()
<SET TLEN <+ .TLEN 1>>
<SET OBJ <GET .TBL .TLEN>>
<TELL " " D .OBJ>
<COND (<==? .LEN 2>
<COND (<NOT <==? .RLEN 2>> <TELL ",">)>
<TELL " or">)
(<G? .LEN 2> <TELL ",">)>
<COND (<L? <SET LEN <- .LEN 1>> 1>
<TELL "?)" CR>
<RETURN>)>>>
<ROUTINE GLOBAL-CHECK (TBL "AUX" LEN RMG RMGL (CNT 0) OBJ OBITS FOO)
#DECL ((TBL) TABLE (RMG) <OR FALSE TABLE> (RMGL CNT) FIX (OBJ) OBJECT)
<SET RMGL <- <PTSIZE .RMG> 1>>
<REPEAT ()
<COND (<THIS-IT? <SET OBJ <GETB .RMG .CNT>> .TBL>
<COND (<IGRTR? CNT .RMGL> <RETURN>)>>)>
<SET RMGL <- </ <PTSIZE .RMG> 4> 1>>
<SET CNT 0>
<REPEAT ()
<COND (<==? ,P-NAM <GET .RMG <* .CNT 2>>>
<GET .RMG <+ <* .CNT 2> 1>>>
<SET FOO
<PUT .FOO 0 <GET ,P-NAM 0>>
<PUT .FOO 1 <GET ,P-NAM 1>>
<RETURN>)
(<IGRTR? CNT .RMGL> <RETURN>)>>)>
<COND (<VERB? EXAMINE FIND FOLLOW DROP LOOK-INSIDE
SEARCH SEARCH-OBJECT-FOR THROUGH WALK-TO>
<ROUTINE DO-SL (OBJ BIT1 BIT2 "AUX" BITS)
#DECL ((OBJ) OBJECT (BIT1 BIT2 BITS) FIX)
(T
(T <RTRUE>)>)>>
<CONSTANT P-SRCBOT 2>
<CONSTANT P-SRCTOP 0>
<CONSTANT P-SRCALL 1>
<ROUTINE SEARCH-LIST (OBJ TBL LVL "AUX" FLS )
#DECL ((OBJ ) <OR FALSE OBJECT> (TBL) TABLE (LVL) FIX (FLS) ANY)
<COND (<SET OBJ <FIRST? .OBJ>>
<REPEAT ()
<COND (<AND <OR <NOT <==? .LVL ,P-SRCTOP>>
<FIRST? .OBJ>
>
<SET FLS
<SEARCH-LIST .OBJ .TBL
<COND (<SET OBJ <NEXT? .OBJ>>) (T <RETURN>)>>)>>
<ROUTINE THIS-IT? (OBJ TBL "AUX" SYNS)
<- </ <PTSIZE .SYNS> 2> 1>>>>
<RFALSE>)
<RFALSE>)
<RFALSE>)>
<RTRUE>>
<ROUTINE OBJ-FOUND (OBJ TBL "AUX" PTR)
#DECL ((OBJ) OBJECT (TBL) TABLE (PTR) FIX)
<PUT .TBL <+ .PTR 1> .OBJ>
<ROUTINE TAKE-CHECK ()
<ROUTINE ITAKE-CHECK (TBL BITS "AUX" PTR OBJ TAKEN)
#DECL ((TBL) TABLE (BITS PTR) FIX (OBJ) OBJECT
(TAKEN) <OR FALSE FIX ATOM>)
<REPEAT ()
<COND (<L? <SET PTR <- .PTR 1>> 0> <RETURN>)
(T
<SET OBJ <GET .TBL <+ .PTR 1>>>
<COND (<NOT <HELD? .OBJ>>
<SET TAKEN T>)
<SET TAKEN <>>)
(<AND <BTST .BITS ,STAKE>
<SET TAKEN <>>)
(T <SET TAKEN T>)>
<COND (<AND .TAKEN <BTST .BITS ,SHAVE>>
<TELL "(You don't have">
<COND (<EQUAL? .OBJ
<TELL " that!)" CR>)
(T
<TELL " " D .OBJ"!)"CR>)>
<RFALSE>)
(<AND <NOT .TAKEN>
<TELL "(taken)" CR>)>)>)>>)
(T)>>
<ROUTINE MANY-CHECK ("AUX" (LOSS <>) TMP)
#DECL ((LOSS) <OR FALSE FIX>)
<SET LOSS 1>)
<SET LOSS 2>)>
<COND (.LOSS
<TELL "(You can't use multiple ">
<COND (<==? .LOSS 2> <TELL "in">)>
<TELL "direct objects with \"">
<COND (<0? .TMP> <TELL "tell">)
<PRINTB <GET .TMP 0>>)
(T
<TELL "\"!)" CR>
<RFALSE>)
(T)>>
<ROUTINE ZMEMQ (ITM TBL "OPTIONAL" (SIZE -1) "AUX" (CNT 1))
<COND (<NOT .TBL> <RFALSE>)>
<COND (<NOT <L? .SIZE 0>> <SET CNT 0>)
(ELSE <SET SIZE <GET .TBL 0>>)>
<REPEAT ()
<COND (<==? .ITM <GET .TBL .CNT>> <RTRUE>)
(<IGRTR? CNT .SIZE> <RFALSE>)>>>
<ROUTINE ZMEMQB (ITM TBL SIZE "AUX" (CNT 0))
#DECL ((ITM) ANY (TBL) TABLE (SIZE CNT) FIX)
<REPEAT ()
<COND (<==? .ITM <GETB .TBL .CNT>> <RTRUE>)
(<IGRTR? CNT .SIZE> <RFALSE>)>>>
<ROUTINE PRSO-PRINT ("AUX" PTR)
>
<ROUTINE PRSI-PRINT ("AUX" PTR)
>