home *** CD-ROM | disk | FTP | other *** search
- C SYNMCH-- SYNTAX MATCHER
- C
- C COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142
- C ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED
- C WRITTEN BY R. M. SUPNIK
- C
- C DECLARATIONS
- C
- C THIS ROUTINE DETAILS ON BIT 4 OF PRSFLG
- C
- LOGICAL FUNCTION SYNMCH
- IMPLICIT INTEGER(A-Z)
- LOGICAL SYNEQL,TAKEIT,DFLAG
- C
- C PARSER OUTPUT
- C
- LOGICAL PRSWON
- COMMON /PRSVEC/ PRSA,PRSI,PRSO,PRSWON,PRSCON
- C
- COMMON /DEBUG/ DBGFLG,PRSFLG
- C
- COMMON /ORPHS/ OFLAG,OACT,OSLOT,OPREP,ONAME
- COMMON /PV/ ACT,O1,O2,P1,P2
- COMMON /SYNTAX/VFLAG,DOBJ,DFL1,DFL2,DFW1,DFW2,
- 1 IOBJ,IFL1,IFL2,IFW1,IFW2
- COMMON /VRBVOC/ VVOC(950)
- COMMON /SYNFLG/ SDIR,SIND,SSTD,SFLIP,SDRIV,SVMASK
- COMMON /OBJFLG/ VABIT,VRBIT,VTBIT,VCBIT,VEBIT,VFBIT,VPMASK
- DATA R50MIN/1RA/
- C
- SYNMCH=.FALSE.
- D DFLAG=(PRSFLG.AND."20).NE.0
- J=ACT !SET UP PTR TO SYNTAX.
- DRIVE=0 !NO DEFAULT.
- DFORCE=0 !NO FORCED DEFAULT.
- QPREP=OFLAG.AND.OPREP !VALID ORPHAN PREP FLAG.
- 100 J=J+2 !FIND START OF SYNTAX.
- IF((VVOC(J).LE.0).OR.(VVOC(J).GE.R50MIN)) GO TO 100
- LIMIT=J+VVOC(J)+1 !COMPUTE LIMIT.
- J=J+1 !ADVANCE TO NEXT.
- C
- 200 CALL UNPACK(J,NEWJ) !UNPACK SYNTAX.
- D IF(DFLAG) TYPE 60,O1,P1,DOBJ,DFL1,DFL2
- D60 FORMAT(' SYNMCH INPUTS TO SYNEQL- ',5I7)
- SPREP=DOBJ.AND.VPMASK !SAVE EXPECTED PREP.
- IF(.NOT.SYNEQL(P1,O1,DOBJ,DFL1,DFL2)) GO TO 1000
- D IF(DFLAG) TYPE 60,O2,P2,IOBJ,IFL1,IFL2
- SPREP=IOBJ.AND.VPMASK !SAVE EXPECTED PREP.
- IF(SYNEQL(P2,O2,IOBJ,IFL1,IFL2)) GO TO 6000
- C
- C SYNTAX MATCH FAILS, TRY NEXT ONE.
- C
- IF(O2) 3000,500,3000 !IF O2=0, SET DFLT.
- 1000 IF(O1) 3000,500,3000 !IF O1=0, SET DFLT.
- 500 IF((QPREP.EQ.0).OR.(QPREP.EQ.SPREP)) DFORCE=J !IF PREP MCH.
- IF((VFLAG.AND.SDRIV).NE.0) DRIVE=J !IF DRIVER, RECORD.
- 3000 J=NEWJ
- IF(J.LT.LIMIT) GO TO 200 !MORE TO DO?
- C SYNMCH, PAGE 2
- C
- C MATCH HAS FAILED. IF DEFAULT SYNTAX EXISTS, TRY TO SNARF
- C ORPHANS OR GWIMS, OR MAKE NEW ORPHANS.
- C
- D IF(DFLAG) TYPE 20,DRIVE,DFORCE
- D20 FORMAT(' SYNMCH, DRIVE=',2I6)
- IF(DRIVE.EQ.0) DRIVE=DFORCE !NO DRIVER? USE FORCE.
- IF(DRIVE.EQ.0) GO TO 10000 !ANY DRIVER?
- CALL UNPACK(DRIVE,DFORCE) !UNPACK DFLT SYNTAX.
- C
- C TRY TO FILL DIRECT OBJECT SLOT IF THAT WAS THE PROBLEM.
- C
- IF(((VFLAG.AND.SDIR).EQ.0).OR.(O1.NE.0)) GO TO 4000
- C
- C FIRST TRY TO SNARF ORPHAN OBJECT.
- C
- O1=OFLAG.AND.OSLOT
- IF(O1.EQ.0) GO TO 3500 !ANY ORPHAN?
- IF(SYNEQL(P1,O1,DOBJ,DFL1,DFL2)) GO TO 4000
- C
- C ORPHAN FAILS, TRY GWIM.
- C
- 3500 O1=GWIM(DOBJ,DFW1,DFW2) !GET GWIM.
- D IF(DFLAG) TYPE 30,O1
- D30 FORMAT(' SYNMCH- DO GWIM= ',I6)
- IF(O1.GT.0) GO TO 4000 !TEST RESULT.
- CALL ORPHAN(-1,ACT,0,DOBJ.AND.VPMASK,0) !FAILS, ORPHAN.
- CALL RSPEAK(623)
- RETURN
- C
- C TRY TO FILL INDIRECT OBJECT SLOT IF THAT WAS THE PROBLEM.
- C
- 4000 IF(((VFLAG.AND.SIND).EQ.0).OR.(O2.NE.0)) GO TO 6000
- O2=GWIM(IOBJ,IFW1,IFW2) !GWIM.
- D IF(DFLAG) TYPE 40,O2
- D40 FORMAT(' SYNMCH- IO GWIM= ',I6)
- IF(O2.GT.0) GO TO 6000
- IF(O1.EQ.0) O1=OFLAG.AND.OSLOT
- CALL ORPHAN(-1,ACT,O1,DOBJ.AND.VPMASK,0)
- CALL RSPEAK(624)
- RETURN
- C
- C TOTAL CHOMP
- C
- 10000 CALL RSPEAK(601) !CANT DO ANYTHING.
- RETURN
- C SYNMCH, PAGE 3
- C
- C NOW TRY TO TAKE INDIVIDUAL OBJECTS AND
- C IN GENERAL CLEAN UP THE PARSE VECTOR.
- C
- 6000 IF((VFLAG.AND.SFLIP).EQ.0) GO TO 5000 !FLIP?
- J=O1 !YES.
- O1=O2
- O2=J
- C
- 5000 PRSA=VFLAG.AND.SVMASK !GET VERB.
- PRSO=O1 !GET DIR OBJ.
- PRSI=O2 !GET IND OBJ.
- IF(.NOT.TAKEIT(PRSO,DOBJ)) RETURN !TRY TAKE.
- IF(.NOT.TAKEIT(PRSI,IOBJ)) RETURN !TRY TAKE.
- SYNMCH=.TRUE.
- D IF(DFLAG) TYPE 50,SYNMCH,PRSA,PRSO,PRSI,ACT,O1,O2
- D50 FORMAT(' SYNMCH- RESULTS ',L1,6I7)
- RETURN
- C
- END
- C UNPACK- UNPACK SYNTAX SPECIFICATION, ADV POINTER
- C
- C DECLARATIONS
- C
- SUBROUTINE UNPACK(OLDJ,J)
- IMPLICIT INTEGER(A-Z)
- C
- COMMON /VRBVOC/ VVOC(950)
- C
- COMMON /SYNFLG/ SDIR,SIND,SSTD,SFLIP,SDRIV,SVMASK
- COMMON /OBJFLG/ VABIT,VRBIT,VTBIT,VCBIT,VEBIT,VFBIT,VPMASK
- COMMON /SYNTAX/ VFLAG,DOBJ,DFL1,DFL2,DFW1,DFW2,
- 1 IOBJ,IFL1,IFL2,IFW1,IFW2
- INTEGER SYN(11)
- EQUIVALENCE (SYN(1),VFLAG)
- C
- DO 10 I=1,11 !CLEAR SYNTAX.
- SYN(I)=0
- 10 CONTINUE
- C
- VFLAG=VVOC(OLDJ)
- J=OLDJ+1
- IF((VFLAG.AND.SDIR).EQ.0) RETURN !DIR OBJECT?
- DFL1=-1 !ASSUME STD.
- DFL2=-1
- IF((VFLAG.AND.SSTD).EQ.0) GO TO 100 !STD OBJECT?
- DFW1=-1 !YES.
- DFW2=-1
- DOBJ=VABIT+VRBIT+VFBIT
- GO TO 200
- C
- 100 DOBJ=VVOC(J) !NOT STD.
- DFW1=VVOC(J+1)
- DFW2=VVOC(J+2)
- J=J+3
- IF((DOBJ.AND.VEBIT).EQ.0) GO TO 200 !VBIT = VFWIM?
- DFL1=DFW1 !YES.
- DFL2=DFW2
- C
- 200 IF((VFLAG.AND.SIND).EQ.0) RETURN !IND OBJECT?
- IFL1=-1 !ASSUME STD.
- IFL2=-1
- IOBJ=VVOC(J)
- IFW1=VVOC(J+1)
- IFW2=VVOC(J+2)
- J=J+3
- IF((IOBJ.AND.VEBIT).EQ.0) RETURN !VBIT = VFWIM?
- IFL1=IFW1 !YES.
- IFL2=IFW2
- RETURN
- C
- END
- C SYNEQL- TEST FOR SYNTAX EQUALITY
- C
- C DECLARATIONS
- C
- LOGICAL FUNCTION SYNEQL(PREP,OBJ,SPREP,SFL1,SFL2)
- IMPLICIT INTEGER(A-Z)
- C
- C OBJECTS
- C
- COMMON /OBJCTS/ OLNT,ODESC1(220),ODESC2(220),ODESCO(220),
- 1 OACTIO(220),OFLAG1(220),OFLAG2(220),OFVAL(220),
- 2 OTVAL(220),OSIZE(220),OCAPAC(220),OROOM(220),
- 3 OADV(220),OCAN(220),OREAD(220)
- C
- COMMON /OBJFLG/ VABIT,VRBIT,VTBIT,VCBIT,VEBIT,VFBIT,VPMASK
- C
- IF(OBJ.EQ.0) GO TO 100 !ANY OBJECT?
- SYNEQL=(PREP.EQ.(SPREP.AND.VPMASK)).AND.
- 1 (((SFL1.AND.OFLAG1(OBJ)).OR.
- 2 (SFL2.AND.OFLAG2(OBJ))).NE.0)
- RETURN
- C
- 100 SYNEQL=(PREP.EQ.0).AND.(SFL1.EQ.0).AND.(SFL2.EQ.0)
- RETURN
- C
- END
- C TAKEIT- PARSER BASED TAKE OF OBJECT
- C
- C DECLARATIONS
- C
- LOGICAL FUNCTION TAKEIT(OBJ,SFLAG)
- IMPLICIT INTEGER(A-Z)
- C
- COMMON /OBJFLG/ VABIT,VRBIT,VTBIT,VCBIT,VEBIT,VFBIT,VPMASK
- COMMON /STAR/ MBASE,STRBIT
- C
- C GAME STATE
- C
- LOGICAL TELFLG
- COMMON /PLAY/ WINNER,HERE,TELFLG
- COMMON /STATE/ MOVES,DEATHS,RWSCOR,MXSCOR,MXLOAD,
- 1 LTSHFT,BLOC,MUNGRM,HS,EGSCOR,EGMXSC
- C
- C OBJECTS
- C
- COMMON /OBJCTS/ OLNT,ODESC1(220),ODESC2(220),ODESCO(220),
- 1 OACTIO(220),OFLAG1(220),OFLAG2(220),OFVAL(220),
- 2 OTVAL(220),OSIZE(220),OCAPAC(220),OROOM(220),
- 3 OADV(220),OCAN(220),OREAD(220)
- C
- COMMON /OFLAGS/ VISIBT,READBT,TAKEBT,DOORBT,TRANBT,FOODBT,
- 1 NDSCBT,DRNKBT,CONTBT,LITEBT,VICTBT,BURNBT,FLAMBT,
- 2 TOOLBT,TURNBT,ONBT
- COMMON /OFLAGS/ FINDBT,SLEPBT,SCRDBT,TIEBT,CLMBBT,ACTRBT,
- 1 WEAPBT,FITEBT,VILLBT,STAGBT,TRYBT,NOCHBT,OPENBT,
- 2 TCHBT,VEHBT,SCHBT
- C
- C ADVENTURERS
- C
- COMMON /ADVS/ ALNT,AROOM(4),ASCORE(4),AVEHIC(4),
- 1 AOBJ(4),AACTIO(4),ASTREN(4),AFLAG(4)
- C TAKEIT, PAGE 2
- C
- TAKEIT=.FALSE. !ASSUME LOSES.
- IF((OBJ.EQ.0).OR.(OBJ.GT.STRBIT)) GO TO 4000 !NULL/STARS WIN.
- ODO2=ODESC2(OBJ) !GET DESC.
- X=OCAN(OBJ) !GET CONTAINER.
- IF((X.EQ.0).OR.((SFLAG.AND.VFBIT).EQ.0)) GO TO 500
- IF((OFLAG2(X).AND.OPENBT).NE.0) GO TO 500
- CALL RSPSUB(566,ODO2) !CANT REACH.
- RETURN
- C
- 500 IF((SFLAG.AND.VRBIT).EQ.0) GO TO 1000 !SHLD BE IN ROOM?
- IF((SFLAG.AND.VTBIT).EQ.0) GO TO 2000 !CAN BE TAKEN?
- C
- C SHOULD BE IN ROOM (VRBIT NE 0) AND CAN BE TAKEN (VTBIT NE 0)
- C
- IF(SCHLST(0,0,HERE,0,0,OBJ).LE.0) GO TO 4000 !IF NOT, OK.
- C
- C ITS IN THE ROOM AND CAN BE TAKEN.
- C
- IF(((OFLAG1(OBJ).AND.TAKEBT).NE.0).AND.
- 1 ((OFLAG2(OBJ).AND.TRYBT).EQ.0)) GO TO 3000
- C
- C NOT TAKEABLE. IF WE CARE, FAIL.
- C
- IF((SFLAG.AND.VCBIT).EQ.0) GO TO 4000 !IF NO CARE, RETURN.
- CALL RSPSUB(445,ODO2)
- RETURN
- C
- C 1000-- IT SHOULD NOT BE IN THE ROOM.
- C 2000-- IT CANT BE TAKEN.
- C
- 2000 IF((SFLAG.AND.VCBIT).EQ.0) GO TO 4000 !IF NO CARE, RETURN
- 1000 IF(SCHLST(0,0,HERE,0,0,OBJ).LE.0) GO TO 4000
- CALL RSPSUB(665,ODO2)
- RETURN
- C TAKEIT, PAGE 3
- C
- C OBJECT IS IN THE ROOM, CAN BE TAKEN BY THE PARSER,
- C AND IS TAKEABLE IN GENERAL. IT IS NOT A STAR.
- C TAKING IT SHOULD NOT HAVE SIDE AFFECTS.
- C IF IT IS INSIDE SOMETHING, THE CONTAINER IS OPEN.
- C THE FOLLOWING CODE IS LIFTED FROM SUBROUTINE TAKE.
- C
- 3000 IF(OBJ.NE.AVEHIC(WINNER)) GO TO 3500 !TAKE VEHICLE?
- CALL RSPEAK(672)
- RETURN
- C
- 3500 IF(((X.NE.0).AND.(OADV(X).EQ.WINNER)).OR.
- 1 ((WEIGHT(0,OBJ,WINNER)+OSIZE(OBJ)).LE.MXLOAD))
- 2 GO TO 3700
- CALL RSPEAK(558) !TOO BIG.
- RETURN
- C
- 3700 CALL NEWSTA(OBJ,559,0,0,WINNER) !DO TAKE.
- OFLAG2(OBJ)=OFLAG2(OBJ).OR.TCHBT !TOUCHED.
- CALL SCRUPD(OFVAL(OBJ))
- OFVAL(OBJ)=0
- C
- 4000 TAKEIT=.TRUE. !SUCCESS.
- RETURN
- C
- END
- C GWIM- GET WHAT I MEAN IN AMBIGOUS SITUATIONS
- C
- C DECLARATIONS
- C
- INTEGER FUNCTION GWIM(SFLAG,SFW1,SFW2)
- IMPLICIT INTEGER(A-Z)
- LOGICAL TAKEIT,NOCARE
- C
- COMMON /OBJFLG/ VABIT,VRBIT,VTBIT,VCBIT,VEBIT,VFBIT,VPMASK
- COMMON /STAR/ MBASE,STRBIT
- C
- C GAME STATE
- C
- LOGICAL TELFLG
- COMMON /PLAY/ WINNER,HERE,TELFLG
- C
- C OBJECTS
- C
- COMMON /OBJCTS/ OLNT,ODESC1(220),ODESC2(220),ODESCO(220),
- 1 OACTIO(220),OFLAG1(220),OFLAG2(220),OFVAL(220),
- 2 OTVAL(220),OSIZE(220),OCAPAC(220),OROOM(220),
- 3 OADV(220),OCAN(220),OREAD(220)
- C
- COMMON /OFLAGS/ VISIBT,READBT,TAKEBT,DOORBT,TRANBT,FOODBT,
- 1 NDSCBT,DRNKBT,CONTBT,LITEBT,VICTBT,BURNBT,FLAMBT,
- 2 TOOLBT,TURNBT,ONBT
- COMMON /OFLAGS/ FINDBT,SLEPBT,SCRDBT,TIEBT,CLMBBT,ACTRBT,
- 1 WEAPBT,FITEBT,VILLBT,STAGBT,TRYBT,NOCHBT,OPENBT,
- 2 TCHBT,VEHBT,SCHBT
- C
- C ADVENTURERS
- C
- COMMON /ADVS/ ALNT,AROOM(4),ASCORE(4),AVEHIC(4),
- 1 AOBJ(4),AACTIO(4),ASTREN(4),AFLAG(4)
- C GWIM, PAGE 2
- C
- GWIM=-1 !ASSUME LOSE.
- AV=AVEHIC(WINNER)
- NOBJ=0
- NOCARE=(SFLAG.AND.VCBIT).EQ.0
- C
- C FIRST SEARCH ADVENTURER
- C
- IF((SFLAG.AND.VABIT).NE.0)
- 1 NOBJ=FWIM(SFW1,SFW2,0,0,WINNER,NOCARE)
- IF((SFLAG.AND.VRBIT).NE.0) GO TO 100
- 50 GWIM=NOBJ
- RETURN
- C
- C ALSO SEARCH ROOM
- C
- 100 ROBJ=FWIM(SFW1,SFW2,HERE,0,0,NOCARE)
- IF(ROBJ) 500,50,200 !TEST RESULT.
- C
- C ROBJ > 0
- C
- 200 IF((AV.EQ.0).OR.(ROBJ.EQ.AV).OR.
- 1 ((OFLAG2(ROBJ).AND.FINDBT).NE.0)) GO TO 300
- IF(OCAN(ROBJ).NE.AV) GO TO 50 !UNREACHABLE? TRY NOBJ
- 300 IF(NOBJ.NE.0) RETURN !IF AMBIGUOUS, RETURN.
- IF(.NOT.TAKEIT(ROBJ,SFLAG)) RETURN !IF UNTAKEABLE, RETURN
- GWIM=ROBJ
- 500 RETURN
- C
- END
-