Inventory This is the complete source code of the example game infix.inf.
Back to List
Complete
Browsing infix.h
0001 ! ----------------------------------------------------------------------------
0002 ! INFIX: Support for the optional library extension "Infix".
0003 !
0004 ! Supplied for use with Inform 6 Serial number 991113
0005 ! Release 6/10
0006 ! (c) Graham Nelson 1999
0007 ! but freely usable (see manuals)
0008 ! ----------------------------------------------------------------------------
0009 System_file;
0010 Ifdef DEBUG;
0011
0012 Constant INFIXTT_NUMBER 0;
0013 Constant INFIXTT_ARRAY 1;
0014 Constant INFIXTT_ROUTINE 2;
0015 Constant INFIXTT_CONSTANT 3;
0016 Constant INFIXTT_DWORD 4;
0017 Constant INFIXTT_ACTION 5;
0018 Constant INFIXTT_ATTRIBUTE 6;
0019 Constant INFIXTT_PROPERTY 7;
0020 Constant INFIXTT_GLOBAL 8;
0021 Constant INFIXTT_NAMEDOBJECT 9;
0022 Constant INFIXTT_SYSFUN 10;
0023 Constant INFIXTT_STATICSTRING 11;
0024 Constant INFIXTT_LOGICAL 12;
0025
0026 Global infix_term_type;
0027 Global infix_data1;
0028 Global infix_data2;
0029 Global infix_lvalue;
0030 Global infix_parsed_lvalue;
0031 Array infix_tolowercase -> 256;
0032 Array infix_text -> 128;
0033
0034
0035 [ InfixPrintAttribute x; print (string) #attribute_names_array-->x; ];
0036 [ InfixPrintProperty x; print (property) x; ];
0037 [ InfixPrintGlobal x; print (string) #global_names_array-->x; ];
0038 [ InfixPrintAction x;
0039 print (string) #action_names_array-->(x-#lowest_action_number);
0040 ];
0041 [ InfixPrintRoutine x;
0042 print (string) #routine_names_array-->(x-#lowest_routine_number);
0043 ];
0044 [ InfixPrintConstant x;
0045 print (string) #constant_names_array-->(x-#lowest_constant_number);
0046 ];
0047 [ InfixPrintArray x;
0048 print (string) #array_names_array-->(x-#lowest_array_number);
0049 ];
0050 [ InfixPrintFakeAction x;
0051 print (string) #fake_action_names_array-->(x-#lowest_fake_action_number);
0052 ];
0053 [ InfixPrintPA x n;
0054 for (n=#lowest_routine_number:n<=#highest_routine_number:n++)
0055 { if (x == Symb__Tab(INFIXTT_ROUTINE, n))
0056 { print (InfixPrintRoutine) n; return;
0057 }
0058 }
0059 print "Routine(", x, ")";
0060 ];
0061
0062 [ InfixMatchPrule PrintingRule range1 range2 wa wl t i i2 it2 itlc j k plus;
0063 itlc = infix_tolowercase;
0064 if (itlc->255 == 0)
0065 { for (j=0:j<256:j++) itlc->j = j;
0066 itlc->'A' = 'a'; itlc->'B' = 'b';
0067 itlc->'C' = 'c'; itlc->'D' = 'd';
0068 itlc->'E' = 'e'; itlc->'F' = 'f';
0069 itlc->'G' = 'g'; itlc->'H' = 'h';
0070 itlc->'I' = 'i'; itlc->'J' = 'j';
0071 itlc->'K' = 'k'; itlc->'L' = 'l';
0072 itlc->'M' = 'm'; itlc->'N' = 'n';
0073 itlc->'O' = 'o'; itlc->'P' = 'p';
0074 itlc->'Q' = 'q'; itlc->'R' = 'r';
0075 itlc->'S' = 's'; itlc->'T' = 't';
0076 itlc->'U' = 'u'; itlc->'V' = 'v';
0077 itlc->'W' = 'w'; itlc->'X' = 'x';
0078 itlc->'Y' = 'y'; itlc->'Z' = 'z';
0079 }
0080 switch(PrintingRule)
0081 { InfixPrintAttribute:
0082 if (wa->0 == '~') { wl--; wa++; plus = 100; } ! A tilde
0083 t = #attribute_names_array;
0084 InfixPrintProperty: t = #property_names_array;
0085 InfixPrintAction: t = #action_names_array;
0086 InfixPrintFakeAction: t = #fake_action_names_array;
0087 InfixPrintGlobal: t = #global_names_array;
0088 InfixPrintRoutine: t = #routine_names_array;
0089 InfixPrintAction: t = #constant_names_array;
0090 InfixPrintArray: t = #array_names_array;
0091 }
0092
0093 i2 = range2-range1; it2 = infix_text+2;
0094 for (i=0: i<=i2: i++)
0095 { infix_text-->0 = 62; @output_stream 3 infix_text;
0096 if (t) print (string) t-->i; else PrintingRule(i+range1);
0097 @output_stream -3;
0098 k = infix_text-->0;
0099 if (k ~= wl) jump XL;
0100 if (itlc->(it2->0) ~= wa->0) jump XL;
0101 for (j=1:j<k:j++)
0102 if (itlc->(it2->j) ~= wa->j) jump XL;
0103 parsed_number = i + range1 + plus; rtrue;
0104 .XL;
0105 }
0106 rfalse;
0107 ];
0108
0109 [ InfixActionToken;
0110 if (InfixMatchPrule(InfixPrintAction,
0111 #lowest_action_number, #highest_action_number,
0112 WordAddress(wn), WordLength(wn)))
0113 { wn++; infix_lvalue = parsed_number; return 0;
0114 }
0115 if (InfixMatchPrule(InfixPrintFakeAction,
0116 #lowest_fake_action_number, #highest_fake_action_number,
0117 WordAddress(wn), WordLength(wn)))
0118 { wn++; infix_lvalue = parsed_number; return 0;
0119 }
0120 return -1;
0121 ];
0122
0123 [ InfixRvalueTerm n w i initial_wn wa wl sign base digit dcount;
0124
0125 initial_wn = wn;
0126
0127 infix_parsed_lvalue = -1;
0128 infix_term_type = INFIXTT_NUMBER;
0129
0130 w = NextWordStopped();
0131 if (w == -1) return -1;
0132
0133 wa = WordAddress(wn-1);
0134 wl = WordLength(wn-1);
0135 if (wa->0 == '-' or '$' or '0' or '1' or '2' or '3' or '4'
0136 or '5' or '6' or '7' or '8' or '9')
0137 { ! Parse decimal, hex or binary number
0138
0139 sign = 1; base = 10; dcount = 0;
0140 if (wa->0 == '-') { sign = -1; wl--; wa++; }
0141 else
0142 { if (wa->0 == '$') { base = 16; wl--; wa++; }
0143 if (wa->0 == '$') { base = 2; wl--; wa++; }
0144 }
0145 if (wl == 0) return -1;
0146 n = 0;
0147 while (wl > 0)
0148 { if (wa->0 >= 'a') digit = wa->0 - 'a' + 10;
0149 else digit = wa->0 - '0';
0150 dcount++;
0151 switch(base)
0152 { 2: if (dcount == 17) return -1;
0153 10: if (dcount == 6) return -1;
0154 if (dcount == 5)
0155 { if (n > 3276) return -1;
0156 if (n == 3276)
0157 { if (sign == 1 && digit > 7) return -1;
0158 if (sign == -1 && digit > 8) return -1;
0159 }
0160 }
0161 16: if (dcount == 5) return -1;
0162 }
0163 if (digit >= 0 && digit < base) n = base*n + digit;
0164 else return -1;
0165 wl--; wa++;
0166 }
0167 parsed_number = n*sign; return 1;
0168 }
0169
0170 ! Parse character constant 'a'
0171
0172 if (wl == 3 && wa->0==''' && wa->2==''')
0173 { parsed_number = wa->1; return 1;
0174 }
0175
0176 ! ##Action, 'dword'
0177
0178 switch(w)
0179 { '##': infix_term_type = INFIXTT_ACTION;
0180 w = NextWordStopped(); if (w == -1) return -1;
0181 wn--;
0182 if (InfixActionToken() == 0) return 1;
0183 return -1;
0184 '^^': infix_term_type = INFIXTT_DWORD;
0185 w = NextWordStopped(); if (w == -1) return -1;
0186 parsed_number = w; return 1;
0187 }
0188
0189 ! Test for attribute, property, class name, variable name, array name, routine
0190 ! name, constant name
0191
0192 wn--;
0193 if ((wa->0 >= 'a' && wa->0 <= 'z')
0194 || (wa->0 >= 'A' && wa->0 <= 'Z')
0195 || wa->0 == '_')
0196 {
0197
0198 infix_term_type = INFIXTT_ATTRIBUTE;
0199 if (InfixMatchPrule(InfixPrintAttribute,
0200 #lowest_attribute_number, #highest_attribute_number, wa, wl))
0201 { wn++; return 1; }
0202
0203 infix_term_type = INFIXTT_PROPERTY;
0204 if (InfixMatchPrule(InfixPrintProperty,
0205 #lowest_property_number, #highest_property_number, wa, wl))
0206 { wn++; return 1; }
0207
0208 infix_term_type = INFIXTT_GLOBAL;
0209 if (InfixMatchPrule(InfixPrintGlobal,
0210 #lowest_global_number, #highest_global_number, wa, wl))
0211 { infix_parsed_lvalue = parsed_number-16;
0212 parsed_number = #globals_array-->infix_parsed_lvalue;
0213 wn++; return 1;
0214 }
0215
0216 infix_term_type = INFIXTT_ARRAY;
0217 if (InfixMatchPrule(InfixPrintArray,
0218 #lowest_array_number, #highest_array_number, wa, wl))
0219 { infix_parsed_lvalue = parsed_number;
0220 parsed_number = Symb__Tab(INFIXTT_ARRAY,parsed_number);
0221 infix_data1 = temp__global3;
0222 infix_data2 = temp__global2;
0223 wn++; return 1;
0224 }
0225
0226 infix_term_type = INFIXTT_ROUTINE;
0227 if (InfixMatchPrule(InfixPrintRoutine,
0228 #lowest_routine_number, #highest_routine_number, wa, wl))
0229 { infix_parsed_lvalue = parsed_number;
0230 parsed_number = Symb__Tab(INFIXTT_ROUTINE,parsed_number);
0231 infix_data1 = temp__global3;
0232 infix_data2 = temp__global2;
0233 wn++; return 1;
0234 }
0235
0236 infix_term_type = INFIXTT_CONSTANT;
0237 if (InfixMatchPrule(InfixPrintConstant,
0238 #lowest_constant_number, #highest_constant_number, wa, wl))
0239 { infix_parsed_lvalue = parsed_number;
0240 parsed_number = Symb__Tab(INFIXTT_CONSTANT,parsed_number);
0241 infix_data1 = temp__global3;
0242 infix_data2 = temp__global2;
0243 wn++; return 1;
0244 }
0245
0246 switch(w)
0247 { 'parent', 'child', 'children',
0248 'random', 'metaclass', 'sibling': parsed_number = w;
0249 infix_parsed_lvalue = INFIXTT_SYSFUN;
0250 wn++; return 1;
0251 }
0252 }
0253
0254 infix_term_type = INFIXTT_NAMEDOBJECT;
0255
0256 wn = initial_wn; i = ParseToken(SCOPE_TT, InfixBigScope);
0257
0258 if (i == GPR_REPARSE) return i;
0259 if (i > GPR_MULTIPLE)
0260 { print "(", (name) i, " (", i, "))^";
0261 parsed_number = i; return 1;
0262 }
0263 return -1;
0264 ];
0265 [ InfixBigScope x;
0266 if (scope_stage == 1) return false; ! No multiples here
0267 if (scope_stage == 2)
0268 { objectloop (x ofclass Object) PlaceInScope(x);
0269 return true; ! That's the whole scope
0270 }
0271 print "; I'm unable to make any sense of that term.^";
0272 ];
0273
0274 [ InfixCheckLineSpaced wa wl i force altered;
0275 for (i = 1 : i <= parse->1 : i++)
0276 { wa = WordAddress(i);
0277 wl = WordLength(i);
0278 if (wl > 3 && wa->0==''' && wa->(wl-1)==''')
0279 { wa->(wl-1) = ' ';
0280 if (wa->(wl-2) == '/' && wa->(wl-3) == '/')
0281 { wa->(wl-2) = ' ';
0282 wa->(wl-3) = ' ';
0283 }
0284 LTI_Insert(wa-buffer, ''');
0285 LTI_Insert(wa-buffer + 2, ' ');
0286 altered = true; break;
0287 }
0288 }
0289 for (i = 2 : i < buffer->1 + 2: i++)
0290 { force = false;
0291 if (buffer->i=='-' && buffer->(i+1)=='-' && buffer->(i+2)=='>')
0292 force = true;
0293 if (force)
0294 { if (i>2 && buffer->(i-1)~=' ')
0295 { LTI_Insert(i++, ' '); altered = true;
0296 }
0297 if (buffer->(i+3)~=' ')
0298 { LTI_Insert(i+3, ' '); i++; altered = true;
0299 }
0300 i = i + 2; continue;
0301 }
0302
0303 if (buffer->i==':' && buffer->(i+1)==':') force = true;
0304 if (buffer->i=='-' && buffer->(i+1)=='>') force = true;
0305 if (buffer->i=='.' && buffer->(i+1)=='&')
0306 { buffer->i = ']'; force = true;
0307 }
0308 if (buffer->i=='.' && buffer->(i+1)=='#')
0309 { buffer->i = ']'; force = true;
0310 }
0311 if (buffer->i==']' && buffer->(i+1)=='&') force = true;
0312 if (buffer->i==']' && buffer->(i+1)=='#') force = true;
0313 if (buffer->i=='+' && buffer->(i+1)=='+') force = true;
0314 if (buffer->i=='-' && buffer->(i+1)=='-') force = true;
0315 if (buffer->i=='&' && buffer->(i+1)=='&') force = true;
0316 if (buffer->i=='|' && buffer->(i+1)=='|') force = true;
0317 if (buffer->i=='~' && buffer->(i+1)=='~') force = true;
0318
0319 if (buffer->i=='=' && buffer->(i+1)=='=') force = true;
0320 if (buffer->i=='~' && buffer->(i+1)=='=') force = true;
0321 if (buffer->i=='>' && buffer->(i+1)=='=') force = true;
0322 if (buffer->i=='<' && buffer->(i+1)=='=') force = true;
0323 if (buffer->i=='#' && buffer->(i+1)=='#') force = true;
0324
0325 if (force)
0326 { if (i>2 && buffer->(i-1)~=' ')
0327 { LTI_Insert(i++, ' '); altered = true;
0328 }
0329 if (buffer->(i+2)~=' ')
0330 { LTI_Insert(i+2, ' '); i++; altered = true;
0331 }
0332 i = i + 1; continue;
0333 }
0334
0335 if (buffer->i=='+') force = true;
0336 if (buffer->i=='-') force = true;
0337 if (buffer->i=='*') force = true;
0338 if (buffer->i=='/') force = true;
0339 if (buffer->i=='%') force = true;
0340 if (buffer->i=='(') force = true;
0341 if (buffer->i==')') force = true;
0342 if (buffer->i=='<' && buffer->(i-1)~=';') force = true;
0343 if (buffer->i=='>') force = true;
0344 if (buffer->i==',') force = true;
0345 if (buffer->i=='.') force = true;
0346 if (buffer->i=='&') force = true;
0347 if (buffer->i=='|') force = true;
0348 if (buffer->i=='~') force = true;
0349 if (buffer->i=='=') force = true;
0350 if (force)
0351 { if (i>2 && buffer->(i-1)~=' ')
0352 { LTI_Insert(i++, ' '); altered = true;
0353 }
0354 if (buffer->(i+1)~=' ')
0355 { LTI_Insert(i+1, ' '); i++; altered = true;
0356 }
0357 }
0358 }
0359 for (i = 2 : i < buffer->1 + 2: i++)
0360 if (buffer->i == '~') { buffer->i = '['; altered = true; }
0361 return altered;
0362 ];
0363
0364 Array InfixRV_rvals --> 32;
0365 Array InfixRV_lvals --> 32;
0366 Array InfixRV_op --> 32;
0367 Array InfixRV_lop --> 32;
0368 Array InfixRV_rop --> 32;
0369 Array InfixRV_types --> 32;
0370 Array InfixRV_commas --> 32;
0371
0372 [ InfixRvalue acc w i n flag base expecting_term max maxi lop rop lvalside
0373 a b sysfun_f;
0374
0375 if (InfixCheckLineSpaced()) return GPR_REPARSE;
0376
0377 ! w = wn; for (i=0: i<10: i++) { wn = w; InfixRvalueTerm(); print i, "^"; }
0378 ! wn = w;
0379
0380 expecting_term = true; base = 0;
0381 do
0382 { w = NextWordStopped();
0383 if (expecting_term)
0384 { switch(w)
0385 { '-//':
0386 InfixRV_rvals-->n = 'unary-'; InfixRV_types-->n = base + 8;
0387 '[//':
0388 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
0389 '[[':
0390 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
0391 '++':
0392 InfixRV_rvals-->n = 'pre++'; InfixRV_types-->n = base + 9;
0393 '--':
0394 InfixRV_rvals-->n = 'pre--'; InfixRV_types-->n = base + 9;
0395 '(//':
0396 InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base+100;
0397 ')//':
0398 InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base-100;
0399 if (base < 0) { wn--; flag = true; }
0400 -1: flag = true;
0401 default:
0402 wn--;
0403 if (InfixRValueTerm() == 1)
0404 { InfixRV_rvals-->n = parsed_number;
0405 InfixRV_lvals-->n = infix_parsed_lvalue;
0406 InfixRV_types-->n = -1;
0407 expecting_term = false;
0408 }
0409 else flag = true;
0410 }
0411 }
0412 else
0413 { expecting_term = true;
0414 switch(w)
0415 { ',//':
0416 InfixRV_rvals-->n = w; InfixRV_types-->n = base;
0417 '=//':
0418 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 1;
0419 '&&', '||':
0420 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
0421 '==', '[=', '>//', '>=', '/', '<=', 'has', 'hasnt',
0422 'in', 'notin', 'ofclass', 'provides':
0423 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 3;
0424 'or':
0425 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 4;
0426 '+//', '-//':
0427 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 5;
0428 '*//', '@{2f}//', '%//', '&//', '|//':
0429 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
0430 '->', '-->':
0431 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 7;
0432 ']&', ']#':
0433 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 10;
0434 './/':
0435 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 12;
0436 '::':
0437 InfixRV_rvals-->n = w; InfixRV_types-->n = base + 13;
0438 '(//':
0439 InfixRV_rvals-->n = '(rcall';
0440 InfixRV_types-->n = base + 11; base = base + 100;
0441 ')//':
0442 InfixRV_rvals-->n = w; InfixRV_types-->n = -3;
0443 base = base - 100;
0444 if (base < 0) { wn--; flag = true; }
0445 expecting_term = false;
0446 '++':
0447 InfixRV_rvals-->n = 'post++'; InfixRV_types-->n = base + 9;
0448 expecting_term = false;
0449 '--':
0450 InfixRV_rvals-->n = 'post--'; InfixRV_types-->n = base + 9;
0451 expecting_term = false;
0452 default:
0453 flag = true;
0454 }
0455 }
0456 n++;
0457 } until (flag || n==32);
0458 if (base > 0) return -1;
0459 n--; if (n == 0) return -1;
0460 wn--;
0461
0462 for (i=0: i
Last updated 27 February 2004.
This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation.
Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.