| Back to List Inventory Complete Plain Coloured Gaudy |
Browsing infix.h
This is the complete source code of the example game infix.inf.
0001 ! ==============================================================================
0002 ! INFIX: Support for the optional library debugger extension "Infix".
0003 !
0004 ! Supplied for use with Inform 6 -- Release 6/11 -- Serial number 040227
0005 !
0006 ! Copyright Graham Nelson 1993-2004 but freely usable (see manuals)
0007 !
0008 ! This file is automatically Included in your game file by "Grammar" if you
0009 ! supply the -X compiler switch.
0010 ! ==============================================================================
0011
0012 System_file;
0013
0014 ! ------------------------------------------------------------------------------
0015
0016 #Ifdef DEBUG;
0017
0018 Constant INFIXTT_NUMBER 0;
0019 Constant INFIXTT_ARRAY 1;
0020 Constant INFIXTT_ROUTINE 2;
0021 Constant INFIXTT_CONSTANT 3;
0022 Constant INFIXTT_DWORD 4;
0023 Constant INFIXTT_ACTION 5;
0024 Constant INFIXTT_ATTRIBUTE 6;
0025 Constant INFIXTT_PROPERTY 7;
0026 Constant INFIXTT_GLOBAL 8;
0027 Constant INFIXTT_NAMEDOBJECT 9;
0028 Constant INFIXTT_SYSFUN 10;
0029 Constant INFIXTT_STATICSTRING 11;
0030 Constant INFIXTT_LOGICAL 12;
0031
0032 Global infix_term_type;
0033 Global infix_data1;
0034 Global infix_data2;
0035 Global infix_lvalue;
0036 Global infix_parsed_lvalue;
0037 Array infix_tolowercase -> 256;
0038 #Ifdef VN_1630;
0039 Array infix_text buffer 126;
0040 #Ifnot;
0041 Array infix_text -> 128;
0042 #Endif; ! VN_
0043
0044
0045 [ InfixPrintAttribute x; print (string) #attribute_names_array-->x; ];
0046
0047 [ InfixPrintProperty x; print (property) x; ];
0048
0049 [ InfixPrintGlobal x; print (string) #global_names_array-->x; ];
0050
0051 [ InfixPrintAction x; print (string) #action_names_array-->(x-#lowest_action_number); ];
0052
0053 [ InfixPrintRoutine x; print (string) #routine_names_array-->(x-#lowest_routine_number); ];
0054
0055 [ InfixPrintConstant x; print (string) #constant_names_array-->(x-#lowest_constant_number); ];
0056
0057 [ InfixPrintArray x; print (string) #array_names_array-->(x-#lowest_array_number); ];
0058
0059 [ InfixPrintFakeAction x;
0060 print (string) #fake_action_names_array-->(x-#lowest_fake_action_number); ];
0061
0062 [ InfixPrintPA x n;
0063 for (n=#lowest_routine_number : n<=#highest_routine_number : n++) {
0064 if (x == Symb__Tab(INFIXTT_ROUTINE, n)) {
0065 print (InfixPrintRoutine) n; return;
0066 }
0067 }
0068 print "Routine(", x, ")";
0069 ];
0070
0071 [ InfixMatchPrule PrintingRule range1 range2 wa wl t i i2 it2 itlc j k plus;
0072 itlc = infix_tolowercase;
0073 if (itlc->255 == 0) {
0074 for (j=0 : j<256 : j++) itlc->j = j;
0075 itlc->'A' = 'a'; itlc->'B' = 'b';
0076 itlc->'C' = 'c'; itlc->'D' = 'd';
0077 itlc->'E' = 'e'; itlc->'F' = 'f';
0078 itlc->'G' = 'g'; itlc->'H' = 'h';
0079 itlc->'I' = 'i'; itlc->'J' = 'j';
0080 itlc->'K' = 'k'; itlc->'L' = 'l';
0081 itlc->'M' = 'm'; itlc->'N' = 'n';
0082 itlc->'O' = 'o'; itlc->'P' = 'p';
0083 itlc->'Q' = 'q'; itlc->'R' = 'r';
0084 itlc->'S' = 's'; itlc->'T' = 't';
0085 itlc->'U' = 'u'; itlc->'V' = 'v';
0086 itlc->'W' = 'w'; itlc->'X' = 'x';
0087 itlc->'Y' = 'y'; itlc->'Z' = 'z';
0088 }
0089 switch(PrintingRule) {
0090 InfixPrintAttribute:
0091 if (wa->0 == '~') { wl--; wa++; plus = 100; } ! A tilde
0092 t = #attribute_names_array;
0093 InfixPrintProperty: t = #property_names_array;
0094 InfixPrintAction: t = #action_names_array;
0095 InfixPrintFakeAction: t = #fake_action_names_array;
0096 InfixPrintGlobal: t = #global_names_array;
0097 InfixPrintRoutine: t = #routine_names_array;
0098 InfixPrintAction: t = #constant_names_array;
0099 InfixPrintArray: t = #array_names_array;
0100 }
0101
0102 i2 = range2-range1; it2 = infix_text+2;
0103 for (i=0 : i<=i2 : i++) {
0104 infix_text-->0 = 62; @output_stream 3 infix_text;
0105 if (t) print (string) t-->i; else PrintingRule(i+range1);
0106 @output_stream -3;
0107 k = infix_text-->0;
0108 if (k ~= wl) jump XL;
0109 if (itlc->(it2->0) ~= wa->0) jump XL;
0110 for (j=1 : j<k : j++)
0111 if (itlc->(it2->j) ~= wa->j) jump XL;
0112 parsed_number = i + range1 + plus;
0113 rtrue;
0114 .XL;
0115 }
0116 rfalse;
0117 ];
0118
0119 [ InfixActionToken;
0120 if (InfixMatchPrule(InfixPrintAction, #lowest_action_number,
0121 #highest_action_number, WordAddress(wn), WordLength(wn))) {
0122 wn++; infix_lvalue = parsed_number; return 0;
0123 }
0124 if (InfixMatchPrule(InfixPrintFakeAction, #lowest_fake_action_number,
0125 #highest_fake_action_number, WordAddress(wn), WordLength(wn))) {
0126 wn++; infix_lvalue = parsed_number; return 0;
0127 }
0128 return -1;
0129 ];
0130
0131 [ InfixRvalueTerm n w i initial_wn wa wl sign base digit dcount;
0132
0133 initial_wn = wn;
0134
0135 infix_parsed_lvalue = -1;
0136 infix_term_type = INFIXTT_NUMBER;
0137
0138 w = NextWordStopped();
0139 if (w == -1) return -1;
0140
0141 wa = WordAddress(wn-1);
0142 wl = WordLength(wn-1);
0143 if (wa->0 == '-' or '$' or '0' or '1' or '2' or '3'
0144 or '4' or '5' or '6' or '7' or '8' or '9') {
0145 ! Parse decimal, hex or binary number
0146
0147 sign = 1; base = 10; dcount = 0;
0148 if (wa->0 == '-') { sign = -1; wl--; wa++; }
0149 else {
0150 if (wa->0 == '$') { base = 16; wl--; wa++; }
0151 if (wa->0 == '$') { base = 2; wl--; wa++; }
0152 }
0153 if (wl == 0) return -1;
0154 n = 0;
0155 while (wl > 0) {
0156 if (wa->0 >= 'a') digit = wa->0 - 'a' + 10;
0157 else digit = wa->0 - '0';
0158 dcount++;
0159 switch (base) {
0160 2:
0161 if (dcount == 17) return -1;
0162 10:
0163 if (dcount == 6) return -1;
0164 if (dcount == 5) {
0165 if (n > 3276) return -1;
0166 if (n == 3276) {
0167 if (sign == 1 && digit > 7) return -1;
0168 if (sign == -1 && digit > 8) return -1;
0169 }
0170 }
0171 16:
0172 if (dcount == 5) return -1;
0173 }
0174 if (digit >= 0 && digit < base) n = base*n + digit;
0175 else return -1;
0176 wl--; wa++;
0177 }
0178 parsed_number = n*sign; return 1;
0179 }
0180
0181 ! Parse character constant 'a'
0182
0183 if (wl == 3 && wa->0 == ''' && wa->2 == ''') {
0184 parsed_number = wa->1; return 1;
0185 }
0186
0187 ! ##Action, 'dword'
0188
0189 switch (w) {
0190 '##':
0191 infix_term_type = INFIXTT_ACTION;
0192 w = NextWordStopped(); if (w == -1) return -1;
0193 wn--;
0194 if (InfixActionToken() == 0) return 1;
0195 return -1;
0196 '^^':
0197 infix_term_type = INFIXTT_DWORD;
0198 w = NextWordStopped(); if (w == -1) return -1;
0199 parsed_number = w; return 1;
0200 }
0201
0202 ! Test for attribute, property, class name, variable name, array name, routine
0203 ! name, constant name
0204
0205 wn--;
0206 if ((wa->0 >= 'a' && wa->0 <= 'z') ||
0207 (wa->0 >= 'A' && wa->0 <= 'Z') ||
0208 wa->0 == '_') {
0209
0210
0211 infix_term_type = INFIXTT_ATTRIBUTE;
0212 if (InfixMatchPrule(InfixPrintAttribute, #lowest_attribute_number,
0213 #highest_attribute_number, wa, wl)) {
0214 wn++; return 1; }
0215
0216 infix_term_type = INFIXTT_PROPERTY;
0217 if (InfixMatchPrule(InfixPrintProperty, #lowest_property_number,
0218 #highest_property_number, wa, wl)) {
0219 wn++; return 1; }
0220
0221 infix_term_type = INFIXTT_GLOBAL;
0222 if (InfixMatchPrule(InfixPrintGlobal, #lowest_global_number,
0223 #highest_global_number, wa, wl)) {
0224 infix_parsed_lvalue = parsed_number-16;
0225 parsed_number = #globals_array-->infix_parsed_lvalue;
0226 wn++; return 1;
0227 }
0228
0229 infix_term_type = INFIXTT_ARRAY;
0230 if (InfixMatchPrule(InfixPrintArray, #lowest_array_number,
0231 #highest_array_number, wa, wl)) {
0232 infix_parsed_lvalue = parsed_number;
0233 parsed_number = Symb__Tab(INFIXTT_ARRAY,parsed_number);
0234 infix_data1 = temp__global3;
0235 infix_data2 = temp__global2;
0236 wn++; return 1;
0237 }
0238
0239 infix_term_type = INFIXTT_ROUTINE;
0240 if (InfixMatchPrule(InfixPrintRoutine, #lowest_routine_number,
0241 #highest_routine_number, wa, wl)) {
0242 infix_parsed_lvalue = parsed_number;
0243 parsed_number = Symb__Tab(INFIXTT_ROUTINE,parsed_number);
0244 infix_data1 = temp__global3;
0245 infix_data2 = temp__global2;
0246 wn++; return 1;
0247 }
0248
0249 infix_term_type = INFIXTT_CONSTANT;
0250 if (InfixMatchPrule(InfixPrintConstant, #lowest_constant_number,
0251 #highest_constant_number, wa, wl)) {
0252 infix_parsed_lvalue = parsed_number;
0253 parsed_number = Symb__Tab(INFIXTT_CONSTANT,parsed_number);
0254 infix_data1 = temp__global3;
0255 infix_data2 = temp__global2;
0256 wn++; return 1;
0257 }
0258
0259 switch (w) {
0260 'parent', 'child', 'children',
0261 'random', 'metaclass', 'sibling':
0262 parsed_number = w;
0263 infix_parsed_lvalue = INFIXTT_SYSFUN;
0264 wn++; return 1;
0265 }
0266 }
0267
0268 infix_term_type = INFIXTT_NAMEDOBJECT;
0269
0270 wn = initial_wn; i = ParseToken(SCOPE_TT, InfixBigScope);
0271
0272 if (i == GPR_REPARSE) return i;
0273 if (i > GPR_MULTIPLE) {
0274 print "(", (name) i, " (", i, "))^";
0275 parsed_number = i; return 1;
0276 }
0277 return -1;
0278 ]; ! end of InfixRvalueTerm
0279
0280 [ InfixBigScope x;
0281 if (scope_stage == 1) return false; ! No multiples here
0282 if (scope_stage == 2) {
0283 objectloop (x ofclass Object) PlaceInScope(x);
0284 return true; ! That's the whole scope
0285 }
0286 print "; I'm unable to make any sense of that term.^";
0287 ];
0288
0289 [ InfixCheckLineSpaced wa wl i force altered;
0290 for (i=1 : i<=parse->1 : i++) {
0291 wa = WordAddress(i);
0292 wl = WordLength(i);
0293 if (wl > 3 && wa->0 == ''' && wa->(wl-1) == ''') {
0294 wa->(wl-1) = ' ';
0295 if (wa->(wl-2) == '/' && wa->(wl-3) == '/') {
0296 wa->(wl-2) = ' ';
0297 wa->(wl-3) = ' ';
0298 }
0299 LTI_Insert(wa-buffer, ''');
0300 LTI_Insert(wa-buffer + 2, ' ');
0301 altered = true; break;
0302 }
0303 }
0304 for (i=2 : i1 + 2 : i++) {
0305 force = false;
0306 if (buffer->i == '-' && buffer->(i+1) == '-' && buffer->(i+2) == '>')
0307 force = true;
0308 if (force) {
0309 if (i>2 && buffer->(i-1) ~= ' ') {
0310 LTI_Insert(i++, ' '); altered = true;
0311 }
0312 if (buffer->(i+3) ~= ' ') {
0313 LTI_Insert(i+3, ' '); i++; altered = true;
0314 }
0315 i = i + 2; continue;
0316 }
0317
0318 if (buffer->i == ':' && buffer->(i+1) == ':') force = true;
0319 if (buffer->i == '-' && buffer->(i+1) == '>') force = true;
0320 if (buffer->i == '.' && buffer->(i+1) == '&') {
0321 buffer->i = ']'; force = true;
0322 }
0323 if (buffer->i == '.' && buffer->(i+1) == '#') {
0324 buffer->i = ']'; force = true;
0325 }
0326 if (buffer->i == ']' && buffer->(i+1) == '&') force = true;
0327 if (buffer->i == ']' && buffer->(i+1) == '#') force = true;
0328 if (buffer->i == '+' && buffer->(i+1) == '+') force = true;
0329 if (buffer->i == '-' && buffer->(i+1) == '-') force = true;
0330 if (buffer->i == '&' && buffer->(i+1) == '&') force = true;
0331 if (buffer->i == '|' && buffer->(i+1) == '|') force = true;
0332 if (buffer->i == '~' && buffer->(i+1) == '~') force = true;
0333
0334 if (buffer->i == '=' && buffer->(i+1) == '=') force = true;
0335 if (buffer->i == '~' && buffer->(i+1) == '=') force = true;
0336 if (buffer->i == '>' && buffer->(i+1) == '=') force = true;
0337 if (buffer->i == '<' && buffer->(i+1) == '=') force = true;
0338 if (buffer->i == '#' && buffer->(i+1) == '#') force = true;
0339
0340 if (force) {
0341 if (i > 2 && buffer->(i-1) ~= ' ') {
0342 LTI_Insert(i++, ' '); altered = true;
0343 }
0344 if (buffer->(i+2) ~= ' ') {
0345 LTI_Insert(i+2, ' '); i++; altered = true;
0346 }
0347 i = i + 1; continue;
0348 }
0349
0350 if (buffer->i == '+') force = true;
0351 if (buffer->i == '-') force = true;
0352 if (buffer->i == '*') force = true;
0353 if (buffer->i == '/') force = true;
0354 if (buffer->i == '%') force = true;
0355 if (buffer->i == '(') force = true;
0356 if (buffer->i == ')') force = true;
0357 if (buffer->i == '<' && buffer->(i-1) ~= ';') force = true;
0358 if (buffer->i == '>') force = true;
0359 if (buffer->i == ',') force = true;
0360 if (buffer->i == '.') force = true;
0361 if (buffer->i == '&') force = true;
0362 if (buffer->i == '|') force = true;
0363 if (buffer->i == '~') force = true;
0364 if (buffer->i == '=') force = true;
0365 if (force) {
0366 if (i > 2 && buffer->(i-1) ~= ' ') {
0367 LTI_Insert(i++, ' '); altered = true;
0368 }
0369 if (buffer->(i+1) ~= ' ') {
0370 LTI_Insert(i+1, ' '); i++; altered = true;
0371 }
0372 }
0373 }
0374 for (i=2 : i1 + 2 : i++)
0375 if (buffer->i == '~') { buffer->i = '['; altered = true; }
0376 return altered;
0377 ]; ! end of InfixCheckLineSpaced
0378
0379 Array InfixRV_rvals --> 32;
0380 Array InfixRV_lvals --> 32;
0381 Array InfixRV_op --> 32;
0382 Array InfixRV_lop --> 32;
0383 Array InfixRV_rop --> 32;
0384 Array InfixRV_types --> 32;
0385 Array InfixRV_commas --> 32;
0386
0387 [ InfixInBounds addr index n;
0388 if (addr < #array__start || addr > #array__end)
0389 rtrue;
0390 for (n=#lowest_array_number : n<=#highest_array_number : n++) {
0391 if (addr == Symb__Tab(INFIXTT_ARRAY, n)) {
0392 if (temp__global3 == 1 or 3)
0393 temp__global2=temp__global2*WORDSIZE+WORDSIZE-1;
0394 if (index > temp__global2) {
0395 print "Array index out of range";
0396 rfalse;
0397 }
0398 }
0399 }
0400 rtrue;
0401 ];
0402
0403 [ InfixRvalue acc w i n flag base expecting_term max maxi lop rop lvalside
0404 a b sysfun_f;
0405
0406 if (InfixCheckLineSpaced()) return GPR_REPARSE;
0407
0408 ! w = wn; for (i=0 : i<10 : i++) { wn = w; InfixRvalueTerm(); print i, "^"; }
0409 ! wn = w;
0410
0411 expecting_term = true; base = 0;
0412 do {
0413 w = NextWordStopped();
0414 if (expecting_term) {
0415 switch (w) {
0416 '-//':
0417 InfixRV_rvals-->n = 'unary-'; InfixRV_types-->n = base + 8;
0418 '[//':
0419 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
0420 '[[':
0421 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
0422 '++':
0423 InfixRV_rvals-->n = 'pre++'; InfixRV_types-->n = base + 9;
0424 '--':
0425 InfixRV_rvals-->n = 'pre--'; InfixRV_types-->n = base + 9;
0426 '(//':
0427 InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base+100;
0428 ')//':
0429 InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base-100;
0430 if (base < 0) { wn--; flag = true; }
0431 -1:
0432 flag = true;
0433 default:
0434 wn--;
0435 if (InfixRValueTerm() == 1) {
0436 InfixRV_rvals-->n = parsed_number;
0437 InfixRV_lvals-->n = infix_parsed_lvalue;
0438 InfixRV_types-->n = -1;
0439 expecting_term = false;
0440 }
0441 else flag = true;
0442 }
0443 }
0444 else {
0445 expecting_term = true;
0446 switch (w) {
0447 comma_word:
0448 InfixRV_rvals-->n = w; InfixRV_types-->n = base;
0449 '=//':
0450 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 1;
0451 '&&', '||':
0452 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
0453 '==', '[=', '>//', '>=', '/', '<=', 'has', 'hasnt',
0454 'in', 'notin', 'ofclass', 'provides':
0455 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 3;
0456 'or':
0457 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 4;
0458 '+//', '-//':
0459 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 5;
0460 '*//', '@{2f}//', '%//', '&//', '|//':
0461 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
0462 '->', '-->':
0463 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 7;
0464 ']&', ']#':
0465 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 10;
0466 THEN1__WD:
0467 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 12;
0468 '::':
0469 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 13;
0470 '(//':
0471 InfixRV_rvals-->n = '(rcall';
0472 InfixRV_types-->n = base + 11; base = base + 100;
0473 ')//':
0474 InfixRV_rvals-->n = w; InfixRV_types-->n = -3;
0475 base = base - 100;
0476 if (base < 0) { wn--; flag = true; }
0477 expecting_term = false;
0478 '++':
0479 InfixRV_rvals-->n = 'post++'; InfixRV_types-->n = base + 9;
0480 expecting_term = false;
0481 '--':
0482 InfixRV_rvals-->n = 'post--'; InfixRV_types-->n = base + 9;
0483 expecting_term = false;
0484 default:
0485 flag = true;
0486 }
0487 }
0488 n++;
0489 } until (flag || n == 32);
0490 if (base > 0) return -1;
0491 n--; if (n == 0) return -1;
0492 wn--;
0493
0494 for (i=0 : i
0495 acc = 0; if (InfixRV_types-->i ~= -3) acc = InfixRV_rvals-->i;
0496 InfixRV_op-->i = acc;
0497 }
0498
0499 for (::) {
0500
0501 ! for (i=0 : i
0502 ! if (InfixRV_types-->i == -1) print InfixRV_rvals-->i, " ";
0503 ! else if (InfixRV_types-->i == -3) print " # ";
0504 ! else if (InfixRV_types-->i == -2) print " ## ";
0505 ! else print (address) InfixRV_rvals-->i, "_", InfixRV_types-->i, " ";
0506 ! }
0507 ! new_line;
0508
0509 max = -2;
0510 for (i=0 : ii > max) {
0511 max = InfixRV_types-->i; maxi = i; }
0512 if (max == -1) { parsed_number = InfixRV_rvals-->maxi; return 1; }
0513
0514 lop = maxi-1; rop = maxi+1;
0515 while (lop >= 0 && InfixRV_types-->lop < -1) lop--;
0516 while (rop < n && InfixRV_types-->rop < -1) rop++;
0517 if (lop >= 0) InfixRV_lop-->maxi = InfixRV_rvals-->lop;
0518 if (rop < n) InfixRV_rop-->maxi = InfixRV_rvals-->rop;
0519 flag = false;
0520 infix_term_type = INFIXTT_NUMBER;
0521 switch (InfixRV_rvals-->maxi) {
0522 comma_word:
0523 acc = (InfixRV_rvals-->rop);
0524 '=//', 'pre++', 'post++', 'pre--', 'post--':
0525 lvalside = lop;
0526 switch (InfixRV_rvals-->maxi) {
0527 '=//': acc = (InfixRV_rvals-->rop);
0528 'pre++': acc = (InfixRV_rvals-->rop) + 1; lvalside = rop;
0529 'pre--': acc = (InfixRV_rvals-->rop) - 1; lvalside = rop;
0530 'post++': acc = (InfixRV_rvals-->lop) + 1;
0531 'post--': acc = (InfixRV_rvals-->lop) - 1;
0532 }
0533 switch (InfixRV_op-->lvalside) {
0534 THEN1__WD:
0535 (InfixRV_lop-->lvalside).(InfixRV_rop-->lvalside) = acc;
0536 '->':
0537 if (InfixInBounds(InfixRV_lop-->lvalside, InfixRV_rop-->lvalside))
0538 (InfixRV_lop-->lvalside)->(InfixRV_rop-->lvalside) = acc;
0539 '-->':
0540 if (InfixInBounds(InfixRV_lop-->lvalside, WORDSIZE * InfixRV_rop-->lvalside))
0541 (InfixRV_lop-->lvalside)-->(InfixRV_rop-->lvalside) = acc;
0542 default:
0543 w = InfixRV_lvals-->lvalside; if (w == -1) return -1;
0544 @storew #globals_array w acc;
0545 }
0546 switch(InfixRV_rvals-->maxi) {
0547 'post++': acc--;
0548 'post--': acc++;
0549 }
0550 '(rcall':
0551 sysfun_f = false;
0552 switch (InfixRV_op-->lop) {
0553 THEN1__WD:
0554 a = InfixRV_lop-->lop; b = InfixRV_rop-->lop;
0555 default:
0556 a = InfixRV_rvals-->lop; b = call;
0557 if (InfixRV_lvals-->lop == INFIXTT_SYSFUN)
0558 sysfun_f = true;
0559 }
0560 w = 0;
0561 i = maxi + 1; base = 100;
0562 if (InfixRV_types-->i == -1 && InfixRV_rvals-->i == ')//') {
0563 if (sysfun_f) return -1;
0564 acc = a.b();
0565 }
0566 else {
0567 while (base > 0) {
0568 if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == ')//') base = base - 100;
0569 if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == '(//') base = base + 100;
0570 if (InfixRV_op-->i == '(rcall') base = base + 100;
0571 if (base == 100 && InfixRV_op-->i == comma_word) {
0572 InfixRV_commas-->(w++) = i;
0573 ! print "Comma found at ", i, "^";
0574 }
0575 i++;
0576 }
0577 ! print "Num args = ", w + 1, "^";
0578 ! for (i=0 : i
0579 ! print "arg: ", InfixRV_lop-->(InfixRV_commas-->i), "^";
0580 ! print "arg: ", InfixRV_rvals-->rop, "^";
0581 switch (w+1) {
0582 1:
0583 if (sysfun_f) {
0584 b = InfixRV_rvals-->rop;
0585 infix_term_type = INFIXTT_NAMEDOBJECT;
0586 switch(a) {
0587 'metaclass':
0588 acc = metaclass(b);
0589 'parent':
0590 acc = parent(b);
0591 'child':
0592 acc = child(b);
0593 'children':
0594 acc = children(b);
0595 infix_term_type = INFIXTT_NUMBER;
0596 'random':
0597 acc = random(b);
0598 infix_term_type = INFIXTT_NUMBER;
0599 'sibling':
0600 acc = sibling(b);
0601 }
0602 }
0603 else
0604 acc = a.b(InfixRV_rvals-->rop);
0605 2:
0606 if (sysfun_f) return -1;
0607 acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0608 InfixRV_rvals-->rop);
0609 3:
0610 if (sysfun_f) return -1;
0611 acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0612 InfixRV_lop-->(InfixRV_commas-->1),
0613 InfixRV_rvals-->rop);
0614 4:
0615 if (sysfun_f) return -1;
0616 acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0617 InfixRV_lop-->(InfixRV_commas-->1),
0618 InfixRV_lop-->(InfixRV_commas-->2),
0619 InfixRV_rvals-->rop);
0620 5:
0621 if (sysfun_f) return -1;
0622 acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0623 InfixRV_lop-->(InfixRV_commas-->1),
0624 InfixRV_lop-->(InfixRV_commas-->2),
0625 InfixRV_lop-->(InfixRV_commas-->3),
0626 InfixRV_rvals-->rop);
0627 default:
0628 return -1;
0629 }
0630 }
0631 '+//': acc = (InfixRV_rvals-->lop) + (InfixRV_rvals-->rop);
0632 '-//': acc = (InfixRV_rvals-->lop) - (InfixRV_rvals-->rop);
0633 '*//': acc = (InfixRV_rvals-->lop) * (InfixRV_rvals-->rop);
0634 '@{2f}//': acc = (InfixRV_rvals-->lop) / (InfixRV_rvals-->rop);
0635 '%//': acc = (InfixRV_rvals-->lop) % (InfixRV_rvals-->rop);
0636 THEN1__WD: acc = (InfixRV_rvals-->lop) . (InfixRV_rvals-->rop);
0637 '->': acc = (InfixRV_rvals-->lop) -> (InfixRV_rvals-->rop);
0638 '-->': acc = (InfixRV_rvals-->lop) --> (InfixRV_rvals-->rop);
0639 ']&': acc = (InfixRV_rvals-->lop) .& (InfixRV_rvals-->rop);
0640 ']#': acc = (InfixRV_rvals-->lop) .# (InfixRV_rvals-->rop);
0641 '::': acc = (InfixRV_rvals-->lop) :: (InfixRV_rvals-->rop);
0642 '&//': acc = (InfixRV_rvals-->lop) & (InfixRV_rvals-->rop);
0643 '|//': acc = (InfixRV_rvals-->lop) | (InfixRV_rvals-->rop);
0644 '&&': acc = (InfixRV_rvals-->lop) && (InfixRV_rvals-->rop);
0645 infix_term_type = INFIXTT_LOGICAL;
0646 '||': acc = (InfixRV_rvals-->lop) || (InfixRV_rvals-->rop);
0647 infix_term_type = INFIXTT_LOGICAL;
0648 '/': acc = (InfixRV_rvals-->lop) < (InfixRV_rvals-->rop);
0649 infix_term_type = INFIXTT_LOGICAL;
0650 '<=': acc = (InfixRV_rvals-->lop) <= (InfixRV_rvals-->rop);
0651 infix_term_type = INFIXTT_LOGICAL;
0652 '>//': acc = (InfixRV_rvals-->lop) > (InfixRV_rvals-->rop);
0653 infix_term_type = INFIXTT_LOGICAL;
0654 '>=': acc = (InfixRV_rvals-->lop) >= (InfixRV_rvals-->rop);
0655 infix_term_type = INFIXTT_LOGICAL;
0656 '==': acc = (InfixRV_rvals-->lop) == (InfixRV_rvals-->rop);
0657 infix_term_type = INFIXTT_LOGICAL;
0658 '[=': acc = (InfixRV_rvals-->lop) ~= (InfixRV_rvals-->rop);
0659 infix_term_type = INFIXTT_LOGICAL;
0660 'has': acc = (InfixRV_rvals-->lop) has (InfixRV_rvals-->rop);
0661 infix_term_type = INFIXTT_LOGICAL;
0662 'hasnt': acc = (InfixRV_rvals-->lop) hasnt (InfixRV_rvals-->rop);
0663 infix_term_type = INFIXTT_LOGICAL;
0664 'in': acc = (InfixRV_rvals-->lop) in (InfixRV_rvals-->rop);
0665 infix_term_type = INFIXTT_LOGICAL;
0666 'notin': acc = (InfixRV_rvals-->lop) notin (InfixRV_rvals-->rop);
0667 infix_term_type = INFIXTT_LOGICAL;
0668 'provides': acc = (InfixRV_rvals-->lop) provides (InfixRV_rvals-->rop);
0669 infix_term_type = INFIXTT_LOGICAL;
0670 'ofclass': acc = (InfixRV_rvals-->lop) ofclass (InfixRV_rvals-->rop);
0671 infix_term_type = INFIXTT_LOGICAL;
0672 '[[': acc = ~~ (InfixRV_rvals-->rop); flag = true;
0673 '[//': acc = ~ (InfixRV_rvals-->rop); flag = true;
0674 'unary-': acc = - (InfixRV_rvals-->rop); flag = true;
0675 } ! end of switch(InfixRV_rvals-->maxi)
0676 InfixRV_rvals-->maxi = acc;
0677 InfixRV_types-->maxi = -1;
0678 if (rop < n) InfixRV_types-->rop = -2;
0679 if (flag == false && lop >= 0) InfixRV_types-->lop = -2;
0680 } ! end of for (::)
0681 ]; ! end of InfixRvalue
0682
0683 ! ------------------------------------------------------------------------
0684
0685 [ InfixWelcomeSub;
0686 print "; Welcome to the ~Infix~ debugger (1/990428), which makes the
0687 following verbs available:^^
0688 ~; ~: evaluates this Inform expression: e.g.
0689 ~; location~ will print the value of the variable ~location~,
0690 ~; 3*5+1~ will print 16, ~; children(old cloth bag)~ will tell you
0691 how many items are in it. (You can name objects either by their
0692 names inside the source code, such as ~n_obj~, or by typing the
0693 names by which the game's parser would normally know them, such
0694 as ~north wall~: the effect is the same.)^
0695 Any expression is allowed except that you can't use double-quoted
0696 strings of text: but you can send messages, call routines or
0697 assign values to variables, properties and array entries.
0698 ^ ~; score++~ is one way to get on in the world.
0699 ^ ~; deadflag = true~ is one way to get out of it.
0700 ^ ~; StopDaemon(nasty little dwarf)~ will keep you from being pestered.^
0701 Conditions like ~; score>20~ are also allowed and print
0702 either 1 (if true) or 0 (if false).^^";
0703 print "~;examine ~ or ~;x ~ gives full details
0704 of whatever it is. For instance, ~;x ##Take~ describes the Take
0705 action; ~;x Class~ the class Class; ~;x 'drop'~ the dictionary
0706 word ~drop~ and so on for numbers, routines, arrays and of course
0707 objects. ~;xo~ examines something as an object, so for instance
0708 ~;x location~ tells you about the variable ~location~, but ~;xo
0709 location~ tells you what object it refers to.^^";
0710 print "~;give~, ~;remove~ and ~;move~ work like the corresponding
0711 Inform statements.^^";
0712 print "~;<~ causes an action: for instance, ~;< Eat cheese~.^^";
0713 print "~;watch~ or ~;w~ can set a watch on various activities:
0714 type just ~;w~ for details.^^";
0715 print "~;inventory~ or ~;i~ describes the contents of this story file.^";
0716 ];
0717
0718 [ InfixEvalSub; InfixExamineP(true); ];
0719
0720 [ InfixActionSub;
0721 print "; <", (InfixPrintAction) infix_lvalue;
0722 if (noun) print " (", (the) noun, ")";
0723 if (second) print " (", (the) second, ")";
0724 print ">^";
0725 if (second) <<(infix_lvalue) noun second>>;
0726 if (noun) <<(infix_lvalue) noun>>;
0727 <<(infix_lvalue)>>;
0728 ];
0729
0730 [ InfixGiveSub f;
0731 print "; give (", (the) noun, ") ";
0732 if (second < 0) { second = ~second; f=true; }
0733 if (second < 0 || second >= 48) "";
0734 if (f) print "@@126";
0735 print (DebugAttribute) second;
0736 if (f) @clear_attr noun second;
0737 else @set_attr noun second;
0738 ];
0739
0740 [ InfixMoveSub;
0741 print "; move (", (the) noun, ") to (", (the) second, ")";
0742 move noun to second;
0743 ];
0744
0745 [ InfixRemoveSub;
0746 print "; remove (", (the) noun, ")";
0747 remove noun;
0748 ];
0749
0750 [ InfixHex x y;
0751 y = (x & $7f00) / $100;
0752 if (x < 0) y = y + $80;
0753 x = x & $ff;
0754 print (Infixhexdigit) y/$10, (Infixhexdigit) y, (Infixhexdigit) x/$10, (Infixhexdigit) x;
0755 ];
0756
0757 [ Infixhexdigit x; x = x % $10; if (x < 10) print x; else print (char) 'a'+x-10; ];
0758
0759 [ InfixExamineOSub;
0760 infix_data1 = metaclass(noun);
0761 infix_term_type = INFIXTT_CONSTANT;
0762 InfixExamineP(false);
0763 ];
0764
0765 [ InfixExamineSSub;
0766 infix_term_type = INFIXTT_STATICSTRING;
0767 InfixExamineP(false);
0768 ];
0769
0770 [ InfixExamineSub; InfixExamineP(false); ];
0771
0772 [ InfixExamineP brief x a b w flag lines;
0773 switch (infix_term_type) {
0774 INFIXTT_NUMBER:
0775 if (brief) "; == ", noun;
0776 print "; The number ", noun, " == $", (InfixHex) noun;
0777 if (noun >= 32 && noun < 127) print " == '", (char) noun, "'";
0778 new_line;
0779 INFIXTT_NAMEDOBJECT:
0780 print "~", (name) noun, "~ (", noun, ")^"; if (brief) return;
0781 <>;
0782 INFIXTT_CONSTANT:
0783 if (brief) "; == ", noun;
0784 switch (infix_data1 & 15) {
0785 nothing:
0786 print "; Constant ", (InfixPrintConstant) infix_parsed_lvalue,
0787 " == ", noun, "^";
0788 Object: <>;
0789 Class:
0790 print "Class ", (name) noun, "^";
0791 objectloop (a ofclass noun) {
0792 if (flag) print ", "; else print "Contains: ";
0793 print (name) a, " (", a, ")"; flag=true;
0794 }
0795 if (flag == false) "No object is of this class";
0796 }
0797 new_line;
0798 INFIXTT_ATTRIBUTE:
0799 if (brief) "; == ", noun;
0800 if (noun >= 48 || noun < 0) "; No such attribute";
0801 print "; Attribute ", (InfixPrintAttribute) noun,
0802 " (numbered ", noun, ")^";
0803 objectloop (x has noun) {
0804 if (flag) print ", ";
0805 else print "Each of these ~has ", (InfixPrintAttribute) noun, "~: ";
0806 print (name) x, " (", x, ")"; flag = true;
0807 }
0808 if (flag == false) "No object ~has ", (InfixPrintAttribute) noun, "~";
0809 new_line;
0810 INFIXTT_PROPERTY:
0811 if (brief) "; == ", noun;
0812 print "; Property ", (property) noun, " (numbered ", noun, ")^";
0813 objectloop (x provides noun) {
0814 if (flag) print ", "; else print "Provided by: ";
0815 print (name) x, " (", x, ")"; flag = true;
0816 }
0817 if (flag == false) "Which is not provided by any object";
0818 new_line;
0819 INFIXTT_DWORD:
0820 if (brief) "; == ", noun;
0821 if (noun == 0) "; This word is not in the dictionary";
0822 a = noun->#dict_par1;
0823 print "; Dictionary word '", (address) noun;
0824 if (a & 4) print "//p";
0825 print "' (address ", noun, ")";
0826 if (a) {
0827 print ": ";
0828 if (a & 2) print "meta ";
0829 if (a & 1) print "verb ";
0830 if (a & 8) print "preposition ";
0831 if (a & 4) print "pluralising ";
0832 if (a & 128) print "noun ";
0833 }
0834 new_line;
0835 if (a & 1) <>;
0836 INFIXTT_ROUTINE:
0837 if (brief) "; == ", noun;
0838 print "; Routine ", (InfixPrintRoutine) infix_parsed_lvalue, " (number ",
0839 infix_parsed_lvalue, ", packed address ", noun, ")^";
0840 INFIXTT_GLOBAL:
0841 if (brief) "; == ", noun;
0842 print "; Global ", (InfixPrintGlobal) infix_parsed_lvalue, " == ", noun, "^";
0843 INFIXTT_ARRAY:
0844 if (brief) "; == ", noun;
0845 print "; Array ", (InfixPrintArray) infix_parsed_lvalue, " ";
0846 infix_data1 = infix_data1 % 16;
0847 switch (infix_data1) {
0848 0: print "->"; a=0;
0849 1: print "-->"; a=0;
0850 2: print "string"; a=1;
0851 3: print "table"; a=1;
0852 4: print "buffer"; a=WORDSIZE;
0853 }
0854 print " ", infix_data2 + 1 - a, "^; == "; b = infix_data2;
0855 for (w=b : w>=a : w--)
0856 if (infix_data1 == 0 or 2 or 4) { if (noun->w) break; }
0857 else { if (noun-->w) break; }
0858 if (b-w < 5) w=b;
0859 for (: x<=w : x++) {
0860 if (infix_data1 == 0 or 2 or 4) print noun->x, " ";
0861 else print noun-->x, " ";
0862 if (x+1 == a) print ": ";
0863 }
0864 if (w < b) print "(then ", b-w, " zero entries)";
0865 new_line;
0866 INFIXTT_ACTION:
0867 if (brief) "; == ", noun;
0868 if (noun >= #lowest_fake_action_number && noun <= #highest_fake_action_number)
0869 "; Fake action ", (InfixPrintFakeAction) noun,
0870 " (numbered ", noun, ")^Is not generated by any grammar";
0871 print "; Action ", (InfixPrintAction) noun,
0872 " (numbered ", noun, ")^";
0873 w = HDR_DICTIONARY-->0;
0874 for (b=0 : b<(HDR_DICTIONARY-->0 + 5)-->0 : b++) {
0875 w = HDR_DICTIONARY-->0 + 7 + b*9;
0876 if ((w->#dict_par1) & 1) {
0877 a = (HDR_STATICMEMORY-->0)-->($ff-(w->#dict_par2));
0878 lines = a->0; a++;
0879 for (: lines>0 : lines--) {
0880 a = UnpackGrammarLine(a);
0881 if (action_to_be == noun) {
0882 print "'", (address) w, "' "; DebugGrammarLine();
0883 new_line;
0884 flag = true;
0885 }
0886 }
0887 }
0888 }
0889 if (flag == 0) "Is not generated by any grammar";
0890 INFIXTT_SYSFUN:
0891 if (brief) "; == ", noun;
0892 "; System function ~", (address) infix_parsed_lvalue, "~ has
0893 not been overridden by any routine and so has its standard definition.";
0894 INFIXTT_STATICSTRING:
0895 if (brief) "; == ", noun;
0896 if (metaclass(noun) ~= String) "; ", noun, " is not a string.";
0897 print "~", (string) noun, "~^";
0898 INFIXTT_LOGICAL:
0899 if (noun == true) "; true"; if (noun == false) "; false";
0900 "; ", noun;
0901 }
0902 ]; ! end of InfixExamineP
0903
0904 [ InfixDescribeWatchSub x y z s flag aflag;
0905 print "; The Infix ~;watch~ verb allows you to set a watch on any named
0906 routine(s) or objects: for instance ~;watch ScoreSub~ or
0907 ~;watch silver bars~. You can also:
0908 ^ ~;watch objects~: changes to attribute or property settings";
0909 if (debug_flag & 8) print " (on)"; else print " (off)";
0910
0911 print ";^ ~;watch timers~: the running of timers and daemons each turn";
0912 if (debug_flag & 4) print " (on)"; else print " (off)";
0913
0914 print ";^ ~;watch messages~: all messages sent";
0915 if (debug_flag & 1) print " (on)"; else print " (off)";
0916
0917 print ";^ ~;watch actions~: all actions generated";
0918 if (debug_flag & 2) print " (on)"; else print " (off)";
0919
0920 print ".^~~;watch~ can be abbreviated to ~;w~ and use ~off~ to stop
0921 watching: for instance ~;w location off~.^";
0922 aflag = debug_flag;
0923 objectloop (x has infix__watching) flag = true; aflag = aflag || flag;
0924 if (flag) print "The following objects are currently being watched: ";
0925 flag = false;
0926 objectloop (x has infix__watching) {
0927 if (flag) print ", "; flag = true;
0928 print (name) x, " (", x, ")";
0929 }
0930 if (flag) new_line;
0931 s = (#highest_routine_number - #lowest_routine_number);
0932 if (s%8 == 0) s=s/8; else s=s/8+1;
0933 for (flag=false,x=0 : xx) flag = true;
0934 aflag = aflag || flag;
0935 if (flag) print "The following routines are currently being watched: ";
0936 for (x=0,flag=false : x
0937 for (y=1,z=0 : y<256 : z++,y=y*2) {
0938 if ((#routine_flags_array->x) & y) {
0939 if (flag) print ", "; flag = true;
0940 print (InfixPrintRoutine)
0941 #lowest_routine_number + x*8 + z;
0942 }
0943 }
0944 }
0945 if (flag) new_line;
0946 if (aflag == false) "At present, nothing is being watched.";
0947 ];
0948
0949 [ InfixWatchOnSub i j k l;
0950 if (noun == 0) return InfixDescribeWatchSub();
0951 if (infix_term_type == INFIXTT_ROUTINE) {
0952 i = infix_parsed_lvalue/8;
0953 for (j=0,k=1 : j
0954 l = #routine_flags_array->i;
0955 l = l | k;
0956 @storeb #routine_flags_array i l;
0957 "; Watching routine ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
0958 }
0959 if (metaclass(noun) == Object) {
0960 give noun infix__watching;
0961 "; Watching object ~", (name) noun, "~ (", noun, ").";
0962 }
0963 InfixDescribeWatchSub();
0964 ];
0965
0966 [ InfixWatchOffSub i j k l;
0967 if (noun == 0) return InfixDescribeWatchSub();
0968 if (infix_term_type == INFIXTT_ROUTINE) {
0969 i = infix_parsed_lvalue/8;
0970 for (j=0,k=1 : j
0971 l = #routine_flags_array->i;
0972 l = l & (~k);
0973 @storeb #routine_flags_array i l;
0974 "; Not watching ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
0975 }
0976 if (metaclass(noun) == Object) {
0977
|