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 web site has not been fully supported since April 2008. Information may be out of date. This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.