infix.h 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. ! ==============================================================================
  2. ! INFIX: Support for the optional library debugger extension "Infix".
  3. !
  4. ! Supplied for use with Inform 6 -- Release 6/12 -- Serial number 151220
  5. !
  6. ! Copyright Graham Nelson 1993-2004 and David Griffith 2012-2015
  7. !
  8. ! This code is licensed under either the traditional Inform license as
  9. ! described by the DM4 or the Artistic License version 2.0. See the
  10. ! file COPYING in the distribution archive or at
  11. ! https://github.com/DavidGriffith/inform6lib/
  12. !
  13. ! This file is automatically Included in your game file by "Grammar" if you
  14. ! supply the -X compiler switch.
  15. ! ==============================================================================
  16. System_file;
  17. ! ------------------------------------------------------------------------------
  18. #Ifdef DEBUG;
  19. Constant INFIXTT_NUMBER 0;
  20. Constant INFIXTT_ARRAY 1;
  21. Constant INFIXTT_ROUTINE 2;
  22. Constant INFIXTT_CONSTANT 3;
  23. Constant INFIXTT_DWORD 4;
  24. Constant INFIXTT_ACTION 5;
  25. Constant INFIXTT_ATTRIBUTE 6;
  26. Constant INFIXTT_PROPERTY 7;
  27. Constant INFIXTT_GLOBAL 8;
  28. Constant INFIXTT_NAMEDOBJECT 9;
  29. Constant INFIXTT_SYSFUN 10;
  30. Constant INFIXTT_STATICSTRING 11;
  31. Constant INFIXTT_LOGICAL 12;
  32. Global infix_term_type;
  33. Global infix_data1;
  34. Global infix_data2;
  35. Global infix_lvalue;
  36. Global infix_parsed_lvalue;
  37. Array infix_tolowercase -> 256;
  38. #Ifdef VN_1630;
  39. Array infix_text buffer 126;
  40. #Ifnot;
  41. Array infix_text -> 128;
  42. #Endif; ! VN_
  43. [ InfixPrintAttribute x; print (string) #attribute_names_array-->x; ];
  44. [ InfixPrintProperty x; print (property) x; ];
  45. #Ifdef TARGET_GLULX;
  46. [ InfixPrintGIProperty x; print (property) x; ];
  47. #Endif; ! TARGET_
  48. [ InfixPrintGlobal x; print (string) #global_names_array-->x; ];
  49. [ InfixPrintAction x; print (string) #action_names_array-->(x-#lowest_action_number); ];
  50. [ InfixPrintRoutine x; print (string) #routine_names_array-->(x-#lowest_routine_number); ];
  51. [ InfixPrintConstant x; print (string) #constant_names_array-->(x-#lowest_constant_number); ];
  52. [ InfixPrintArray x; print (string) #array_names_array-->(x-#lowest_array_number); ];
  53. [ InfixPrintFakeAction x;
  54. print (string) #fake_action_names_array-->(x-#lowest_fake_action_number); ];
  55. [ InfixPrintPA x n;
  56. for (n=#lowest_routine_number : n<=#highest_routine_number : n++) {
  57. if (x == Symb__Tab(INFIXTT_ROUTINE, n)) {
  58. print (InfixPrintRoutine) n; return;
  59. }
  60. }
  61. print "Routine(", x, ")";
  62. ];
  63. [ InfixMatchPrule PrintingRule range1 range2 wa wl t i i2 it2 itlc j k plus;
  64. itlc = infix_tolowercase;
  65. if (itlc->255 == 0) {
  66. for (j=0 : j<256 : j++) itlc->j = j;
  67. itlc->'A' = 'a'; itlc->'B' = 'b';
  68. itlc->'C' = 'c'; itlc->'D' = 'd';
  69. itlc->'E' = 'e'; itlc->'F' = 'f';
  70. itlc->'G' = 'g'; itlc->'H' = 'h';
  71. itlc->'I' = 'i'; itlc->'J' = 'j';
  72. itlc->'K' = 'k'; itlc->'L' = 'l';
  73. itlc->'M' = 'm'; itlc->'N' = 'n';
  74. itlc->'O' = 'o'; itlc->'P' = 'p';
  75. itlc->'Q' = 'q'; itlc->'R' = 'r';
  76. itlc->'S' = 's'; itlc->'T' = 't';
  77. itlc->'U' = 'u'; itlc->'V' = 'v';
  78. itlc->'W' = 'w'; itlc->'X' = 'x';
  79. itlc->'Y' = 'y'; itlc->'Z' = 'z';
  80. }
  81. switch (PrintingRule) {
  82. InfixPrintAttribute:
  83. if (wa->0 == '~') { wl--; wa++; plus = 100; } ! A tilde
  84. t = #attribute_names_array;
  85. InfixPrintProperty: t = #property_names_array;
  86. #Ifdef TARGET_GLULX;
  87. InfixPrintGIProperty: t = #identifiers_table-->2;
  88. #Endif; ! TARGET_
  89. InfixPrintAction: t = #action_names_array;
  90. InfixPrintFakeAction: t = #fake_action_names_array;
  91. InfixPrintGlobal: t = #global_names_array;
  92. InfixPrintRoutine: t = #routine_names_array;
  93. InfixPrintAction: t = #constant_names_array;
  94. InfixPrintArray: t = #array_names_array;
  95. }
  96. i2 = range2-range1; it2 = infix_text+WORDSIZE;
  97. for (i=0 : i<=i2 : i++) {
  98. #ifdef TARGET_ZCODE;
  99. infix_text-->0 = 62; @output_stream 3 infix_text;
  100. if (t) print (string) t-->i; else PrintingRule(i+range1);
  101. @output_stream -3;
  102. #ifnot; ! TARGET_GLULX
  103. if (t) PrintToBuffer(infix_text, 62, t-->i);
  104. else PrintToBuffer(infix_text, 62, PrintingRule, i+range1);
  105. #endif; ! TARGET_
  106. k = infix_text-->0;
  107. if (k ~= wl) jump XL;
  108. if (itlc->(it2->0) ~= itlc->(wa->0)) jump XL;
  109. for (j=1 : j<k : j++)
  110. if (itlc->(it2->j) ~= itlc->(wa->j)) jump XL;
  111. parsed_number = i + range1 + plus;
  112. rtrue;
  113. .XL;
  114. }
  115. rfalse;
  116. ];
  117. [ InfixActionToken;
  118. if (InfixMatchPrule(InfixPrintAction, #lowest_action_number,
  119. #highest_action_number, WordAddress(wn), WordLength(wn))) {
  120. wn++; infix_lvalue = parsed_number; return 0;
  121. }
  122. if (InfixMatchPrule(InfixPrintFakeAction, #lowest_fake_action_number,
  123. #highest_fake_action_number, WordAddress(wn), WordLength(wn))) {
  124. wn++; infix_lvalue = parsed_number; return 0;
  125. }
  126. return -1;
  127. ];
  128. [ InfixRvalueTerm n w i initial_wn wa wl sign base digit dcount;
  129. initial_wn = wn;
  130. infix_parsed_lvalue = -1;
  131. infix_term_type = INFIXTT_NUMBER;
  132. w = NextWordStopped();
  133. if (w == -1) return -1;
  134. wa = WordAddress(wn-1);
  135. wl = WordLength(wn-1);
  136. if (wa->0 == '-' or '$' or '0' or '1' or '2' or '3'
  137. or '4' or '5' or '6' or '7' or '8' or '9') {
  138. ! Parse decimal, hex or binary number
  139. sign = 1; base = 10; dcount = 0;
  140. if (wa->0 == '-') { sign = -1; wl--; wa++; }
  141. else {
  142. if (wa->0 == '$') { base = 16; wl--; wa++; }
  143. if (wa->0 == '$') { base = 2; wl--; wa++; }
  144. }
  145. if (wl == 0) return -1;
  146. n = 0;
  147. while (wl > 0) {
  148. if (wa->0 >= 'a') digit = wa->0 - 'a' + 10;
  149. else digit = wa->0 - '0';
  150. dcount++;
  151. #Ifdef TARGET_ZCODE;
  152. switch (base) {
  153. 2:
  154. if (dcount == 17) return -1;
  155. 10:
  156. if (dcount == 6) return -1;
  157. if (dcount == 5) {
  158. if (n > 3276) return -1;
  159. if (n == 3276) {
  160. if (sign == 1 && digit > 7) return -1;
  161. if (sign == -1 && digit > 8) return -1;
  162. }
  163. }
  164. 16:
  165. if (dcount == 5) return -1;
  166. }
  167. #Ifnot; ! TARGET_GLULX
  168. switch (base) {
  169. 2:
  170. if (dcount == 33) return -1;
  171. 10:
  172. if (dcount == 11) return -1;
  173. if (dcount == 10) {
  174. if (n > 214748363) return -1;
  175. }
  176. 16:
  177. if (dcount == 9) return -1;
  178. }
  179. #Endif; ! TARGET_
  180. if (digit >= 0 && digit < base) n = base*n + digit;
  181. else return -1;
  182. wl--; wa++;
  183. }
  184. parsed_number = n*sign; return 1;
  185. }
  186. ! Parse character constant 'a'
  187. if (wl == 3 && wa->0 == ''' && wa->2 == ''') {
  188. parsed_number = wa->1; return 1;
  189. }
  190. ! ##Action, 'dword'
  191. switch (w) {
  192. '##':
  193. infix_term_type = INFIXTT_ACTION;
  194. w = NextWordStopped(); if (w == -1) return -1;
  195. wn--;
  196. if (InfixActionToken() == 0) return 1;
  197. return -1;
  198. '^^':
  199. infix_term_type = INFIXTT_DWORD;
  200. w = NextWordStopped(); if (w == -1) return -1;
  201. parsed_number = w; return 1;
  202. }
  203. ! Test for attribute, property, class name, variable name, array name, routine
  204. ! name, constant name
  205. wn--;
  206. if ((wa->0 >= 'a' && wa->0 <= 'z') ||
  207. (wa->0 >= 'A' && wa->0 <= 'Z') ||
  208. wa->0 == '_') {
  209. infix_term_type = INFIXTT_ATTRIBUTE;
  210. if (InfixMatchPrule(InfixPrintAttribute, #lowest_attribute_number,
  211. #highest_attribute_number, wa, wl)) {
  212. wn++; return 1; }
  213. infix_term_type = INFIXTT_PROPERTY;
  214. #Ifdef TARGET_ZCODE;
  215. if (InfixMatchPrule(InfixPrintProperty, #lowest_property_number,
  216. #highest_property_number, wa, wl)) {
  217. wn++; return 1;
  218. }
  219. #Ifnot; ! TARGET_
  220. if (InfixMatchPrule(InfixPrintProperty, #lowest_property_number,
  221. #identifiers_table-->1 - 1, wa, wl)) {
  222. wn++; return 1;
  223. }
  224. if (InfixMatchPrule(InfixPrintGIProperty, INDIV_PROP_START,
  225. #highest_property_number, wa, wl)) {
  226. wn++; return 1;
  227. }
  228. #Endif; ! TARGET_
  229. infix_term_type = INFIXTT_GLOBAL;
  230. if (InfixMatchPrule(InfixPrintGlobal, #lowest_global_number,
  231. #highest_global_number, wa, wl)) {
  232. infix_parsed_lvalue = parsed_number-16;
  233. parsed_number = #globals_array-->infix_parsed_lvalue;
  234. wn++; return 1;
  235. }
  236. infix_term_type = INFIXTT_ARRAY;
  237. if (InfixMatchPrule(InfixPrintArray, #lowest_array_number,
  238. #highest_array_number, wa, wl)) {
  239. infix_parsed_lvalue = parsed_number;
  240. parsed_number = Symb__Tab(INFIXTT_ARRAY,parsed_number);
  241. infix_data1 = temp__global3;
  242. infix_data2 = temp__global2;
  243. wn++; return 1;
  244. }
  245. infix_term_type = INFIXTT_ROUTINE;
  246. if (InfixMatchPrule(InfixPrintRoutine, #lowest_routine_number,
  247. #highest_routine_number, wa, wl)) {
  248. infix_parsed_lvalue = parsed_number;
  249. parsed_number = Symb__Tab(INFIXTT_ROUTINE,parsed_number);
  250. infix_data1 = temp__global3;
  251. infix_data2 = temp__global2;
  252. wn++; return 1;
  253. }
  254. infix_term_type = INFIXTT_CONSTANT;
  255. if (InfixMatchPrule(InfixPrintConstant, #lowest_constant_number,
  256. #highest_constant_number, wa, wl)) {
  257. infix_parsed_lvalue = parsed_number;
  258. parsed_number = Symb__Tab(INFIXTT_CONSTANT,parsed_number);
  259. infix_data1 = temp__global3;
  260. infix_data2 = temp__global2;
  261. wn++; return 1;
  262. }
  263. switch (w) {
  264. 'parent', 'child', 'children',
  265. 'random', 'metaclass', 'sibling':
  266. parsed_number = w;
  267. infix_parsed_lvalue = INFIXTT_SYSFUN;
  268. wn++; return 1;
  269. }
  270. }
  271. infix_term_type = INFIXTT_NAMEDOBJECT;
  272. wn = initial_wn; i = ParseToken(SCOPE_TT, InfixBigScope);
  273. if (i == GPR_REPARSE) return i;
  274. if (i > GPR_MULTIPLE) {
  275. print "(", (name) i, " (", i, "))^";
  276. parsed_number = i; return 1;
  277. }
  278. return -1;
  279. ]; ! end of InfixRvalueTerm
  280. [ InfixBigScope x;
  281. if (scope_stage == 1) return false; ! No multiples here
  282. if (scope_stage == 2) {
  283. objectloop (x ofclass Object) PlaceInScope(x);
  284. return true; ! That's the whole scope
  285. }
  286. print "; I'm unable to make any sense of that term.^";
  287. ];
  288. [ InfixCheckLineSpaced wa wl i force altered;
  289. for (i=1 : i<=NumberWords() : i++) {
  290. wa = WordAddress(i);
  291. wl = WordLength(i);
  292. if (wl > 3 && wa->0 == ''' && wa->(wl-1) == ''') {
  293. wa->(wl-1) = ' ';
  294. if (wa->(wl-2) == '/' && wa->(wl-3) == '/') {
  295. wa->(wl-2) = ' ';
  296. wa->(wl-3) = ' ';
  297. }
  298. LTI_Insert(wa-buffer, ''');
  299. LTI_Insert(wa-buffer + 2, ' ');
  300. altered = true; break;
  301. }
  302. }
  303. for (i=WORDSIZE : i<GetKeyBufLength() + WORDSIZE : i++) {
  304. #Ifdef TARGET_GLULX;
  305. buffer->i = LowerCase(buffer->i);
  306. #Endif; ! TARGET_
  307. force = false;
  308. if (buffer->i == '-' && buffer->(i+1) == '-' && buffer->(i+2) == '>')
  309. force = true;
  310. if (force) {
  311. if (i>WORDSIZE && buffer->(i-1) ~= ' ') {
  312. LTI_Insert(i++, ' '); altered = true;
  313. }
  314. if (buffer->(i+3) ~= ' ') {
  315. LTI_Insert(i+3, ' '); i++; altered = true;
  316. }
  317. i = i + 2; continue;
  318. }
  319. if (buffer->i == ':' && buffer->(i+1) == ':') force = true;
  320. if (buffer->i == '-' && buffer->(i+1) == '>') force = true;
  321. if (buffer->i == '.' && buffer->(i+1) == '&') {
  322. buffer->i = ']'; force = true;
  323. }
  324. if (buffer->i == '.' && buffer->(i+1) == '#') {
  325. buffer->i = ']'; force = true;
  326. }
  327. if (buffer->i == ']' && buffer->(i+1) == '&') force = true;
  328. if (buffer->i == ']' && buffer->(i+1) == '#') force = true;
  329. if (buffer->i == '+' && buffer->(i+1) == '+') force = true;
  330. if (buffer->i == '-' && buffer->(i+1) == '-') force = true;
  331. if (buffer->i == '&' && buffer->(i+1) == '&') force = true;
  332. if (buffer->i == '|' && buffer->(i+1) == '|') force = true;
  333. if (buffer->i == '~' && buffer->(i+1) == '~') force = true;
  334. if (buffer->i == '=' && buffer->(i+1) == '=') force = true;
  335. if (buffer->i == '~' && buffer->(i+1) == '=') force = true;
  336. if (buffer->i == '>' && buffer->(i+1) == '=') force = true;
  337. if (buffer->i == '<' && buffer->(i+1) == '=') force = true;
  338. if (buffer->i == '#' && buffer->(i+1) == '#') force = true;
  339. if (force) {
  340. if (i > WORDSIZE && buffer->(i-1) ~= ' ') {
  341. LTI_Insert(i++, ' '); altered = true;
  342. }
  343. if (buffer->(i+2) ~= ' ') {
  344. LTI_Insert(i+2, ' '); i++; altered = true;
  345. }
  346. i = i + 1; continue;
  347. }
  348. if (buffer->i == '+') force = true;
  349. if (buffer->i == '-') force = true;
  350. if (buffer->i == '*') force = true;
  351. if (buffer->i == '/') force = true;
  352. if (buffer->i == '%') force = true;
  353. if (buffer->i == '(') force = true;
  354. if (buffer->i == ')') force = true;
  355. if (buffer->i == '<' && buffer->(i-1) ~= ';') force = true;
  356. if (buffer->i == '>') force = true;
  357. if (buffer->i == ',') force = true;
  358. if (buffer->i == '.') force = true;
  359. if (buffer->i == '&') force = true;
  360. if (buffer->i == '|') force = true;
  361. if (buffer->i == '~') force = true;
  362. if (buffer->i == '=') force = true;
  363. if (force) {
  364. if (i > WORDSIZE && buffer->(i-1) ~= ' ') {
  365. LTI_Insert(i++, ' '); altered = true;
  366. }
  367. if (buffer->(i+1) ~= ' ') {
  368. LTI_Insert(i+1, ' '); i++; altered = true;
  369. }
  370. }
  371. }
  372. for (i=WORDSIZE : i<GetKeyBufLength() + WORDSIZE : i++)
  373. if (buffer->i == '~') { buffer->i = '['; altered = true; }
  374. return altered;
  375. ]; ! end of InfixCheckLineSpaced
  376. Array InfixRV_rvals --> 32;
  377. Array InfixRV_lvals --> 32;
  378. Array InfixRV_op --> 32;
  379. Array InfixRV_lop --> 32;
  380. Array InfixRV_rop --> 32;
  381. Array InfixRV_types --> 32;
  382. Array InfixRV_commas --> 32;
  383. [ InfixInBounds addr index n;
  384. if (addr < #array__start || addr > #array__end)
  385. rtrue;
  386. for (n=#lowest_array_number : n<=#highest_array_number : n++) {
  387. if (addr == Symb__Tab(INFIXTT_ARRAY, n)) {
  388. if (temp__global3 == 1 or 3)
  389. temp__global2=temp__global2*WORDSIZE+WORDSIZE-1;
  390. if (index > temp__global2) {
  391. print "Array index out of range";
  392. rfalse;
  393. }
  394. }
  395. }
  396. rtrue;
  397. ];
  398. [ InfixRvalue acc w i n flag base expecting_term max maxi lop rop lvalside
  399. a b sysfun_f;
  400. if (InfixCheckLineSpaced()) return GPR_REPARSE;
  401. ! w = wn; for (i=0 : i<10 : i++) { wn = w; InfixRvalueTerm(); print i, "^"; }
  402. ! wn = w;
  403. expecting_term = true; base = 0;
  404. do {
  405. w = NextWordStopped();
  406. if (expecting_term) {
  407. switch (w) {
  408. '-//':
  409. InfixRV_rvals-->n = 'unary-'; InfixRV_types-->n = base + 8;
  410. '[//':
  411. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  412. '[[':
  413. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  414. '++':
  415. InfixRV_rvals-->n = 'pre++'; InfixRV_types-->n = base + 9;
  416. '--':
  417. InfixRV_rvals-->n = 'pre--'; InfixRV_types-->n = base + 9;
  418. '(//':
  419. InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base+100;
  420. ')//':
  421. InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base-100;
  422. if (base < 0) { wn--; flag = true; }
  423. -1:
  424. flag = true;
  425. default:
  426. wn--;
  427. if (InfixRValueTerm() == 1) {
  428. InfixRV_rvals-->n = parsed_number;
  429. InfixRV_lvals-->n = infix_parsed_lvalue;
  430. InfixRV_types-->n = -1;
  431. expecting_term = false;
  432. }
  433. else flag = true;
  434. }
  435. }
  436. else {
  437. expecting_term = true;
  438. switch (w) {
  439. comma_word:
  440. InfixRV_rvals-->n = w; InfixRV_types-->n = base;
  441. '=//':
  442. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 1;
  443. '&&', '||':
  444. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  445. '==', '[=', '>//', '>=', '<//', '<=', 'has', 'hasnt',
  446. 'in', 'notin', 'ofclass', 'provides':
  447. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 3;
  448. 'or':
  449. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 4;
  450. '+//', '-//':
  451. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 5;
  452. '*//', '@{2f}//', '%//', '&//', '|//':
  453. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  454. '->', '-->':
  455. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 7;
  456. ']&', ']#':
  457. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 10;
  458. THEN1__WD:
  459. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 12;
  460. '::':
  461. InfixRV_rvals-->n = w; InfixRV_types-->n = base + 13;
  462. '(//':
  463. InfixRV_rvals-->n = '(rcall';
  464. InfixRV_types-->n = base + 11; base = base + 100;
  465. ')//':
  466. InfixRV_rvals-->n = w; InfixRV_types-->n = -3;
  467. base = base - 100;
  468. if (base < 0) { wn--; flag = true; }
  469. expecting_term = false;
  470. '++':
  471. InfixRV_rvals-->n = 'post++'; InfixRV_types-->n = base + 9;
  472. expecting_term = false;
  473. '--':
  474. InfixRV_rvals-->n = 'post--'; InfixRV_types-->n = base + 9;
  475. expecting_term = false;
  476. default:
  477. flag = true;
  478. }
  479. }
  480. n++;
  481. } until (flag || n == 32);
  482. if (base > 0) return -1;
  483. n--; if (n == 0) return -1;
  484. wn--;
  485. for (i=0 : i<n : i++) {
  486. acc = 0; if (InfixRV_types-->i ~= -3) acc = InfixRV_rvals-->i;
  487. InfixRV_op-->i = acc;
  488. }
  489. for (::) {
  490. ! for (i=0 : i<n : i++) {
  491. ! if (InfixRV_types-->i == -1) print InfixRV_rvals-->i, " ";
  492. ! else if (InfixRV_types-->i == -3) print " # ";
  493. ! else if (InfixRV_types-->i == -2) print " ## ";
  494. ! else print (address) InfixRV_rvals-->i, "_", InfixRV_types-->i, " ";
  495. ! }
  496. ! new_line;
  497. max = -2;
  498. for (i=0 : i<n : i++) if (InfixRV_types-->i > max) {
  499. max = InfixRV_types-->i; maxi = i; }
  500. if (max == -1) { parsed_number = InfixRV_rvals-->maxi; return 1; }
  501. lop = maxi-1; rop = maxi+1;
  502. while (lop >= 0 && InfixRV_types-->lop < -1) lop--;
  503. while (rop < n && InfixRV_types-->rop < -1) rop++;
  504. if (lop >= 0) InfixRV_lop-->maxi = InfixRV_rvals-->lop;
  505. if (rop < n) InfixRV_rop-->maxi = InfixRV_rvals-->rop;
  506. flag = false;
  507. infix_term_type = INFIXTT_NUMBER;
  508. switch (InfixRV_rvals-->maxi) {
  509. comma_word:
  510. acc = (InfixRV_rvals-->rop);
  511. '=//', 'pre++', 'post++', 'pre--', 'post--':
  512. lvalside = lop;
  513. switch (InfixRV_rvals-->maxi) {
  514. '=//': acc = (InfixRV_rvals-->rop);
  515. 'pre++': acc = (InfixRV_rvals-->rop) + 1; lvalside = rop;
  516. 'pre--': acc = (InfixRV_rvals-->rop) - 1; lvalside = rop;
  517. 'post++': acc = (InfixRV_rvals-->lop) + 1;
  518. 'post--': acc = (InfixRV_rvals-->lop) - 1;
  519. }
  520. switch (InfixRV_op-->lvalside) {
  521. THEN1__WD:
  522. (InfixRV_lop-->lvalside).(InfixRV_rop-->lvalside) = acc;
  523. '->':
  524. if (InfixInBounds(InfixRV_lop-->lvalside, InfixRV_rop-->lvalside))
  525. (InfixRV_lop-->lvalside)->(InfixRV_rop-->lvalside) = acc;
  526. '-->':
  527. if (InfixInBounds(InfixRV_lop-->lvalside, WORDSIZE * InfixRV_rop-->lvalside))
  528. (InfixRV_lop-->lvalside)-->(InfixRV_rop-->lvalside) = acc;
  529. default:
  530. w = InfixRV_lvals-->lvalside; if (w == -1) return -1;
  531. #ifdef TARGET_ZCODE;
  532. @storew #globals_array w acc;
  533. #ifnot;
  534. @astore #globals_array w acc;
  535. #endif;
  536. }
  537. switch(InfixRV_rvals-->maxi) {
  538. 'post++': acc--;
  539. 'post--': acc++;
  540. }
  541. '(rcall':
  542. sysfun_f = false;
  543. switch (InfixRV_op-->lop) {
  544. THEN1__WD:
  545. a = InfixRV_lop-->lop; b = InfixRV_rop-->lop;
  546. default:
  547. a = InfixRV_rvals-->lop; b = call;
  548. if (InfixRV_lvals-->lop == INFIXTT_SYSFUN)
  549. sysfun_f = true;
  550. }
  551. w = 0;
  552. i = maxi + 1; base = 100;
  553. if (InfixRV_types-->i == -1 && InfixRV_rvals-->i == ')//') {
  554. if (sysfun_f) return -1;
  555. acc = a.b();
  556. }
  557. else {
  558. while (base > 0) {
  559. if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == ')//') base = base - 100;
  560. if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == '(//') base = base + 100;
  561. if (InfixRV_op-->i == '(rcall') base = base + 100;
  562. if (base == 100 && InfixRV_op-->i == comma_word) {
  563. InfixRV_commas-->(w++) = i;
  564. ! print "Comma found at ", i, "^";
  565. }
  566. i++;
  567. }
  568. ! print "Num args = ", w + 1, "^";
  569. ! for (i=0 : i<w : i++)
  570. ! print "arg: ", InfixRV_lop-->(InfixRV_commas-->i), "^";
  571. ! print "arg: ", InfixRV_rvals-->rop, "^";
  572. switch (w+1) {
  573. 1:
  574. if (sysfun_f) {
  575. b = InfixRV_rvals-->rop;
  576. infix_term_type = INFIXTT_NAMEDOBJECT;
  577. switch(a) {
  578. 'metaclass':
  579. acc = metaclass(b);
  580. 'parent':
  581. acc = parent(b);
  582. 'child':
  583. acc = child(b);
  584. 'children':
  585. acc = children(b);
  586. infix_term_type = INFIXTT_NUMBER;
  587. 'random':
  588. acc = random(b);
  589. infix_term_type = INFIXTT_NUMBER;
  590. 'sibling':
  591. acc = sibling(b);
  592. }
  593. }
  594. else
  595. acc = a.b(InfixRV_rvals-->rop);
  596. 2:
  597. if (sysfun_f) return -1;
  598. acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  599. InfixRV_rvals-->rop);
  600. 3:
  601. if (sysfun_f) return -1;
  602. acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  603. InfixRV_lop-->(InfixRV_commas-->1),
  604. InfixRV_rvals-->rop);
  605. 4:
  606. if (sysfun_f) return -1;
  607. acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  608. InfixRV_lop-->(InfixRV_commas-->1),
  609. InfixRV_lop-->(InfixRV_commas-->2),
  610. InfixRV_rvals-->rop);
  611. 5:
  612. if (sysfun_f) return -1;
  613. acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  614. InfixRV_lop-->(InfixRV_commas-->1),
  615. InfixRV_lop-->(InfixRV_commas-->2),
  616. InfixRV_lop-->(InfixRV_commas-->3),
  617. InfixRV_rvals-->rop);
  618. default:
  619. return -1;
  620. }
  621. }
  622. '+//': acc = (InfixRV_rvals-->lop) + (InfixRV_rvals-->rop);
  623. '-//': acc = (InfixRV_rvals-->lop) - (InfixRV_rvals-->rop);
  624. '*//': acc = (InfixRV_rvals-->lop) * (InfixRV_rvals-->rop);
  625. '@{2f}//': acc = (InfixRV_rvals-->lop) / (InfixRV_rvals-->rop);
  626. '%//': acc = (InfixRV_rvals-->lop) % (InfixRV_rvals-->rop);
  627. THEN1__WD: acc = (InfixRV_rvals-->lop) . (InfixRV_rvals-->rop);
  628. '->': acc = (InfixRV_rvals-->lop) -> (InfixRV_rvals-->rop);
  629. '-->': acc = (InfixRV_rvals-->lop) --> (InfixRV_rvals-->rop);
  630. ']&': acc = (InfixRV_rvals-->lop) .& (InfixRV_rvals-->rop);
  631. ']#': acc = (InfixRV_rvals-->lop) .# (InfixRV_rvals-->rop);
  632. '::': acc = (InfixRV_rvals-->lop) :: (InfixRV_rvals-->rop);
  633. '&//': acc = (InfixRV_rvals-->lop) & (InfixRV_rvals-->rop);
  634. '|//': acc = (InfixRV_rvals-->lop) | (InfixRV_rvals-->rop);
  635. '&&': acc = (InfixRV_rvals-->lop) && (InfixRV_rvals-->rop);
  636. infix_term_type = INFIXTT_LOGICAL;
  637. '||': acc = (InfixRV_rvals-->lop) || (InfixRV_rvals-->rop);
  638. infix_term_type = INFIXTT_LOGICAL;
  639. '<//': acc = (InfixRV_rvals-->lop) < (InfixRV_rvals-->rop);
  640. infix_term_type = INFIXTT_LOGICAL;
  641. '<=': acc = (InfixRV_rvals-->lop) <= (InfixRV_rvals-->rop);
  642. infix_term_type = INFIXTT_LOGICAL;
  643. '>//': acc = (InfixRV_rvals-->lop) > (InfixRV_rvals-->rop);
  644. infix_term_type = INFIXTT_LOGICAL;
  645. '>=': acc = (InfixRV_rvals-->lop) >= (InfixRV_rvals-->rop);
  646. infix_term_type = INFIXTT_LOGICAL;
  647. '==': acc = (InfixRV_rvals-->lop) == (InfixRV_rvals-->rop);
  648. infix_term_type = INFIXTT_LOGICAL;
  649. '[=': acc = (InfixRV_rvals-->lop) ~= (InfixRV_rvals-->rop);
  650. infix_term_type = INFIXTT_LOGICAL;
  651. 'has': acc = (InfixRV_rvals-->lop) has (InfixRV_rvals-->rop);
  652. infix_term_type = INFIXTT_LOGICAL;
  653. 'hasnt': acc = (InfixRV_rvals-->lop) hasnt (InfixRV_rvals-->rop);
  654. infix_term_type = INFIXTT_LOGICAL;
  655. 'in': acc = (InfixRV_rvals-->lop) in (InfixRV_rvals-->rop);
  656. infix_term_type = INFIXTT_LOGICAL;
  657. 'notin': acc = (InfixRV_rvals-->lop) notin (InfixRV_rvals-->rop);
  658. infix_term_type = INFIXTT_LOGICAL;
  659. 'provides': acc = (InfixRV_rvals-->lop) provides (InfixRV_rvals-->rop);
  660. infix_term_type = INFIXTT_LOGICAL;
  661. 'ofclass': acc = (InfixRV_rvals-->lop) ofclass (InfixRV_rvals-->rop);
  662. infix_term_type = INFIXTT_LOGICAL;
  663. '[[': acc = ~~ (InfixRV_rvals-->rop); flag = true;
  664. '[//': acc = ~ (InfixRV_rvals-->rop); flag = true;
  665. 'unary-': acc = - (InfixRV_rvals-->rop); flag = true;
  666. } ! end of switch(InfixRV_rvals-->maxi)
  667. InfixRV_rvals-->maxi = acc;
  668. InfixRV_types-->maxi = -1;
  669. if (rop < n) InfixRV_types-->rop = -2;
  670. if (flag == false && lop >= 0) InfixRV_types-->lop = -2;
  671. } ! end of for (::)
  672. ]; ! end of InfixRvalue
  673. ! ------------------------------------------------------------------------
  674. [ InfixWelcomeSub;
  675. print "; Welcome to the ~Infix~ debugger (1/040828), which makes the
  676. following verbs available:^^
  677. ~; <expression>~: evaluates this Inform expression: e.g.
  678. ~; location~ will print the value of the variable ~location~,
  679. ~; 3*5+1~ will print 16, ~; children(old cloth bag)~ will tell you
  680. how many items are in it. (You can name objects either by their
  681. names inside the source code, such as ~d_obj~, or by typing the
  682. names by which the game's parser would normally know them, such
  683. as ~floor~: the effect is the same.)^
  684. Any expression is allowed except that you can't use double-quoted
  685. strings of text: but you can send messages, call routines or
  686. assign values to variables, properties and array entries.
  687. ^ ~; score++~ is one way to get on in the world.
  688. ^ ~; deadflag = true~ is one way to get out of it.
  689. ^ ~; StopDaemon(nasty little dwarf)~ will keep you from being pestered.^
  690. Conditions like ~; score>20~ are also allowed and print
  691. either 1 (if true) or 0 (if false).^^";
  692. print "~;examine <something>~ or ~;x <something>~ gives full details
  693. of whatever it is. For instance, ~;x ##Take~ describes the Take
  694. action; ~;x Class~ the class Class; ~;x 'drop'~ the dictionary
  695. word ~drop~ and so on for numbers, routines, arrays and of course
  696. objects. ~;xo~ examines something as an object, so for instance
  697. ~;x location~ tells you about the variable ~location~, but ~;xo
  698. location~ tells you what object it refers to.^^";
  699. print "~;give~, ~;remove~ and ~;move~ work like the corresponding
  700. Inform statements.^^";
  701. print "~;<~ causes an action: for instance, ~;< Eat cheese~.^^";
  702. print "~;watch~ or ~;w~ can set a watch on various activities:
  703. type just ~;w~ for details.^^";
  704. print "~;inventory~ or ~;i~ describes the contents of this story file.^";
  705. ];
  706. [ InfixEvalSub; InfixExamineP(true); ];
  707. [ InfixActionSub;
  708. print "; <", (InfixPrintAction) infix_lvalue;
  709. if (noun) print " (", (the) noun, ")";
  710. if (second) print " (", (the) second, ")";
  711. print ">^";
  712. if (second) <<(infix_lvalue) noun second>>;
  713. if (noun) <<(infix_lvalue) noun>>;
  714. <<(infix_lvalue)>>;
  715. ];
  716. [ InfixGiveSub f t;
  717. print "; give (", (the) noun, ") ";
  718. if (second < 0) { second = ~second; f=true; }
  719. #Ifdef VN_1630;
  720. t = NUM_ATTR_BYTES * 8;
  721. #Ifnot;
  722. t = 48;
  723. #Endif; ! VN_
  724. if (second < 0 || second >= t) "<No such attribute>";
  725. if (f) print "@@126";
  726. print (DebugAttribute) second;
  727. #Ifdef TARGET_ZCODE;
  728. if (f) @clear_attr noun second;
  729. else @set_attr noun second;
  730. #Ifnot; ! TARGET_GLULX
  731. t = second + 8;
  732. if (f) @astorebit noun t 0; ! give noun ~second;
  733. else @astorebit noun t 1; ! give noun second;
  734. #Endif; ! TARGET_
  735. if (t); ! quell unused n variable warning
  736. ];
  737. [ InfixMoveSub;
  738. print "; move (", (the) noun, ") to (", (the) second, ")";
  739. move noun to second;
  740. ];
  741. [ InfixRemoveSub;
  742. print "; remove (", (the) noun, ")";
  743. remove noun;
  744. ];
  745. [ InfixHex x y;
  746. #Ifdef TARGET_ZCODE;
  747. y = (x & $7f00) / $100;
  748. if (x < 0) y = y + $80;
  749. #Ifnot; ! TARGET_GLULX
  750. y = (x & $7f000000) / $1000000;
  751. if (x < 0) y = y + $80;
  752. print (Infixhexdigit) y/$10, (Infixhexdigit) y;
  753. y = x & $ff0000 / $10000;
  754. print (Infixhexdigit) y/$10, (Infixhexdigit) y;
  755. y = (x & $ff00) / $100;
  756. #Endif; ! TARGET_
  757. x = x & $ff;
  758. print (Infixhexdigit) y/$10, (Infixhexdigit) y, (Infixhexdigit) x/$10, (Infixhexdigit) x;
  759. ];
  760. [ Infixhexdigit x; x = x % $10; if (x < 10) print x; else print (char) 'a'+x-10; ];
  761. [ InfixExamineOSub;
  762. infix_data1 = metaclass(noun);
  763. #Ifdef TARGET_GLULX; ! different coding for Glulx
  764. if (infix_data1 == Object) infix_data1 = 2;
  765. if (infix_data1 == Class) infix_data1 = 1;
  766. #Endif; ! TARGET_
  767. infix_term_type = INFIXTT_CONSTANT;
  768. InfixExamineP(false);
  769. ];
  770. [ InfixExamineSSub;
  771. infix_term_type = INFIXTT_STATICSTRING;
  772. InfixExamineP(false);
  773. ];
  774. [ InfixExamineSub; InfixExamineP(false); ];
  775. [ InfixExamineP brief x a b w flag lines;
  776. switch (infix_term_type) {
  777. INFIXTT_NUMBER:
  778. if (brief) "; == ", noun;
  779. print "; The number ", noun, " == $", (InfixHex) noun;
  780. if (noun >= 32 && noun < 127) print " == '", (char) noun, "'";
  781. new_line;
  782. INFIXTT_NAMEDOBJECT:
  783. print "~", (name) noun, "~ (", noun, ")^"; if (brief) return;
  784. <<Showobj noun>>;
  785. INFIXTT_CONSTANT:
  786. if (brief) "; == ", noun;
  787. switch (infix_data1 & 15) {
  788. nothing:
  789. print "; Constant ", (InfixPrintConstant) infix_parsed_lvalue,
  790. " == ", noun, "^";
  791. 2: <<Showobj noun>>;
  792. 1:
  793. print "Class ", (name) noun, "^";
  794. objectloop (a ofclass noun) {
  795. if (flag) print ", "; else print "Contains: ";
  796. print (name) a, " (", a, ")"; flag=true;
  797. }
  798. if (flag == false) "No object is of this class";
  799. }
  800. new_line;
  801. INFIXTT_ATTRIBUTE:
  802. if (brief) "; == ", noun;
  803. if (noun >= 48 || noun < 0) "; No such attribute";
  804. print "; Attribute ", (InfixPrintAttribute) noun,
  805. " (numbered ", noun, ")^";
  806. objectloop (x has noun) {
  807. if (flag) print ", ";
  808. else print "Each of these ~has ", (InfixPrintAttribute) noun, "~: ";
  809. print (name) x, " (", x, ")"; flag = true;
  810. }
  811. if (flag == false) "No object ~has ", (InfixPrintAttribute) noun, "~";
  812. new_line;
  813. INFIXTT_PROPERTY:
  814. if (brief) "; == ", noun;
  815. print "; Property ", (property) noun, " (numbered ", noun, ")^";
  816. objectloop (x provides noun) {
  817. if (flag) print ", "; else print "Provided by: ";
  818. print (name) x, " (", x, ")"; flag = true;
  819. }
  820. if (flag == false) "Which is not provided by any object";
  821. new_line;
  822. INFIXTT_DWORD:
  823. if (brief) "; == ", noun;
  824. if (noun == 0) "; This word is not in the dictionary";
  825. a = noun->#dict_par1;
  826. print "; Dictionary word '", (address) noun;
  827. if (a & 4) print "//p";
  828. print "' (address ", noun, ")";
  829. if (a) {
  830. print ": ";
  831. if (a & 2) print "meta ";
  832. if (a & 1) print "verb ";
  833. if (a & 8) print "preposition ";
  834. if (a & 4) print "pluralising ";
  835. if (a & 128) print "noun ";
  836. }
  837. new_line;
  838. if (a & 1) <<Showverb noun>>;
  839. INFIXTT_ROUTINE:
  840. if (brief) "; == ", noun;
  841. print "; Routine ", (InfixPrintRoutine) infix_parsed_lvalue, " (number ",
  842. infix_parsed_lvalue, ", packed address ", noun, ")^";
  843. INFIXTT_GLOBAL:
  844. if (brief) "; == ", noun;
  845. print "; Global ", (InfixPrintGlobal) infix_parsed_lvalue, " == ", noun, "^";
  846. INFIXTT_ARRAY:
  847. if (brief) "; == ", noun;
  848. print "; Array ", (InfixPrintArray) infix_parsed_lvalue, " ";
  849. infix_data1 = infix_data1 % 16;
  850. switch (infix_data1) {
  851. 0: print "->"; a=0;
  852. 1: print "-->"; a=0;
  853. 2: print "string"; a=1;
  854. 3: print "table"; a=1;
  855. 4: print "buffer"; a=WORDSIZE;
  856. }
  857. print " ", infix_data2 + 1 - a, "^; == "; b = infix_data2;
  858. for (w=b : w>=a : w--)
  859. if (infix_data1 == 0 or 2 or 4) { if (noun->w) break; }
  860. else { if (noun-->w) break; }
  861. if (b-w < 5) w=b;
  862. for (: x<=w : x++) {
  863. if (infix_data1 == 0 or 2 or 4) print noun->x, " ";
  864. else print noun-->x, " ";
  865. if (x+1 == a) print ": ";
  866. }
  867. if (w < b) print "(then ", b-w, " zero entries)";
  868. new_line;
  869. INFIXTT_ACTION:
  870. if (brief) "; == ", noun;
  871. if (noun >= #lowest_fake_action_number && noun <= #highest_fake_action_number)
  872. "; Fake action ", (InfixPrintFakeAction) noun,
  873. " (numbered ", noun, ")^Is not generated by any grammar";
  874. print "; Action ", (InfixPrintAction) noun,
  875. " (numbered ", noun, ")^";
  876. #Ifdef TARGET_ZCODE;
  877. w = HDR_DICTIONARY-->0;
  878. for (b=0 : b<(HDR_DICTIONARY-->0 + 5)-->0 : b++) {
  879. w = HDR_DICTIONARY-->0 + 7 + b*9;
  880. if ((w->#dict_par1) & 1) {
  881. a = (HDR_STATICMEMORY-->0)-->($ff-(w->#dict_par2));
  882. lines = a->0; a++;
  883. for (: lines>0 : lines--) {
  884. a = UnpackGrammarLine(a);
  885. if (action_to_be == noun) {
  886. print "'", (address) w, "' "; DebugGrammarLine();
  887. new_line;
  888. flag = true;
  889. }
  890. }
  891. }
  892. }
  893. #Ifnot; ! TARGET_GLULX
  894. for (b=0 : b < #dictionary_table-->0 : b++) {
  895. w = #dictionary_table + WORDSIZE + b*(DICT_WORD_SIZE + 7);
  896. if ((w->#dict_par1) & 1) {
  897. a = (#grammar_table)-->($100-(w->#dict_par2));
  898. lines = a->0; a++;
  899. for (: lines>0 : lines--) {
  900. a = UnpackGrammarLine(a);
  901. if (action_to_be == noun) {
  902. print "'", (address) w, "' "; DebugGrammarLine();
  903. new_line;
  904. flag = true;
  905. }
  906. }
  907. }
  908. }
  909. #Endif; ! TARGET_
  910. if (flag == 0) "Is not generated by any grammar";
  911. INFIXTT_SYSFUN:
  912. if (brief) "; == ", noun;
  913. "; System function ~", (address) infix_parsed_lvalue, "~ has
  914. not been overridden by any routine and so has its standard definition.";
  915. INFIXTT_STATICSTRING:
  916. if (brief) "; == ", noun;
  917. if (metaclass(noun) ~= String) "; ", noun, " is not a string.";
  918. print "~", (string) noun, "~^";
  919. INFIXTT_LOGICAL:
  920. if (noun == true) "; true"; if (noun == false) "; false";
  921. "; ", noun;
  922. }
  923. ]; ! end of InfixExamineP
  924. [ InfixDescribeWatchSub x y z s flag aflag;
  925. print "; The Infix ~;watch~ verb allows you to set a watch on any named
  926. routine(s) or objects: for instance ~;watch ScoreSub~ or
  927. ~;watch silver bars~. You can also:
  928. ^ ~;watch objects~: changes to attribute or property settings";
  929. if (debug_flag & 8) print " (on)"; else print " (off)";
  930. print ";^ ~;watch timers~: the running of timers and daemons each turn";
  931. if (debug_flag & 4) print " (on)"; else print " (off)";
  932. print ";^ ~;watch messages~: all messages sent";
  933. if (debug_flag & 1) print " (on)"; else print " (off)";
  934. print ";^ ~;watch actions~: all actions generated";
  935. if (debug_flag & 2) print " (on)"; else print " (off)";
  936. print ".^~~;watch~ can be abbreviated to ~;w~ and use ~off~ to stop
  937. watching: for instance ~;w location off~.^";
  938. aflag = debug_flag;
  939. objectloop (x has infix__watching) flag = true; aflag = aflag || flag;
  940. if (flag) print "The following objects are currently being watched: ";
  941. flag = false;
  942. objectloop (x has infix__watching) {
  943. if (flag) print ", "; flag = true;
  944. print (name) x, " (", x, ")";
  945. }
  946. if (flag) new_line;
  947. s = (#highest_routine_number - #lowest_routine_number);
  948. if (s%8 == 0) s=s/8; else s=s/8+1;
  949. for (flag=false,x=0 : x<s : x++) if (#routine_flags_array->x) flag = true;
  950. aflag = aflag || flag;
  951. if (flag) print "The following routines are currently being watched: ";
  952. for (x=0,flag=false : x<s : x++) {
  953. for (y=1,z=0 : y<256 : z++,y=y*2) {
  954. if ((#routine_flags_array->x) & y) {
  955. if (flag) print ", "; flag = true;
  956. print (InfixPrintRoutine)
  957. #lowest_routine_number + x*8 + z;
  958. }
  959. }
  960. }
  961. if (flag) new_line;
  962. if (aflag == false) "At present, nothing is being watched.";
  963. ];
  964. [ InfixWatchOnSub i j k l;
  965. if (noun == 0) return InfixDescribeWatchSub();
  966. if (infix_term_type == INFIXTT_ROUTINE) {
  967. i = infix_parsed_lvalue/8;
  968. for (j=0,k=1 : j<infix_parsed_lvalue%8 : j++) k=k*2;
  969. l = #routine_flags_array->i;
  970. l = l | k;
  971. #ifdef TARGET_ZCODE;
  972. @storeb #routine_flags_array i l;
  973. #ifnot; ! TARGET_GLULX
  974. @astoreb #routine_flags_array i l;
  975. #endif; ! TARGET_
  976. "; Watching routine ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  977. }
  978. if (metaclass(noun) == Object) {
  979. give noun infix__watching;
  980. "; Watching object ~", (name) noun, "~ (", noun, ").";
  981. }
  982. InfixDescribeWatchSub();
  983. ];
  984. [ InfixWatchOffSub i j k l;
  985. if (noun == 0) return InfixDescribeWatchSub();
  986. if (infix_term_type == INFIXTT_ROUTINE) {
  987. i = infix_parsed_lvalue/8;
  988. for (j=0,k=1 : j<infix_parsed_lvalue%8 : j++) k=k*2;
  989. l = #routine_flags_array->i;
  990. l = l & (~k);
  991. #ifdef TARGET_ZCODE;
  992. @storeb #routine_flags_array i l;
  993. #ifnot; ! TARGET_GLULX
  994. @astoreb #routine_flags_array i l;
  995. #endif; ! TARGET
  996. "; Not watching ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  997. }
  998. if (metaclass(noun) == Object) {
  999. #ifdef TARGET_ZCODE;
  1000. @clear_attr noun infix__watching;
  1001. #ifnot; ! TARGET_GLULX
  1002. @astorebit noun (infix__watching+8) 0;
  1003. #endif; ! TARGET_
  1004. "; Not watching object ~", (name) noun, "~ (", noun, ").";
  1005. }
  1006. InfixDescribeWatchSub();
  1007. ];
  1008. [ InfixList from to tab filter i flag;
  1009. print "^ ";
  1010. for (i=from : i<=to : i++)
  1011. if (tab-->(i-from)) {
  1012. flag = true;
  1013. if (tab == #array_names_array) {
  1014. Symb__Tab(INFIXTT_ARRAY, i);
  1015. flag = ~~(temp__global3 & 16);
  1016. }
  1017. if (tab == #routine_names_array) {
  1018. Symb__Tab(INFIXTT_ROUTINE,i);
  1019. flag = ~~(temp__global3 & 16);
  1020. }
  1021. if (tab == #constant_names_array) {
  1022. Symb__Tab(INFIXTT_CONSTANT,i);
  1023. flag = (~~(temp__global3 & 16)) && (temp__global3 % 16 == filter);
  1024. }
  1025. if (flag) print (string) tab-->(i-from), " ";
  1026. }
  1027. new_line;
  1028. ];
  1029. [ InfixInvSub i;
  1030. print (string) Story, (string) Headline;
  1031. print " ", (number) #highest_object_number - #lowest_object_number + 1,
  1032. " objects;^";
  1033. print " non-library object-name constants:";
  1034. InfixList(#lowest_constant_number, #highest_constant_number, #constant_names_array, 2);
  1035. print " ", (number) #highest_class_number - #lowest_class_number + 1, " classes:^ ";
  1036. for (i=#lowest_class_number : i<=#highest_class_number : i++)
  1037. print (name) #class_objects_array-->i, " ";
  1038. new_line;
  1039. print " non-library arrays:";
  1040. InfixList(#lowest_array_number, #highest_array_number, #array_names_array);
  1041. print " non-library routines:";
  1042. InfixList(#lowest_routine_number, #highest_routine_number, #routine_names_array);
  1043. print " non-library constants:";
  1044. InfixList(#lowest_constant_number, #highest_constant_number, #constant_names_array, 0);
  1045. print " (common) properties:";
  1046. #Ifdef TARGET_ZCODE;
  1047. InfixList(#lowest_property_number, INDIV_PROP_START-1, #property_names_array);
  1048. #Ifnot; ! TARGET_GLULX
  1049. InfixList(#lowest_property_number, #identifiers_table-->1 - 1, #property_names_array);
  1050. #Endif; ! TARGET_
  1051. print " (individual) properties:";
  1052. #Ifdef TARGET_ZCODE;
  1053. InfixList(INDIV_PROP_START, #highest_property_number, #property_names_array + 126);
  1054. #Ifnot; ! TARGET_GLULX
  1055. InfixList(INDIV_PROP_START, #highest_property_number, #identifiers_table-->2);
  1056. #Endif; ! TARGET_
  1057. print " attributes:";
  1058. InfixList(#lowest_attribute_number, #highest_attribute_number, #attribute_names_array);
  1059. if (true) return;
  1060. print " variables:";
  1061. InfixList(#lowest_global_number, #highest_global_number, #global_names_array);
  1062. print " actions:";
  1063. InfixList(#lowest_action_number, #highest_action_number, #action_names_array);
  1064. print " fake actions:";
  1065. InfixList(#lowest_fake_action_number, #highest_fake_action_number, #fake_action_names_array);
  1066. ];
  1067. Verb meta ';i' ';inv' ';inventory'
  1068. * -> InfixInv;
  1069. Verb meta ';x' ';examine'
  1070. * InfixRvalue -> InfixExamine;
  1071. Verb meta ';xo' ';examineo'
  1072. * InfixRvalue -> InfixExamineO;
  1073. Verb meta ';xs' ';examines'
  1074. * InfixRvalue -> InfixExamineS;
  1075. Verb meta ';<'
  1076. * InfixActionToken -> InfixAction
  1077. * InfixActionToken InfixRvalue -> InfixAction
  1078. * InfixActionToken InfixRvalue InfixRvalue -> InfixAction;
  1079. Verb meta ';//'
  1080. * -> InfixWelcome
  1081. * InfixRvalue -> InfixEval;
  1082. Verb meta ';give'
  1083. * InfixRvalue InfixRvalue -> InfixGive;
  1084. Verb meta ';move'
  1085. * InfixRvalue "to" InfixRvalue -> InfixMove;
  1086. Verb meta ';remove'
  1087. * InfixRvalue -> InfixRemove;
  1088. Verb meta ';watch' ';w'
  1089. * -> InfixWatchOn
  1090. * "timers"/"daemons" -> TimersOn
  1091. * "timers"/"daemons" "off" -> TimersOff
  1092. * "actions" -> ActionsOn
  1093. * "actions" "off" -> ActionsOff
  1094. * "messages" -> RoutinesOn
  1095. * "messages" "off" -> RoutinesOff
  1096. * "objects" -> ChangesOn
  1097. * "objects" "off" -> ChangesOff
  1098. * InfixRvalueTerm -> InfixWatchOn
  1099. * InfixRvalueTerm "off" -> InfixWatchOff;
  1100. #Endif; ! DEBUG
  1101. ! ==============================================================================