Inform - Support - Source

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 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
0463    {   acc = 0; if (InfixRV_types-->i ~= -3) acc = InfixRV_rvals-->i;
0464        InfixRV_op-->i = acc;
0465    }
0466   
0467    for (::)
0468    {   
0469  !      for (i=0: i
0470  !      {   if (InfixRV_types-->i == -1) print InfixRV_rvals-->i, " ";
0471  !          else if (InfixRV_types-->i == -3) print " # ";
0472  !          else if (InfixRV_types-->i == -2) print " ## ";
0473  !          else print (address) InfixRV_rvals-->i, "_", InfixRV_types-->i, " ";
0474  !      }
0475  !      new_line;
0476   
0477        max = -2;
0478        for (i=0:ii > max)
0479                          { max = InfixRV_types-->i; maxi = i; }
0480        if (max == -1) { parsed_number = InfixRV_rvals-->maxi; return 1; }
0481   
0482        lop = maxi-1; rop = maxi+1;
0483        while (lop>=0 && InfixRV_types-->lop < -1) lop--;
0484        while (roprop < -1) rop++;
0485        if (lop>=0) InfixRV_lop-->maxi = InfixRV_rvals-->lop;
0486        if (ropmaxi = InfixRV_rvals-->rop;
0487        flag = false;
0488      infix_term_type = INFIXTT_NUMBER;
0489      switch(InfixRV_rvals-->maxi)
0490      { ',//':     acc = (InfixRV_rvals-->rop);
0491        '=//', 'pre++', 'post++', 'pre--', 'post--':
0492                   lvalside = lop;
0493                   switch(InfixRV_rvals-->maxi)
0494                   {   '=//': acc = (InfixRV_rvals-->rop);
0495                       'pre++': acc = (InfixRV_rvals-->rop) + 1; lvalside = rop;
0496                       'pre--': acc = (InfixRV_rvals-->rop) - 1; lvalside = rop;
0497                       'post++': acc = (InfixRV_rvals-->lop) + 1;
0498                       'post--': acc = (InfixRV_rvals-->lop) - 1;
0499                   }
0500                   switch (InfixRV_op-->lvalside)
0501                   {   './/':
0502                         (InfixRV_lop-->lvalside).(InfixRV_rop-->lvalside) = acc;
0503                       '->':
0504                         (InfixRV_lop-->lvalside)->(InfixRV_rop-->lvalside) = acc;
0505                       '-->':
0506                         (InfixRV_lop-->lvalside)-->(InfixRV_rop-->lvalside) = acc;
0507                       default:
0508                           w = InfixRV_lvals-->lvalside; if (w == -1) return -1;
0509                           @storew #globals_array w acc;
0510                   }
0511                   switch(InfixRV_rvals-->maxi)
0512                   {   'post++': acc--;
0513                       'post--': acc++;
0514                   }
0515        '(rcall':  sysfun_f = false;
0516                   switch (InfixRV_op-->lop)
0517                   {   './/': a = InfixRV_lop-->lop; b = InfixRV_rop-->lop;
0518                       default:
0519                           a = InfixRV_rvals-->lop; b = call;
0520                           if (InfixRV_lvals-->lop == INFIXTT_SYSFUN)
0521                               sysfun_f = true;
0522                   }
0523                   w = 0;
0524                   i = maxi + 1; base = 100;
0525                   if (InfixRV_types-->i == -1 && InfixRV_rvals-->i == ')//')
0526                   {   if (sysfun_f) return -1;
0527                       acc = a.b();
0528                   }
0529                   else
0530                   {   while (base > 0)
0531                       {   if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == ')//')
0532                               base = base - 100;
0533                           if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == '(//')
0534                               base = base + 100;
0535                           if (InfixRV_op-->i=='(rcall') base = base + 100;
0536                           if (base == 100 && InfixRV_op-->i == ',//')
0537                           {   InfixRV_commas-->(w++) = i;
0538  !                             print "Comma found at ", i, "^";
0539                           }
0540                           i++;
0541                       }
0542  !                     print "Num args = ", w + 1, "^";
0543  !                     for (i = 0 : i < w : i++)
0544  !                         print "arg: ", InfixRV_lop-->(InfixRV_commas-->i), "^";
0545  !                     print "arg: ", InfixRV_rvals-->rop, "^";
0546                       switch(w+1)
0547                       {   1: if (sysfun_f)
0548                              {   b = InfixRV_rvals-->rop;
0549                                  infix_term_type = INFIXTT_NAMEDOBJECT;
0550                                  switch(a)
0551                                  {   'metaclass': acc = metaclass(b);
0552                                      'parent': acc = parent(b);
0553                                      'child': acc = child(b);
0554                                      'children': acc = children(b);
0555                                           infix_term_type = INFIXTT_NUMBER;
0556                                      'random': acc = random(b);
0557                                           infix_term_type = INFIXTT_NUMBER;
0558                                      'sibling': acc = sibling(b);
0559                                  }
0560                              }
0561                              else
0562                                  acc = a.b(InfixRV_rvals-->rop);
0563                           2: if (sysfun_f) return -1;
0564                              acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0565                                        InfixRV_rvals-->rop);
0566                           3: if (sysfun_f) return -1;
0567                              acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0568                                        InfixRV_lop-->(InfixRV_commas-->1),
0569                                        InfixRV_rvals-->rop);
0570                           4: if (sysfun_f) return -1;
0571                              acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0572                                        InfixRV_lop-->(InfixRV_commas-->1),
0573                                        InfixRV_lop-->(InfixRV_commas-->2),
0574                                        InfixRV_rvals-->rop);
0575                           5: if (sysfun_f) return -1;
0576                              acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
0577                                        InfixRV_lop-->(InfixRV_commas-->1),
0578                                        InfixRV_lop-->(InfixRV_commas-->2),
0579                                        InfixRV_lop-->(InfixRV_commas-->3),
0580                                        InfixRV_rvals-->rop);
0581                           default: return -1;
0582                       }                     
0583                   }
0584        '+//':     acc = (InfixRV_rvals-->lop) + (InfixRV_rvals-->rop);
0585        '-//':     acc = (InfixRV_rvals-->lop) - (InfixRV_rvals-->rop);
0586        '*//':     acc = (InfixRV_rvals-->lop) * (InfixRV_rvals-->rop);
0587        '@{2f}//': acc = (InfixRV_rvals-->lop) / (InfixRV_rvals-->rop);
0588        '%//':     acc = (InfixRV_rvals-->lop) % (InfixRV_rvals-->rop);
0589        './/':     acc = (InfixRV_rvals-->lop) . (InfixRV_rvals-->rop);
0590        '->':      acc = (InfixRV_rvals-->lop) -> (InfixRV_rvals-->rop);
0591        '-->':     acc = (InfixRV_rvals-->lop) --> (InfixRV_rvals-->rop);
0592        ']&':      acc = (InfixRV_rvals-->lop) .& (InfixRV_rvals-->rop);
0593        ']#':      acc = (InfixRV_rvals-->lop) .# (InfixRV_rvals-->rop);
0594        '::':      acc = (InfixRV_rvals-->lop) :: (InfixRV_rvals-->rop);
0595        '&//':     acc = (InfixRV_rvals-->lop) & (InfixRV_rvals-->rop);
0596        '|//':     acc = (InfixRV_rvals-->lop) | (InfixRV_rvals-->rop);
0597        '&&':      acc = (InfixRV_rvals-->lop) && (InfixRV_rvals-->rop);
0598                   infix_term_type = INFIXTT_LOGICAL;
0599        '||':      acc = (InfixRV_rvals-->lop) || (InfixRV_rvals-->rop);
0600                   infix_term_type = INFIXTT_LOGICAL;
0601        '':     acc = (InfixRV_rvals-->lop) < (InfixRV_rvals-->rop);
0602                   infix_term_type = INFIXTT_LOGICAL;
0603        '<=':      acc = (InfixRV_rvals-->lop) <= (InfixRV_rvals-->rop);
0604                   infix_term_type = INFIXTT_LOGICAL;
0605        '>//':     acc = (InfixRV_rvals-->lop) > (InfixRV_rvals-->rop);
0606                   infix_term_type = INFIXTT_LOGICAL;
0607        '>=':      acc = (InfixRV_rvals-->lop) >= (InfixRV_rvals-->rop);
0608                   infix_term_type = INFIXTT_LOGICAL;
0609        '==':      acc = (InfixRV_rvals-->lop) == (InfixRV_rvals-->rop);
0610                   infix_term_type = INFIXTT_LOGICAL;
0611        '[=':  acc = (InfixRV_rvals-->lop) ~= (InfixRV_rvals-->rop);
0612                   infix_term_type = INFIXTT_LOGICAL;
0613        'has':     acc = (InfixRV_rvals-->lop) has (InfixRV_rvals-->rop);
0614                   infix_term_type = INFIXTT_LOGICAL;
0615        'hasnt':   acc = (InfixRV_rvals-->lop) hasnt (InfixRV_rvals-->rop);
0616                   infix_term_type = INFIXTT_LOGICAL;
0617        'in':      acc = (InfixRV_rvals-->lop) in (InfixRV_rvals-->rop);
0618                   infix_term_type = INFIXTT_LOGICAL;
0619        'notin':   acc = (InfixRV_rvals-->lop) notin (InfixRV_rvals-->rop);
0620                   infix_term_type = INFIXTT_LOGICAL;
0621        'provides': acc = (InfixRV_rvals-->lop) provides (InfixRV_rvals-->rop);
0622                   infix_term_type = INFIXTT_LOGICAL;
0623        'ofclass': acc = (InfixRV_rvals-->lop) ofclass (InfixRV_rvals-->rop);
0624                   infix_term_type = INFIXTT_LOGICAL;
0625        '[[':      acc = ~~ (InfixRV_rvals-->rop); flag = true;
0626        '[//':     acc = ~ (InfixRV_rvals-->rop); flag = true;
0627        'unary-':  acc = - (InfixRV_rvals-->rop); flag = true;
0628      }
0629        InfixRV_rvals-->maxi = acc;
0630        InfixRV_types-->maxi = -1;
0631        if (rop < n) InfixRV_types-->rop = -2;
0632        if (flag==false && lop >= 0) InfixRV_types-->lop = -2;
0633    }
0634  ];
0635   
0636  ! ------------------------------------------------------------------------
0637   
0638  [ InfixWelcomeSub;
0639    print "; Welcome to the ~Infix~ debugger (1/990428), which makes the
0640        following verbs available:^^
0641        ~; ~: evaluates this Inform expression: e.g.
0642        ~; location~ will print the value of the variable ~location~,
0643        ~; 3*5+1~ will print 16, ~; children(old cloth bag)~ will tell you
0644        how many items are in it. (You can name objects either by their
0645        names inside the source code, such as ~n_obj~, or by typing the
0646        names by which the game's parser would normally know them, such
0647        as ~north wall~: the effect is the same.)^
0648        Any expression is allowed except that you can't use double-quoted
0649        strings of text: but you can send messages, call routines or
0650        assign values to variables, properties and array entries.
0651        ^   ~; score++~ is one way to get on in the world.
0652        ^   ~; deadflag = true~ is one way to get out of it.
0653        ^   ~; StopDaemon(nasty little dwarf)~ will keep you from being pestered.^
0654        Conditions like ~; score>20~ are also allowed and print
0655        either 1 (if true) or 0 (if false).^^";
0656    print "~;examine ~ or ~;x ~ gives full details
0657        of whatever it is. For instance, ~;x ##Take~ describes the Take
0658        action; ~;x Class~ the class Class; ~;x 'drop'~ the dictionary
0659        word ~drop~ and so on for numbers, routines, arrays and of course
0660        objects.  ~;xo~ examines something as an object, so for instance
0661        ~;x location~ tells you about the variable ~location~, but ~;xo
0662        location~ tells you what object it refers to.^^";
0663    print "~;give~, ~;remove~ and ~;move~ work like the corresponding
0664        Inform statements.^^";
0665    print "~;<~ causes an action: for instance, ~;< Eat cheese~.^^";
0666    print "~;watch~ or ~;w~ can set a watch on various activities:
0667        type just ~;w~ for details.^^";
0668    print "~;inventory~ or ~;i~ describes the contents of this story file.^";
0669  ];
0670  [ InfixEvalSub;
0671    InfixExamineP(true);
0672  ];
0673  [ InfixActionSub;
0674    print "; <", (InfixPrintAction) infix_lvalue;
0675    if (noun) print " (", (the) noun, ")";
0676    if (second) print " (", (the) second, ")";
0677    print ">^";
0678    if (second) <<(infix_lvalue) noun second>>;
0679    if (noun) <<(infix_lvalue) noun>>;
0680    <<(infix_lvalue)>>;
0681  ];
0682  [ InfixGiveSub f;
0683    print "; give (", (the) noun, ") ";
0684    if (second<0) { second = ~second; f=true; }
0685    if (second < 0 || second>=48) "";
0686    if (f) print "@@126";
0687    print (DebugAttribute) second;
0688    if (f) @clear_attr noun second;
0689    else @set_attr noun second;
0690  ];
0691  [ InfixMoveSub;
0692    print "; move (", (the) noun, ") to (", (the) second, ")";
0693    move noun to second;
0694  ];
0695  [ InfixRemoveSub;
0696    print "; remove (", (the) noun, ")";
0697    remove noun;
0698  ];
0699  [ InfixHex x y;
0700        y = (x & $7f00) / $100;
0701        if (x<0) y=y+$80;
0702        x = x & $ff;
0703        print (Infixhexdigit) y/$10, (Infixhexdigit) y,
0704              (Infixhexdigit) x/$10, (Infixhexdigit) x;
0705  ];
0706  [ Infixhexdigit x;
0707    x = x % $10; if (x<10) print x; else print (char) 'a'+x-10;
0708  ];
0709  [ InfixExamineOSub;
0710    infix_data1 = metaclass(noun);
0711    infix_term_type = INFIXTT_CONSTANT;
0712    InfixExamineP(false);
0713  ];
0714  [ InfixExamineSSub;
0715    infix_term_type = INFIXTT_STATICSTRING;
0716    InfixExamineP(false);
0717  ];
0718  [ InfixExamineSub;
0719    InfixExamineP(false);
0720  ];
0721  [ InfixExamineP brief x a b w flag lines;
0722    switch(infix_term_type)
0723    {   INFIXTT_NUMBER:
0724            if (brief) "; == ", noun;
0725            print "; The number ", noun, " == $", (InfixHex) noun;
0726            if (noun >= 32 && noun < 127) print " == '", (char) noun, "'";
0727            new_line;
0728        INFIXTT_NAMEDOBJECT:
0729            print "~", (name) noun, "~ (", noun, ")^"; if (brief) return;
0730            <>;
0731        INFIXTT_CONSTANT:
0732            if (brief) "; == ", noun;
0733            switch(infix_data1 & 15)
0734            {   nothing:
0735                    print "; Constant ", (InfixPrintConstant) infix_parsed_lvalue,
0736                    " == ", noun, "^";
0737                Object: <>;
0738                Class: print "Class ", (name) noun, "^";
0739                    objectloop (a ofclass noun)
0740                    {   if (flag) print ", "; else print "Contains: ";
0741                        print (name) a, " (", a, ")"; flag=true;
0742                    }
0743                    if (flag==false) "No object is of this class";
0744            }
0745            new_line;
0746        INFIXTT_ATTRIBUTE:
0747            if (brief) "; == ", noun;
0748            if (noun>=48 || noun<0) "; No such attribute";
0749            print "; Attribute ", (InfixPrintAttribute) noun,
0750                " (numbered ", noun, ")^";
0751            objectloop (x has noun)
0752            {   if (flag) print ", ";
0753                else print "Each of these ~has ", (InfixPrintAttribute) noun, "~: ";
0754                print (name) x, " (", x, ")"; flag = true;
0755            }
0756            if (flag == false) "No object ~has ", (InfixPrintAttribute) noun, "~";
0757            new_line;
0758        INFIXTT_PROPERTY:
0759            if (brief) "; == ", noun;
0760            print "; Property ", (property) noun, " (numbered ", noun, ")^";
0761            objectloop (x provides noun)
0762            {   if (flag) print ", "; else print "Provided by: ";
0763                print (name) x, " (", x, ")"; flag = true;
0764            }
0765            if (flag == false) "Which is not provided by any object";
0766            new_line;
0767        INFIXTT_DWORD:
0768            if (brief) "; == ", noun;
0769            if (noun == 0) "; This word is not in the dictionary";
0770            a = noun->#dict_par1;
0771            print "; Dictionary word '", (address) noun;
0772            if (a & 4) print "//p";
0773            print "' (address ", noun, ")";
0774            if (a)
0775            {   print ": ";
0776                if (a & 2) print "meta ";
0777                if (a & 1) print "verb   ";
0778                if (a & 8) print "preposition   ";
0779                if (a & 4) print "pluralising ";
0780                if (a & 128) print "noun ";
0781            }
0782            new_line;
0783            if (a & 1) <>;
0784        INFIXTT_ROUTINE:
0785            if (brief) "; == ", noun;
0786            print "; Routine ", (InfixPrintRoutine) infix_parsed_lvalue,
0787                " (number ", infix_parsed_lvalue, ",
0788                packed address ", noun, ")^";
0789        INFIXTT_GLOBAL:
0790            if (brief) "; == ", noun;
0791            print "; Global ", (InfixPrintGlobal) infix_parsed_lvalue,
0792                " == ", noun, "^";
0793        INFIXTT_ARRAY:
0794            if (brief) "; == ", noun;
0795            print "; Array ", (InfixPrintArray) infix_parsed_lvalue, " ";
0796            infix_data1 = infix_data1 % 16;
0797            switch(infix_data1)
0798            {   0: print "->"; a=0;
0799                1: print "-->"; a=0;
0800                2: print "string"; a=1;
0801                3: print "table"; a=1;
0802            }
0803            print " ", infix_data2, "^; == "; b=infix_data2; if (x) b++;
0804            for (w=b-1:w>=a:w--)
0805                if (infix_data1 == 0 or 2) { if (noun->w) break; }
0806                else { if (noun-->w) break; }
0807            if (b-1-w <= 5) w=b-1;
0808            for (:x<=w:x++)
0809                if (infix_data1 == 0 or 2) print noun->x, " ";
0810                else print noun-->x, " ";
0811            if (w
0812            else if (w
0813            new_line;
0814        INFIXTT_ACTION:
0815            if (brief) "; == ", noun;
0816            if (noun >= #lowest_fake_action_number
0817                && noun <= #highest_fake_action_number)
0818               "; Fake action ", (InfixPrintFakeAction) noun,
0819                " (numbered ", noun, ")^Is not generated by any grammar";
0820            print "; Action ", (InfixPrintAction) noun,
0821                " (numbered ", noun, ")^";
0822            w = 0-->4;
0823            for (b=0:b<(0-->4 + 5)-->0:b++)
0824            {   w = 0-->4 + 7 + b*9;
0825                if ((w->#dict_par1) & 1)
0826                {   a = (0-->7)-->($ff-(w->#dict_par2));
0827                    lines = a->0; a++;
0828                    for (:lines > 0:lines--)
0829                    {   a = UnpackGrammarLine(a);
0830                        if (action_to_be == noun)
0831                        {   print "'", (address) w, "' "; DebugGrammarLine();
0832                            new_line;
0833                            flag = true;
0834                        }
0835                    }
0836                }
0837            }
0838            if (flag == 0) "Is not generated by any grammar";
0839        INFIXTT_SYSFUN:
0840            if (brief) "; == ", noun;
0841           "; System function ~", (address) infix_parsed_lvalue, "~ has
0842            not been overridden by any routine and so has its standard
0843            definition.";
0844        INFIXTT_STATICSTRING:
0845            if (brief) "; == ", noun;
0846            if (metaclass(noun) ~= String) "; ", noun, " is not a string.";
0847            print "~", (string) noun, "~^";
0848        INFIXTT_LOGICAL:
0849            if (noun==true) "; true"; if (noun==false) "; false";
0850            "; ", noun;
0851    }
0852  ];
0853  [ InfixDescribeWatchSub x y z s flag aflag;
0854    print "; The Infix ~;watch~ verb allows you to set a watch on any named
0855        routine(s) or objects: for instance ~;watch ScoreSub~ or
0856        ~;watch silver bars~. You can also:
0857        ^    ~;watch objects~: changes to attribute or property settings";
0858    if (debug_flag & 8) print " (on)"; else print " (off)";
0859   
0860        print ";^    ~;watch timers~: the running of timers and daemons each turn";
0861    if (debug_flag & 4) print " (on)"; else print " (off)";
0862   
0863        print ";^    ~;watch messages~: all messages sent";
0864    if (debug_flag & 1) print " (on)"; else print " (off)";
0865   
0866        print ";^    ~;watch actions~: all actions generated";
0867    if (debug_flag & 2) print " (on)"; else print " (off)";
0868   
0869        print ".^~~;watch~ can be abbreviated to ~;w~ and use ~off~ to stop
0870        watching: for instance ~;w location off~.^";
0871    aflag = debug_flag;
0872    objectloop (x has infix__watching) flag = true; aflag = aflag || flag;
0873    if (flag) print "The following objects are currently being watched: ";
0874    flag = false;
0875    objectloop (x has infix__watching)
0876    {   if (flag) print ", "; flag = true;
0877        print (name) x, " (", x, ")";
0878    }
0879    if (flag) new_line;
0880    s = (#highest_routine_number - #lowest_routine_number);
0881    if (s%8 == 0) s=s/8; else s=s/8+1;
0882    for (flag=false, x=0:xx) flag = true;
0883    aflag = aflag || flag;
0884    if (flag) print "The following routines are currently being watched: ";
0885    for (x=0, flag=false:x
0886    {   for (y=1,z=0:y<256:z++,y=y*2)
0887        {   if ((#routine_flags_array->x) & y)
0888            {   if (flag) print ", "; flag = true;
0889                print (InfixPrintRoutine)
0890                    #lowest_routine_number + x*8 + z;
0891            }
0892        }
0893    }
0894    if (flag) new_line;
0895    if (aflag == false) "At present, nothing is being watched.";
0896  ];
0897  [ InfixWatchOnSub i j k l;
0898    if (noun == 0) return InfixDescribeWatchSub();
0899    if (infix_term_type == INFIXTT_ROUTINE)
0900    {   i = infix_parsed_lvalue/8;
0901        for (j=0,k=1:j
0902        l = #routine_flags_array->i;
0903        l = l | k;
0904        @storeb #routine_flags_array i l;
0905       "; Watching routine ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
0906    }
0907    if (metaclass(noun) == Object)
0908    {   give noun infix__watching;
0909       "; Watching object ~", (name) noun, "~ (", noun, ").";  
0910    }
0911    InfixDescribeWatchSub();
0912  ];
0913  [ InfixWatchOffSub i j k l;
0914    if (noun == 0) return InfixDescribeWatchSub();
0915    if (infix_term_type == INFIXTT_ROUTINE)
0916    {   i = infix_parsed_lvalue/8;
0917        for (j=0,k=1:j
0918        l = #routine_flags_array->i;
0919        l = l & (~k);
0920        @storeb #routine_flags_array i l;
0921       "; Not watching ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
0922    }
0923    if (metaclass(noun) == Object)
0924    {   @clear_attr noun infix__watching;
0925       "; Not watching object ~", (name) noun, "~ (", noun, ").";  
0926    }
0927    InfixDescribeWatchSub();
0928  ];
0929  [ InfixList from to tab filter i flag;
0930    print "^    ";
0931    for (i=from:i<=to:i++)
0932        if (tab-->(i-from))
0933        {   flag = true;
0934            if (tab == #array_names_array)
0935            {   Symb__Tab(INFIXTT_ARRAY, i);
0936                flag = ~~(temp__global3 & 16);
0937            }
0938            if (tab == #routine_names_array)
0939            {   Symb__Tab(INFIXTT_ROUTINE,i);
0940                flag = ~~(temp__global3 & 16);
0941            }
0942            if (tab == #constant_names_array)
0943            {   Symb__Tab(INFIXTT_CONSTANT,i);
0944                flag = (~~(temp__global3 & 16)) && (temp__global3 % 16 == filter);
0945            }
0946            if (flag) print (string) tab-->(i-from), " ";
0947        }
0948    new_line;
0949  ];
0950  [ InfixInvSub i;
0951   
0952    print (string) Story, (string) Headline;
0953    print "  ", (number) #highest_object_number - #lowest_object_number + 1,
0954        " objects;^";
0955    print "  non-library object-name constants:";
0956    InfixList(#lowest_constant_number, #highest_constant_number,
0957        #constant_names_array, 2);
0958    print "  ", (number) #highest_class_number - #lowest_class_number + 1,
0959        "  classes:^    ";
0960    for (i=#lowest_class_number:i<=#highest_class_number:i++)
0961        print (name) #class_objects_array-->i, " ";
0962    new_line;
0963    print "  non-library arrays:";
0964    InfixList(#lowest_array_number, #highest_array_number,
0965        #array_names_array);
0966    print "  non-library routines:";
0967    InfixList(#lowest_routine_number, #highest_routine_number,
0968        #routine_names_array);
0969    print "  non-library constants:";
0970    InfixList(#lowest_constant_number, #highest_constant_number,
0971        #constant_names_array, 0);
0972    print "  (common) properties:";
0973    InfixList(#lowest_property_number, 63, #property_names_array);
0974    print "  (individual) properties:";
0975    InfixList(64, #highest_property_number, #property_names_array + 126);
0976    print "  attributes:";
0977    InfixList(#lowest_attribute_number, #highest_attribute_number,
0978        #attribute_names_array);
0979    if (true) return;
0980    print "  variables:";
0981    InfixList(#lowest_global_number, #highest_global_number,
0982        #global_names_array);
0983    print "  actions:";
0984    InfixList(#lowest_action_number, #highest_action_number,
0985        #action_names_array);
0986    print "  fake actions:";
0987    InfixList(#lowest_fake_action_number, #highest_fake_action_number,
0988        #fake_action_names_array);
0989  ];
0990   
0991  Verb meta ";i" ";inv" ";inventory"
0992       * -> InfixInv;
0993  Verb meta ";x" ";examine"
0994       * InfixRvalue -> InfixExamine;
0995  Verb meta ";xo" ";examineo"
0996       * InfixRvalue -> InfixExamineO;
0997  Verb meta ";xs" ";examines"
0998       * InfixRvalue -> InfixExamineS;
0999  Verb meta ";<"
1000       * InfixActionToken -> InfixAction
1001       * InfixActionToken InfixRvalue -> InfixAction
1002       * InfixActionToken InfixRvalue InfixRvalue -> InfixAction;
1003  Verb meta ";"
1004       * -> InfixWelcome
1005       * InfixRvalue -> InfixEval;
1006  Verb meta ";give"
1007       * InfixRvalue InfixRvalue -> InfixGive;
1008  Verb meta ";move"
1009       * InfixRvalue "to" InfixRvalue -> InfixMove;
1010  Verb meta ";remove"
1011       * InfixRvalue -> InfixRemove;
1012  Verb meta ";watch" ";w"
1013       * -> InfixWatchOn
1014       * "timers"/"daemons" -> TimersOn
1015       * "timers"/"daemons" "off" -> TimersOff
1016       * "actions" -> ActionsOn
1017       * "actions" "off" -> ActionsOff
1018       * "messages" -> RoutinesOn
1019       * "messages" "off" -> RoutinesOff
1020       * "objects" -> ChangesOn
1021       * "objects" "off" -> ChangesOff
1022       * InfixRvalueTerm -> InfixWatchOn
1023       * InfixRvalueTerm "off" -> InfixWatchOff;
1024   
1025  ! ------------------------------------------------------------------------


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.