



		
		 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.