np3.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /* SYNMCH-- SYNTAX MATCHER */
  2. /*COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142*/
  3. /* ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED */
  4. /* WRITTEN BY R. M. SUPNIK */
  5. #include "funcs.h"
  6. #include "vars.h"
  7. #include "parse.h"
  8. static void unpack_ P((integer, integer *));
  9. static integer gwim_ P((integer, integer, integer));
  10. static logical syneql_ P((integer, integer, integer, integer, integer));
  11. static logical takeit_ P((integer, integer));
  12. /* THIS ROUTINE DETAILS ON BIT 4 OF PRSFLG */
  13. logical synmch_()
  14. {
  15. /* Initialized data */
  16. /* THE FOLLOWING DATA STATEMENT WAS ORIGINALLY: */
  17. /* DATA R50MIN/1RA/ */
  18. const integer r50min = 1600;
  19. /* System generated locals */
  20. integer i__1;
  21. logical ret_val;
  22. /* Local variables */
  23. integer j;
  24. integer newj;
  25. integer drive, limit, qprep, sprep, dforce;
  26. ret_val = FALSE_;
  27. j = pv_1.act;
  28. /* !SET UP PTR TO SYNTAX. */
  29. drive = 0;
  30. /* !NO DEFAULT. */
  31. dforce = 0;
  32. /* !NO FORCED DEFAULT. */
  33. qprep = orphs_1.oflag & orphs_1.oprep;
  34. L100:
  35. j += 2;
  36. /* !FIND START OF SYNTAX. */
  37. if (vvoc[j - 1] <= 0 || vvoc[j - 1] >= r50min) {
  38. goto L100;
  39. }
  40. limit = j + vvoc[j - 1] + 1;
  41. /* !COMPUTE LIMIT. */
  42. ++j;
  43. /* !ADVANCE TO NEXT. */
  44. L200:
  45. unpack_(j, &newj);
  46. /* !UNPACK SYNTAX. */
  47. sprep = syntax_1.dobj & VPMASK;
  48. if (! syneql_(pv_1.p1, pv_1.o1, syntax_1.dobj, syntax_1.dfl1,
  49. syntax_1.dfl2)) {
  50. goto L1000;
  51. }
  52. sprep = syntax_1.iobj & VPMASK;
  53. if (syneql_(pv_1.p2, pv_1.o2, syntax_1.iobj, syntax_1.ifl1,
  54. syntax_1.ifl2)) {
  55. goto L6000;
  56. }
  57. /* SYNTAX MATCH FAILS, TRY NEXT ONE. */
  58. if (pv_1.o2 != 0) {
  59. goto L3000;
  60. } else {
  61. goto L500;
  62. }
  63. /* !IF O2=0, SET DFLT. */
  64. L1000:
  65. if (pv_1.o1 != 0) {
  66. goto L3000;
  67. } else {
  68. goto L500;
  69. }
  70. /* !IF O1=0, SET DFLT. */
  71. L500:
  72. if (qprep == 0 || qprep == sprep) {
  73. dforce = j;
  74. }
  75. /* !IF PREP MCH. */
  76. if ((syntax_1.vflag & SDRIV) != 0) {
  77. drive = j;
  78. }
  79. L3000:
  80. j = newj;
  81. if (j < limit) {
  82. goto L200;
  83. }
  84. /* !MORE TO DO? */
  85. /* SYNMCH, PAGE 2 */
  86. /* MATCH HAS FAILED. IF DEFAULT SYNTAX EXISTS, TRY TO SNARF */
  87. /* ORPHANS OR GWIMS, OR MAKE NEW ORPHANS. */
  88. if (drive == 0) {
  89. drive = dforce;
  90. }
  91. /* !NO DRIVER? USE FORCE. */
  92. if (drive == 0) {
  93. goto L10000;
  94. }
  95. /* !ANY DRIVER? */
  96. unpack_(drive, &dforce);
  97. /* !UNPACK DFLT SYNTAX. */
  98. /* TRY TO FILL DIRECT OBJECT SLOT IF THAT WAS THE PROBLEM. */
  99. if ((syntax_1.vflag & SDIR) == 0 || pv_1.o1 != 0) {
  100. goto L4000;
  101. }
  102. /* FIRST TRY TO SNARF ORPHAN OBJECT. */
  103. pv_1.o1 = orphs_1.oflag & orphs_1.oslot;
  104. if (pv_1.o1 == 0) {
  105. goto L3500;
  106. }
  107. /* !ANY ORPHAN? */
  108. if (syneql_(pv_1.p1, pv_1.o1, syntax_1.dobj, syntax_1.dfl1,
  109. syntax_1.dfl2)) {
  110. goto L4000;
  111. }
  112. /* ORPHAN FAILS, TRY GWIM. */
  113. L3500:
  114. pv_1.o1 = gwim_(syntax_1.dobj, syntax_1.dfw1, syntax_1.dfw2);
  115. /* !GET GWIM. */
  116. if (pv_1.o1 > 0) {
  117. goto L4000;
  118. }
  119. /* !TEST RESULT. */
  120. i__1 = syntax_1.dobj & VPMASK;
  121. orphan_(- 1, pv_1.act, 0, i__1, 0);
  122. rspeak_(623);
  123. return ret_val;
  124. /* TRY TO FILL INDIRECT OBJECT SLOT IF THAT WAS THE PROBLEM. */
  125. L4000:
  126. if ((syntax_1.vflag & SIND) == 0 || pv_1.o2 != 0) {
  127. goto L6000;
  128. }
  129. pv_1.o2 = gwim_(syntax_1.iobj, syntax_1.ifw1, syntax_1.ifw2);
  130. /* !GWIM. */
  131. if (pv_1.o2 > 0) {
  132. goto L6000;
  133. }
  134. if (pv_1.o1 == 0) {
  135. pv_1.o1 = orphs_1.oflag & orphs_1.oslot;
  136. }
  137. i__1 = syntax_1.dobj & VPMASK;
  138. orphan_(- 1, pv_1.act, pv_1.o1, i__1, 0);
  139. rspeak_(624);
  140. return ret_val;
  141. /* TOTAL CHOMP */
  142. L10000:
  143. rspeak_(601);
  144. /* !CANT DO ANYTHING. */
  145. return ret_val;
  146. /* SYNMCH, PAGE 3 */
  147. /* NOW TRY TO TAKE INDIVIDUAL OBJECTS AND */
  148. /* IN GENERAL CLEAN UP THE PARSE VECTOR. */
  149. L6000:
  150. if ((syntax_1.vflag & SFLIP) == 0) {
  151. goto L5000;
  152. }
  153. j = pv_1.o1;
  154. /* !YES. */
  155. pv_1.o1 = pv_1.o2;
  156. pv_1.o2 = j;
  157. L5000:
  158. prsvec_1.prsa = syntax_1.vflag & SVMASK;
  159. prsvec_1.prso = pv_1.o1;
  160. /* !GET DIR OBJ. */
  161. prsvec_1.prsi = pv_1.o2;
  162. /* !GET IND OBJ. */
  163. if (! takeit_(prsvec_1.prso, syntax_1.dobj)) {
  164. return ret_val;
  165. }
  166. /* !TRY TAKE. */
  167. if (! takeit_(prsvec_1.prsi, syntax_1.iobj)) {
  168. return ret_val;
  169. }
  170. /* !TRY TAKE. */
  171. ret_val = TRUE_;
  172. return ret_val;
  173. } /* synmch_ */
  174. /* UNPACK- UNPACK SYNTAX SPECIFICATION, ADV POINTER */
  175. /* DECLARATIONS */
  176. static void unpack_(oldj, j)
  177. integer oldj;
  178. integer *j;
  179. {
  180. /* Local variables */
  181. integer i;
  182. for (i = 1; i <= 11; ++i) {
  183. /* !CLEAR SYNTAX. */
  184. syn[i - 1] = 0;
  185. /* L10: */
  186. }
  187. syntax_1.vflag = vvoc[oldj - 1];
  188. *j = oldj + 1;
  189. if ((syntax_1.vflag & SDIR) == 0) {
  190. return;
  191. }
  192. syntax_1.dfl1 = -1;
  193. /* !ASSUME STD. */
  194. syntax_1.dfl2 = -1;
  195. if ((syntax_1.vflag & SSTD) == 0) {
  196. goto L100;
  197. }
  198. syntax_1.dfw1 = -1;
  199. /* !YES. */
  200. syntax_1.dfw2 = -1;
  201. syntax_1.dobj = VABIT + VRBIT + VFBIT;
  202. goto L200;
  203. L100:
  204. syntax_1.dobj = vvoc[*j - 1];
  205. /* !NOT STD. */
  206. syntax_1.dfw1 = vvoc[*j];
  207. syntax_1.dfw2 = vvoc[*j + 1];
  208. *j += 3;
  209. if ((syntax_1.dobj & VEBIT) == 0) {
  210. goto L200;
  211. }
  212. syntax_1.dfl1 = syntax_1.dfw1;
  213. /* !YES. */
  214. syntax_1.dfl2 = syntax_1.dfw2;
  215. L200:
  216. if ((syntax_1.vflag & SIND) == 0) {
  217. return;
  218. }
  219. syntax_1.ifl1 = -1;
  220. /* !ASSUME STD. */
  221. syntax_1.ifl2 = -1;
  222. syntax_1.iobj = vvoc[*j - 1];
  223. syntax_1.ifw1 = vvoc[*j];
  224. syntax_1.ifw2 = vvoc[*j + 1];
  225. *j += 3;
  226. if ((syntax_1.iobj & VEBIT) == 0) {
  227. return;
  228. }
  229. syntax_1.ifl1 = syntax_1.ifw1;
  230. /* !YES. */
  231. syntax_1.ifl2 = syntax_1.ifw2;
  232. } /* unpack_ */
  233. /* SYNEQL- TEST FOR SYNTAX EQUALITY */
  234. /* DECLARATIONS */
  235. static logical syneql_(prep, obj, sprep, sfl1, sfl2)
  236. integer prep;
  237. integer obj;
  238. integer sprep;
  239. integer sfl1;
  240. integer sfl2;
  241. {
  242. /* System generated locals */
  243. logical ret_val;
  244. if (obj == 0) {
  245. goto L100;
  246. }
  247. /* !ANY OBJECT? */
  248. ret_val = prep == (sprep & VPMASK) && (sfl1 & objcts_1.oflag1[
  249. obj - 1] | sfl2 & objcts_1.oflag2[obj - 1]) != 0;
  250. return ret_val;
  251. L100:
  252. ret_val = prep == 0 && sfl1 == 0 && sfl2 == 0;
  253. return ret_val;
  254. } /* syneql_ */
  255. /* TAKEIT- PARSER BASED TAKE OF OBJECT */
  256. /* DECLARATIONS */
  257. static logical takeit_(obj, sflag)
  258. integer obj;
  259. integer sflag;
  260. {
  261. /* System generated locals */
  262. logical ret_val;
  263. /* Local variables */
  264. integer x;
  265. integer odo2;
  266. /* TAKEIT, PAGE 2 */
  267. ret_val = FALSE_;
  268. /* !ASSUME LOSES. */
  269. if (obj == 0 || obj > star_1.strbit) {
  270. goto L4000;
  271. }
  272. /* !NULL/STARS WIN. */
  273. odo2 = objcts_1.odesc2[obj - 1];
  274. /* !GET DESC. */
  275. x = objcts_1.ocan[obj - 1];
  276. /* !GET CONTAINER. */
  277. if (x == 0 || (sflag & VFBIT) == 0) {
  278. goto L500;
  279. }
  280. if ((objcts_1.oflag2[x - 1] & OPENBT) != 0) {
  281. goto L500;
  282. }
  283. rspsub_(566, odo2);
  284. /* !CANT REACH. */
  285. return ret_val;
  286. L500:
  287. if ((sflag & VRBIT) == 0) {
  288. goto L1000;
  289. }
  290. if ((sflag & VTBIT) == 0) {
  291. goto L2000;
  292. }
  293. /* SHOULD BE IN ROOM (VRBIT NE 0) AND CAN BE TAKEN (VTBIT NE 0) */
  294. if (schlst_(0, 0, play_1.here, 0, 0, obj) <= 0) {
  295. goto L4000;
  296. }
  297. /* !IF NOT, OK. */
  298. /* ITS IN THE ROOM AND CAN BE TAKEN. */
  299. if ((objcts_1.oflag1[obj - 1] & TAKEBT) != 0 && (
  300. objcts_1.oflag2[obj - 1] & TRYBT) == 0) {
  301. goto L3000;
  302. }
  303. /* NOT TAKEABLE. IF WE CARE, FAIL. */
  304. if ((sflag & VCBIT) == 0) {
  305. goto L4000;
  306. }
  307. rspsub_(445, odo2);
  308. return ret_val;
  309. /* 1000-- IT SHOULD NOT BE IN THE ROOM. */
  310. /* 2000-- IT CANT BE TAKEN. */
  311. L2000:
  312. if ((sflag & VCBIT) == 0) {
  313. goto L4000;
  314. }
  315. L1000:
  316. if (schlst_(0, 0, play_1.here, 0, 0, obj) <= 0) {
  317. goto L4000;
  318. }
  319. rspsub_(665, odo2);
  320. return ret_val;
  321. /* TAKEIT, PAGE 3 */
  322. /* OBJECT IS IN THE ROOM, CAN BE TAKEN BY THE PARSER, */
  323. /* AND IS TAKEABLE IN GENERAL. IT IS NOT A STAR. */
  324. /* TAKING IT SHOULD NOT HAVE SIDE AFFECTS. */
  325. /* IF IT IS INSIDE SOMETHING, THE CONTAINER IS OPEN. */
  326. /* THE FOLLOWING CODE IS LIFTED FROM SUBROUTINE TAKE. */
  327. L3000:
  328. if (obj != advs_1.avehic[play_1.winner - 1]) {
  329. goto L3500;
  330. }
  331. /* !TAKE VEHICLE? */
  332. rspeak_(672);
  333. return ret_val;
  334. L3500:
  335. if (x != 0 && objcts_1.oadv[x - 1] == play_1.winner || weight_(0, obj,
  336. play_1.winner) + objcts_1.osize[obj - 1] <= state_1.mxload) {
  337. goto L3700;
  338. }
  339. rspeak_(558);
  340. /* !TOO BIG. */
  341. return ret_val;
  342. L3700:
  343. newsta_(obj, 559, 0, 0, play_1.winner);
  344. /* !DO TAKE. */
  345. objcts_1.oflag2[obj - 1] |= TCHBT;
  346. scrupd_(objcts_1.ofval[obj - 1]);
  347. objcts_1.ofval[obj - 1] = 0;
  348. L4000:
  349. ret_val = TRUE_;
  350. /* !SUCCESS. */
  351. return ret_val;
  352. } /* takeit_ */
  353. /* GWIM- GET WHAT I MEAN IN AMBIGOUS SITUATIONS */
  354. /* DECLARATIONS */
  355. static integer gwim_(sflag, sfw1, sfw2)
  356. integer sflag;
  357. integer sfw1;
  358. integer sfw2;
  359. {
  360. /* System generated locals */
  361. integer ret_val;
  362. /* Local variables */
  363. integer av;
  364. integer nobj, robj;
  365. logical nocare;
  366. /* GWIM, PAGE 2 */
  367. ret_val = -1;
  368. /* !ASSUME LOSE. */
  369. av = advs_1.avehic[play_1.winner - 1];
  370. nobj = 0;
  371. nocare = (sflag & VCBIT) == 0;
  372. /* FIRST SEARCH ADVENTURER */
  373. if ((sflag & VABIT) != 0) {
  374. nobj = fwim_(sfw1, sfw2, 0, 0, play_1.winner, nocare);
  375. }
  376. if ((sflag & VRBIT) != 0) {
  377. goto L100;
  378. }
  379. L50:
  380. ret_val = nobj;
  381. return ret_val;
  382. /* ALSO SEARCH ROOM */
  383. L100:
  384. robj = fwim_(sfw1, sfw2, play_1.here, 0, 0, nocare);
  385. if (robj < 0) {
  386. goto L500;
  387. } else if (robj == 0) {
  388. goto L50;
  389. } else {
  390. goto L200;
  391. }
  392. /* !TEST RESULT. */
  393. /* ROBJ > 0 */
  394. L200:
  395. if (av == 0 || robj == av || (objcts_1.oflag2[robj - 1] & FINDBT)
  396. != 0) {
  397. goto L300;
  398. }
  399. if (objcts_1.ocan[robj - 1] != av) {
  400. goto L50;
  401. }
  402. /* !UNREACHABLE? TRY NOBJ */
  403. L300:
  404. if (nobj != 0) {
  405. return ret_val;
  406. }
  407. /* !IF AMBIGUOUS, RETURN. */
  408. if (! takeit_(robj, sflag)) {
  409. return ret_val;
  410. }
  411. /* !IF UNTAKEABLE, RETURN */
  412. ret_val = robj;
  413. L500:
  414. return ret_val;
  415. } /* gwim_ */