np3.for 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. C SYNMCH-- SYNTAX MATCHER
  2. C
  3. C COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142
  4. C ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED
  5. C WRITTEN BY R. M. SUPNIK
  6. C
  7. C DECLARATIONS
  8. C
  9. C THIS ROUTINE DETAILS ON BIT 4 OF PRSFLG
  10. C
  11. LOGICAL FUNCTION SYNMCH()
  12. IMPLICIT INTEGER(A-Z)
  13. LOGICAL SYNEQL,TAKEIT
  14. include 'parser.h'
  15. include 'vocab.h'
  16. include 'debug.h'
  17. C
  18. C THE FOLLOWING DATA STATEMENT WAS ORIGINALLY:
  19. C
  20. C DATA R50MIN/1RA/
  21. C
  22. DATA R50MIN/1600/
  23. C
  24. SYNMCH=.FALSE.
  25. D DFLAG=IAND(PRSFLG, 16).NE.0
  26. D if(DFLAG)write(0,*) 'synflags=',sdir,sind,sstd,sflip,sdriv,svmask
  27. J=ACT
  28. C !SET UP PTR TO SYNTAX.
  29. DRIVE=0
  30. C !NO DEFAULT.
  31. DFORCE=0
  32. C !NO FORCED DEFAULT.
  33. QPREP=IAND(OFLAG,OPREP)
  34. 100 J=J+2
  35. C !FIND START OF SYNTAX.
  36. IF((VVOC(J).LE.0).OR.(VVOC(J).GE.R50MIN)) GO TO 100
  37. LIMIT=J+VVOC(J)+1
  38. C !COMPUTE LIMIT.
  39. J=J+1
  40. C !ADVANCE TO NEXT.
  41. C
  42. 200 CALL UNPACKS(J,NEWJ)
  43. C !UNPACK SYNTAX.
  44. D IF(DFLAG) PRINT 60,O1,P1,DOBJ,DFL1,DFL2
  45. D60 FORMAT(' SYNMCH INPUTS TO SYNEQL- ',5I7)
  46. SPREP=IAND(DOBJ,VPMASK)
  47. IF(.NOT.SYNEQL(P1,O1,DOBJ,DFL1,DFL2)) GO TO 1000
  48. D IF(DFLAG) PRINT 60,O2,P2,IOBJ,IFL1,IFL2
  49. SPREP=IAND(IOBJ,VPMASK)
  50. IF(SYNEQL(P2,O2,IOBJ,IFL1,IFL2)) GO TO 6000
  51. C
  52. C SYNTAX MATCH FAILS, TRY NEXT ONE.
  53. C
  54. IF(O2) 3000,500,3000
  55. C !IF O2=0, SET DFLT.
  56. 1000 IF(O1) 3000,500,3000
  57. C !IF O1=0, SET DFLT.
  58. 500 IF((QPREP.EQ.0).OR.(QPREP.EQ.SPREP)) DFORCE=J
  59. C !IF PREP MCH.
  60. IF((IAND(VFLAG,SDRIV)).NE.0) DRIVE=J
  61. 3000 J=NEWJ
  62. IF(J.LT.LIMIT) GO TO 200
  63. C !MORE TO DO?
  64. C SYNMCH, PAGE 2
  65. C
  66. C MATCH HAS FAILED. IF DEFAULT SYNTAX EXISTS, TRY TO SNARF
  67. C ORPHANS OR GWIMS, OR MAKE NEW ORPHANS.
  68. C
  69. D IF(DFLAG) PRINT 20,DRIVE,DFORCE
  70. D20 FORMAT(' SYNMCH, DRIVE=',2I6)
  71. IF(DRIVE.EQ.0) DRIVE=DFORCE
  72. C !NO DRIVER? USE FORCE.
  73. IF(DRIVE.EQ.0) GO TO 10000
  74. C !ANY DRIVER?
  75. CALL UNPACKS(DRIVE,DFORCE)
  76. C !UNPACK DFLT SYNTAX.
  77. C
  78. C TRY TO FILL DIRECT OBJECT SLOT IF THAT WAS THE PROBLEM.
  79. C
  80. IF((IAND(VFLAG,SDIR).EQ.0).OR.(O1.NE.0)) GO TO 4000
  81. C
  82. C FIRST TRY TO SNARF ORPHAN OBJECT.
  83. C
  84. O1=IAND(OFLAG,OSLOT)
  85. IF(O1.EQ.0) GO TO 3500
  86. C !ANY ORPHAN?
  87. IF(SYNEQL(P1,O1,DOBJ,DFL1,DFL2)) GO TO 4000
  88. C
  89. C ORPHAN FAILS, TRY GWIM.
  90. C
  91. 3500 O1=GWIM(DOBJ,DFW1,DFW2)
  92. C !GET GWIM.
  93. D IF(DFLAG) PRINT 30,O1
  94. D30 FORMAT(' SYNMCH- DO GWIM= ',I6)
  95. IF(O1.GT.0) GO TO 4000
  96. C !TEST RESULT.
  97. CALL ORPHAN(-1,ACT,0,IAND(DOBJ,VPMASK),0)
  98. CALL RSPEAK(623)
  99. RETURN
  100. C
  101. C TRY TO FILL INDIRECT OBJECT SLOT IF THAT WAS THE PROBLEM.
  102. C
  103. 4000 IF((IAND(VFLAG,SIND).EQ.0).OR.(O2.NE.0)) GO TO 6000
  104. O2=GWIM(IOBJ,IFW1,IFW2)
  105. C !GWIM.
  106. D IF(DFLAG) PRINT 40,O2
  107. D40 FORMAT(' SYNMCH- IO GWIM= ',I6)
  108. IF(O2.GT.0) GO TO 6000
  109. IF(O1.EQ.0) O1=IAND(OFLAG,OSLOT)
  110. CALL ORPHAN(-1,ACT,O1,IAND(DOBJ,VPMASK),0)
  111. CALL RSPEAK(624)
  112. RETURN
  113. C
  114. C TOTAL CHOMP
  115. C
  116. 10000 CALL RSPEAK(601)
  117. C !CANT DO ANYTHING.
  118. RETURN
  119. C SYNMCH, PAGE 3
  120. C
  121. C NOW TRY TO TAKE INDIVIDUAL OBJECTS AND
  122. C IN GENERAL CLEAN UP THE PARSE VECTOR.
  123. C
  124. 6000 IF(IAND(VFLAG,SFLIP).EQ.0) GO TO 5000
  125. J=O1
  126. C !YES.
  127. O1=O2
  128. O2=J
  129. C
  130. 5000 PRSA=IAND(VFLAG,SVMASK)
  131. PRSO=O1
  132. C !GET DIR OBJ.
  133. PRSI=O2
  134. C !GET IND OBJ.
  135. IF(.NOT.TAKEIT(PRSO,DOBJ)) RETURN
  136. C !TRY TAKE.
  137. IF(.NOT.TAKEIT(PRSI,IOBJ)) RETURN
  138. C !TRY TAKE.
  139. SYNMCH=.TRUE.
  140. D IF(DFLAG) PRINT 50,SYNMCH,PRSA,PRSO,PRSI,ACT,O1,O2
  141. D50 FORMAT(' SYNMCH- RESULTS ',L1,6I7)
  142. RETURN
  143. C
  144. END
  145. C UNPACKS- UNPACK SYNTAX SPECIFICATION, ADV POINTER
  146. C
  147. C DECLARATIONS
  148. C
  149. SUBROUTINE UNPACKS(OLDJ,J)
  150. IMPLICIT INTEGER(A-Z)
  151. include 'vocab.h'
  152. include 'parser.h'
  153. C
  154. DO 10 I=1,11
  155. C !CLEAR SYNTAX.
  156. SYN(I)=0
  157. 10 CONTINUE
  158. C
  159. VFLAG=VVOC(OLDJ)
  160. J=OLDJ+1
  161. IF(IAND(VFLAG,SDIR).EQ.0) RETURN
  162. DFL1=-1
  163. C !ASSUME STD.
  164. DFL2=-1
  165. IF(IAND(VFLAG,SSTD).EQ.0) GO TO 100
  166. DFW1=-1
  167. C !YES.
  168. DFW2=-1
  169. DOBJ=VABIT+VRBIT+VFBIT
  170. GO TO 200
  171. C
  172. 100 DOBJ=VVOC(J)
  173. C !NOT STD.
  174. DFW1=VVOC(J+1)
  175. DFW2=VVOC(J+2)
  176. J=J+3
  177. IF(IAND(DOBJ,VEBIT).EQ.0) GO TO 200
  178. DFL1=DFW1
  179. C !YES.
  180. DFL2=DFW2
  181. C
  182. 200 IF(IAND(VFLAG,SIND).EQ.0) RETURN
  183. IFL1=-1
  184. C !ASSUME STD.
  185. IFL2=-1
  186. IOBJ=VVOC(J)
  187. IFW1=VVOC(J+1)
  188. IFW2=VVOC(J+2)
  189. J=J+3
  190. IF(IAND(IOBJ,VEBIT).EQ.0) RETURN
  191. IFL1=IFW1
  192. C !YES.
  193. IFL2=IFW2
  194. RETURN
  195. C
  196. END
  197. C SYNEQL- TEST FOR SYNTAX EQUALITY
  198. C
  199. C DECLARATIONS
  200. C
  201. LOGICAL FUNCTION SYNEQL(PREP,OBJ,SPREP,SFL1,SFL2)
  202. IMPLICIT INTEGER(A-Z)
  203. include 'objects.h'
  204. include 'parser.h'
  205. C
  206. IF(OBJ.EQ.0) GO TO 100
  207. C !ANY OBJECT?
  208. SYNEQL=(PREP.EQ.IAND(SPREP,VPMASK)).AND.
  209. & (IOR(IAND(SFL1,OFLAG1(OBJ)),
  210. & IAND(SFL2,OFLAG2(OBJ))).NE.0)
  211. RETURN
  212. C
  213. 100 SYNEQL=(PREP.EQ.0).AND.(SFL1.EQ.0).AND.(SFL2.EQ.0)
  214. RETURN
  215. C
  216. END
  217. C TAKEIT- PARSER BASED TAKE OF OBJECT
  218. C
  219. C DECLARATIONS
  220. C
  221. LOGICAL FUNCTION TAKEIT(OBJ,SFLAG)
  222. IMPLICIT INTEGER(A-Z)
  223. include 'parser.h'
  224. COMMON /STAR/ MBASE,STRBIT
  225. include 'gamestat.h'
  226. include 'state.h'
  227. include 'objects.h'
  228. include 'oflags.h'
  229. include 'advers.h'
  230. C TAKEIT, PAGE 2
  231. C
  232. TAKEIT=.FALSE.
  233. C !ASSUME LOSES.
  234. IF((OBJ.EQ.0).OR.(OBJ.GT.STRBIT)) GO TO 4000
  235. C !NULL/STARS WIN.
  236. ODO2=ODESC2(OBJ)
  237. C !GET DESC.
  238. X=OCAN(OBJ)
  239. C !GET CONTAINER.
  240. IF((X.EQ.0).OR.(IAND(SFLAG,VFBIT).EQ.0)) GO TO 500
  241. IF(IAND(OFLAG2(X),OPENBT).NE.0) GO TO 500
  242. CALL RSPSUB(566,ODO2)
  243. C !CANT REACH.
  244. RETURN
  245. C
  246. 500 IF(IAND(SFLAG,VRBIT).EQ.0) GO TO 1000
  247. IF(IAND(SFLAG,VTBIT).EQ.0) GO TO 2000
  248. C
  249. C SHOULD BE IN ROOM (VRBIT NE 0) AND CAN BE TAKEN (VTBIT NE 0)
  250. C
  251. IF(SCHLST(0,0,HERE,0,0,OBJ).LE.0) GO TO 4000
  252. C !IF NOT, OK.
  253. C
  254. C ITS IN THE ROOM AND CAN BE TAKEN.
  255. C
  256. IF((IAND(OFLAG1(OBJ),TAKEBT).NE.0).AND.
  257. & (IAND(OFLAG2(OBJ),TRYBT).EQ.0)) GO TO 3000
  258. C
  259. C NOT TAKEABLE. IF WE CARE, FAIL.
  260. C
  261. IF(IAND(SFLAG,VCBIT).EQ.0) GO TO 4000
  262. CALL RSPSUB(445,ODO2)
  263. RETURN
  264. C
  265. C 1000-- IT SHOULD NOT BE IN THE ROOM.
  266. C 2000-- IT CANT BE TAKEN.
  267. C
  268. 2000 IF(IAND(SFLAG,VCBIT).EQ.0) GO TO 4000
  269. 1000 IF(SCHLST(0,0,HERE,0,0,OBJ).LE.0) GO TO 4000
  270. CALL RSPSUB(665,ODO2)
  271. RETURN
  272. C TAKEIT, PAGE 3
  273. C
  274. C OBJECT IS IN THE ROOM, CAN BE TAKEN BY THE PARSER,
  275. C AND IS TAKEABLE IN GENERAL. IT IS NOT A STAR.
  276. C TAKING IT SHOULD NOT HAVE SIDE AFFECTS.
  277. C IF IT IS INSIDE SOMETHING, THE CONTAINER IS OPEN.
  278. C THE FOLLOWING CODE IS LIFTED FROM SUBROUTINE TAKE.
  279. C
  280. 3000 IF(OBJ.NE.AVEHIC(WINNER)) GO TO 3500
  281. C !TAKE VEHICLE?
  282. CALL RSPEAK(672)
  283. RETURN
  284. C
  285. 3500 IF(((X.NE.0).AND.(OADV(X).EQ.WINNER)).OR.
  286. & ((WEIGHT(0,OBJ,WINNER)+OSIZE(OBJ)).LE.MXLOAD))
  287. & GO TO 3700
  288. CALL RSPEAK(558)
  289. C !TOO BIG.
  290. RETURN
  291. C
  292. 3700 CALL NEWSTA(OBJ,559,0,0,WINNER)
  293. C !DO TAKE.
  294. OFLAG2(OBJ)=IOR(OFLAG2(OBJ),TCHBT)
  295. CALL SCRUPD(OFVAL(OBJ))
  296. OFVAL(OBJ)=0
  297. C
  298. 4000 TAKEIT=.TRUE.
  299. C !SUCCESS.
  300. RETURN
  301. C
  302. END
  303. C
  304. C GWIM- GET WHAT I MEAN IN AMBIGOUS SITUATIONS
  305. C
  306. C DECLARATIONS
  307. C
  308. INTEGER FUNCTION GWIM(SFLAG,SFW1,SFW2)
  309. IMPLICIT INTEGER(A-Z)
  310. LOGICAL TAKEIT,NOCARE
  311. include 'parser.h'
  312. COMMON /STAR/ MBASE,STRBIT
  313. include 'gamestat.h'
  314. include 'objects.h'
  315. include 'oflags.h'
  316. include 'advers.h'
  317. C GWIM, PAGE 2
  318. C
  319. GWIM=-1
  320. C !ASSUME LOSE.
  321. AV=AVEHIC(WINNER)
  322. NOBJ=0
  323. NOCARE=IAND(SFLAG,VCBIT).EQ.0
  324. C
  325. C FIRST SEARCH ADVENTURER
  326. C
  327. IF(IAND(SFLAG,VABIT).NE.0)
  328. & NOBJ=FWIM(SFW1,SFW2,0,0,WINNER,NOCARE)
  329. IF(IAND(SFLAG,VRBIT).NE.0) GO TO 100
  330. 50 GWIM=NOBJ
  331. RETURN
  332. C
  333. C ALSO SEARCH ROOM
  334. C
  335. 100 ROBJ=FWIM(SFW1,SFW2,HERE,0,0,NOCARE)
  336. IF(ROBJ) 500,50,200
  337. C !TEST RESULT.
  338. C
  339. C ROBJ > 0
  340. C
  341. 200 IF((AV.EQ.0).OR.(ROBJ.EQ.AV).OR.
  342. & (IAND(OFLAG2(ROBJ),FINDBT).NE.0)) GO TO 300
  343. IF(OCAN(ROBJ).NE.AV) GO TO 50
  344. C !UNREACHABLE? TRY NOBJ
  345. 300 IF(NOBJ.NE.0) RETURN
  346. C !IF AMBIGUOUS, RETURN.
  347. IF(.NOT.TAKEIT(ROBJ,SFLAG)) RETURN
  348. C !IF UNTAKEABLE, RETURN
  349. GWIM=ROBJ
  350. 500 RETURN
  351. C
  352. END