home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / games / inform / compiler / source / c / zcode < prev   
Encoding:
Text File  |  1994-07-15  |  34.4 KB  |  900 lines

  1. /* ------------------------------------------------------------------------- */
  2. /*   "zcode" : Z-opcodes, text translation and abbreviation routines         */
  3. /*                                                                           */
  4. /*   Part of Inform release 5                                                */
  5. /*                                                                           */
  6. /*   On non-ASCII machines, translate_to_ascii must be altered               */
  7. /* ------------------------------------------------------------------------- */
  8.  
  9. #include "header.h"
  10.  
  11. int32 total_chars_trans, total_bytes_trans, trans_length;
  12. int chars_lookup[256];
  13. int abbrevs_lookup[256], almade_flag=0;
  14.  
  15. extern int translate_to_ascii(char c)
  16. {   return((int) c);
  17. }
  18.  
  19. const char *alphabet[3] = {
  20.     "abcdefghijklmnopqrstuvwxyz",
  21.     "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  22.     " ^0123456789.,!?_#'~/\\-:()"
  23. };
  24.  
  25. extern void make_lookup(void)
  26. {   int i, j, k;
  27.     for (j=0; j<256; j++)
  28.     {   chars_lookup[j]=127; abbrevs_lookup[j]= -1; }
  29.     for (j=0; j<3; j++)
  30.         for (k=0; k<26; k++)
  31.         {   i=(int) ((alphabet[j])[k]);
  32.             chars_lookup[i]=k+j*26;
  33.         }
  34. }
  35.  
  36. extern void make_abbrevs_lookup(void)
  37. {   int i, j, k, l; char p[MAX_ABBREV_LENGTH]; char *p1, *p2;
  38.     do
  39.     { for (i=0, j=0; j<no_abbrevs; j++)
  40.         for (k=j+1; k<no_abbrevs; k++)
  41.         {   p1=abbreviations_at+j*MAX_ABBREV_LENGTH;
  42.             p2=abbreviations_at+k*MAX_ABBREV_LENGTH;
  43.             if (strcmp(p1,p2)<0)
  44.             {   i=1; strcpy(p,p1); strcpy(p1,p2); strcpy(p2,p);
  45.                 l=abbrev_values[j]; abbrev_values[j]=abbrev_values[k];
  46.                 abbrev_values[k]=l;
  47.                 l=abbrev_quality[j]; abbrev_quality[j]=abbrev_quality[k];
  48.                 abbrev_quality[k]=l;
  49.             }
  50.         }
  51.     } while (i==1);
  52.     for (j=no_abbrevs-1; j>=0; j--)
  53.     {   p1=abbreviations_at+j*MAX_ABBREV_LENGTH;
  54.         abbrevs_lookup[p1[0]]=j;
  55.         abbrev_freqs[j]=0;
  56.     }
  57.     almade_flag=1;
  58. }
  59.  
  60. static int z_chars[3], uptothree;
  61. static int total_zchars_trans;
  62. static unsigned char *text_pc;
  63.  
  64. static void write_z_char(int i)
  65. {   uint32 j;
  66.     total_zchars_trans++;
  67.     z_chars[uptothree++]=(i%32);
  68.     if (uptothree!=3) return;
  69.     j= z_chars[0]*0x0400 + z_chars[1]*0x0020 + z_chars[2];
  70.     text_pc[0] = j/256;
  71.     text_pc[1] = j%256;
  72.     uptothree=0; text_pc+=2;
  73.     total_bytes_trans+=2;
  74. }
  75.  
  76. static void end_z_chars(void)
  77. {   unsigned char *p;
  78.     trans_length=total_zchars_trans-trans_length;
  79.     while (uptothree!=0) write_z_char(5);
  80.     p=(unsigned char *) text_pc;
  81.     *(p-2)= *(p-2)+128;
  82. }
  83.  
  84.  
  85. static int try_abbreviations_from(unsigned char *text, int i, int from)
  86. {   int j, k; char *p, c;
  87.     c=text[i];
  88.     for (j=from, p=abbreviations_at+from*MAX_ABBREV_LENGTH;
  89.          (j<no_abbrevs)&&(c==p[0]); j++, p+=MAX_ABBREV_LENGTH)
  90.     {   if (text[i+1]==p[1])
  91.         {   for (k=2; p[k]!=0; k++)
  92.                 if (text[i+k]!=p[k]) goto NotMatched;
  93.             for (k=0; p[k]!=0; k++) text[i+k]=1;
  94.             abbrev_freqs[j]++;
  95.             return(j);
  96.             NotMatched: ; 
  97.         }
  98.     }
  99.     return(-1);
  100. }
  101.  
  102. extern char *translate_text(char *p, char *s_text)
  103. {   int i, j, k, newa, cc, value, value2;
  104.     unsigned char *text;
  105.  
  106.     trans_length=total_zchars_trans;
  107.  
  108.     if ((almade_flag==0)&&(no_abbrevs!=0)&&(abbrev_mode!=0))
  109.         make_abbrevs_lookup();
  110.  
  111.     if ((pass_number==2)&&(abbrev_mode!=0)&&(store_the_text==1))
  112.     {   
  113.         sprintf(all_text_p, "%s\n\n", s_text);
  114.         all_text_p+=strlen(all_text_p);
  115.     }
  116.  
  117.     text=(unsigned char *) s_text;
  118.  
  119.     uptothree=0; text_pc=(unsigned char *) p;
  120.     for (i=0; text[i]!=0; i++)
  121.     {   total_chars_trans++;
  122.         if (double_spaced==1)
  123.         {   if ((text[i]=='.')&&(text[i+1]==' ')&&(text[i+2]==' '))
  124.                 text[i+2]=1;
  125.         }
  126.         if ((economy_mode==1)&&(abbrev_mode!=0)
  127.             &&((k=abbrevs_lookup[text[i]])!=-1))
  128.         {   if ((j=try_abbreviations_from(text, i, k))!=-1)
  129.             {   if (j<32) { write_z_char(2); write_z_char(j); }
  130.                 else { write_z_char(3); write_z_char(j-32); }
  131.             }
  132.         }
  133.         if (text[i]=='@')
  134.         {   if (text[i+1]=='@')
  135.             {   i+=2;
  136.                 value=atoi((char *) (text+i));
  137.                 write_z_char(5); write_z_char(6);
  138.                 write_z_char(value/32); write_z_char(value%32);
  139.                 while (isdigit(text[i])) i++; i--;
  140.             }
  141.             else
  142.             {   value= -1;
  143.                 switch(text[i+1])
  144.                 {   case '0': value=0; break;
  145.                     case '1': value=1; break;
  146.                     case '2': value=2; break;
  147.                     case '3': value=3; break;
  148.                     case '4': value=4; break;
  149.                     case '5': value=5; break;
  150.                     case '6': value=6; break;
  151.                     case '7': value=7; break;
  152.                     case '8': value=8; break;
  153.                     case '9': value=9; break;
  154.                 }
  155.                 value2= -1;
  156.                 switch(text[i+2])
  157.                 {   case '0': value2=0; break;
  158.                     case '1': value2=1; break;
  159.                     case '2': value2=2; break;
  160.                     case '3': value2=3; break;
  161.                     case '4': value2=4; break;
  162.                     case '5': value2=5; break;
  163.                     case '6': value2=6; break;
  164.                     case '7': value2=7; break;
  165.                     case '8': value2=8; break;
  166.                     case '9': value2=9; break;
  167.                 }
  168.                 if ((value!=-1)&&(value2!=-1))
  169.                 {   i++; i++;
  170.                     write_z_char(1); write_z_char(value*10+value2);
  171.                 }
  172.             }
  173.         }
  174.         else
  175.         {   if (text[i]!=1)
  176.             {   if (text[i]==' ') write_z_char(0);
  177.                 else
  178.                 {   cc=chars_lookup[(int) (text[i])];
  179.                     if (cc==127)
  180.                     {   write_z_char(5); write_z_char(6);
  181.                         j=translate_to_ascii(text[i]);
  182.                         write_z_char(j/32); write_z_char(j%32);
  183.                     }
  184.                     else
  185.                     {   newa=cc/26; value=cc%26;
  186.                         if (newa==1) write_z_char(4);
  187.                         if (newa==2) write_z_char(5);
  188.                         write_z_char(value+6);
  189.                     }
  190.                 }
  191.             }
  192.         }
  193.     }
  194.     end_z_chars();
  195.     return((char *) text_pc);
  196. }
  197.  
  198. /* ------------------------------------------------------------------------- */
  199. /*   The (static) Z-code database (using a table adapted from that in the    */
  200. /*   InfoToolkit disassembler "txd")                                         */
  201. /* ------------------------------------------------------------------------- */
  202.  
  203. static opcode the_opcode(int i,char *s,int k,int l,int m)
  204. {   opcode op;  op.name=s;  op.code=i;  op.type1=k;  op.type2=l;  op.no=m;
  205.     return(op);
  206. }
  207.  
  208. extern opcode opcs(int32 i)
  209.    switch(i)
  210.     {
  211.     case  0: return(the_opcode(0x01, "je",              BRANCH,   NONE, TWO));
  212.     case  1: return(the_opcode(0x02, "jl",              BRANCH,   NONE, TWO));
  213.     case  2: return(the_opcode(0x03, "jg",              BRANCH,   NONE, TWO));
  214.     case  3: return(the_opcode(0x04, "dec_chk",         BRANCH,    VAR, TWO));
  215.     case  4: return(the_opcode(0x05, "inc_chk",         BRANCH,    VAR, TWO));
  216.     case  5: return(the_opcode(0x06, "same_parent",     BRANCH,   NONE, TWO));
  217.     case  6: return(the_opcode(0x07, "test",            BRANCH,   NONE, TWO));
  218.     case  7: return(the_opcode(0x08, "or",               STORE,   NONE, TWO));
  219.     case  8: return(the_opcode(0x09, "and",              STORE,   NONE, TWO));
  220.     case  9: return(the_opcode(0x0A, "test_attr",       BRANCH,   NONE, TWO));
  221.     case 10: return(the_opcode(0x0B, "set_attr",          NONE,   NONE, TWO));
  222.     case 11: return(the_opcode(0x0C, "clear_attr",        NONE,   NONE, TWO));
  223.     case 12: return(the_opcode(0x0D, "store",             NONE,    VAR, TWO));
  224.     case 13: return(the_opcode(0x0D, "store",             NONE,    VAR, VARI));
  225.     case 14: return(the_opcode(0x0E, "insert_obj",        NONE,   NONE, TWO));
  226.     case 15: return(the_opcode(0x0F, "loadw",            STORE,   NONE, TWO));
  227.     case 16: return(the_opcode(0x10, "loadb",            STORE,   NONE, TWO));
  228.     case 17: return(the_opcode(0x11, "get_prop",         STORE,   NONE, TWO));
  229.     case 18: return(the_opcode(0x12, "get_prop_addr",    STORE,   NONE, TWO));
  230.     case 19: return(the_opcode(0x13, "get_next_prop",    STORE,   NONE, TWO));
  231.     case 20: return(the_opcode(0x14, "add",              STORE,   NONE, TWO));
  232.     case 21: return(the_opcode(0x15, "sub",              STORE,   NONE, TWO));
  233.     case 22: return(the_opcode(0x16, "mul",              STORE,   NONE, TWO));
  234.     case 23: return(the_opcode(0x17, "div",              STORE,   NONE, TWO));
  235.     case 24: return(the_opcode(0x18, "mod",              STORE,   NONE, TWO));
  236.  
  237.     case 25: return(the_opcode(0x01, "je",              BRANCH,   NONE, VARI));
  238.  
  239.     case 26: return(the_opcode(0x20, "call",              CALL,   NONE, VARI));
  240.     case 27: return(the_opcode(0x20, "call",             STORE,   NONE, VARI));
  241.     case 28: return(the_opcode(0x21, "storew",            NONE,   NONE, VARI));
  242.     case 29: return(the_opcode(0x22, "storeb",            NONE,   NONE, VARI));
  243.     case 30: return(the_opcode(0x23, "put_prop",          NONE,   NONE, VARI));
  244.     case 32: return(the_opcode(0x25, "print_char",       PCHAR,   NONE, VARI));
  245.     case 33: return(the_opcode(0x26, "print_num",         NONE,   NONE, VARI));
  246.     case 34: return(the_opcode(0x27, "random",           STORE,   NONE, VARI));
  247.     case 35: return(the_opcode(0x28, "push",              NONE,   NONE, VARI));
  248.     case 36: return(the_opcode(0x29, "pull",              NONE,    VAR, VARI));
  249.     case 37: return(the_opcode(0x2A, "split_window",      NONE,   NONE, VARI));
  250.     case 38: return(the_opcode(0x2B, "set_window",        NONE,   NONE, VARI));
  251.     case 39: return(the_opcode(0x33, "output_stream",     NONE,   NONE, VARI));
  252.     case 40: return(the_opcode(0x34, "input_stream",      NONE,   NONE, VARI));
  253.     case 41: return(the_opcode(0x35, "sound_effect",      NONE,   NONE, VARI));
  254.  
  255.     case 42: return(the_opcode(0x00, "jz",              BRANCH,   NONE, ONE));
  256.     case 43: return(the_opcode(0x01, "get_sibling",      STORE, OBJECT, ONE));
  257.     case 44: return(the_opcode(0x02, "get_child",        STORE, OBJECT, ONE));
  258.     case 45: return(the_opcode(0x03, "get_parent",       STORE,   NONE, ONE));
  259.     case 46: return(the_opcode(0x04, "get_prop_len",     STORE,   NONE, ONE));
  260.     case 47: return(the_opcode(0x05, "inc",               NONE,    VAR, ONE));
  261.     case 48: return(the_opcode(0x06, "dec",               NONE,    VAR, ONE));
  262.     case 49: return(the_opcode(0x07, "print_addr",        NONE,   NONE, ONE));
  263.  
  264.     case 50: return(the_opcode(0x09, "remove_obj",        NONE,   NONE, ONE));
  265.     case 51: return(the_opcode(0x0A, "print_obj",         NONE,   NONE, ONE));
  266.     case 52: return(the_opcode(0x0B, "ret",             RETURN,   NONE, ONE));
  267.     case 53: return(the_opcode(0x0C, "jump",              JUMP,   NONE, ONE));
  268.     case 54: return(the_opcode(0x0D, "print_paddr",       NONE,   NONE, ONE));
  269.     case 55: return(the_opcode(0x0E, "load",             STORE,    VAR, ONE));
  270.  
  271.     case 57: return(the_opcode(0x00, "rtrue",           RETURN,   NONE, ZERO));
  272.     case 58: return(the_opcode(0x01, "rfalse",          RETURN,   NONE, ZERO));
  273.     case 59: return(the_opcode(0x02, "print",             NONE,   TEXT, ZERO));
  274.     case 60: return(the_opcode(0x03, "print_ret",       RETURN,   TEXT, ZERO));
  275.     case 63: return(the_opcode(0x07, "restart",           NONE,   NONE, ZERO));
  276.     case 64: return(the_opcode(0x08, "ret_popped",      RETURN,   NONE, ZERO));
  277.     case 65: return(the_opcode(0x09, "pop",               NONE,   NONE, ZERO));
  278.     case 66: return(the_opcode(0x0A, "quit",              NONE,   NONE, ZERO));
  279.     case 67: return(the_opcode(0x0B, "new_line",          NONE,   NONE, ZERO));
  280.     case 69: return(the_opcode(0x0D, "verify",          BRANCH,   NONE, ZERO));
  281.   }
  282.  
  283.   if ((version_number==3) && (i==68))
  284.              return(the_opcode(0x0C, "show_status",       NONE,   NONE, ZERO));
  285.  
  286.   if ((version_number==3) || (version_number==4))
  287.   { switch(i)
  288.     {
  289.     case 31: return(the_opcode(0x24, "read",              NONE,   NONE, VARI));
  290.     case 56: return(the_opcode(0x0F, "not",              STORE,   NONE, ONE));
  291.     case 61: return(the_opcode(0x05, "save",            BRANCH,   NONE, ZERO));
  292.     case 62: return(the_opcode(0x06, "restore",         BRANCH,   NONE, ZERO));
  293.     }
  294.   }
  295.  
  296.   if (version_number>=4)
  297.   { switch(i)
  298.     {
  299.     case 70: return(the_opcode(0x19, "call_2s",           CALL,   NONE, TWO));
  300.  
  301.     case 72: return(the_opcode(0x20, "call_vs",           CALL,   NONE, VARI));
  302.     case 89: return(the_opcode(0x2C, "call_vs2",          CALL,   NONE, VARI));
  303.     case 75: return(the_opcode(0x2D, "erase_window",      NONE,   NONE, VARI));
  304.     case 76: return(the_opcode(0x2E, "erase_line",        NONE,   NONE, VARI));
  305.     case 77: return(the_opcode(0x2F, "set_cursor",        NONE,   NONE, VARI));
  306.     case 78: return(the_opcode(0x31, "set_text_style",    NONE,   NONE, VARI));
  307.     case 79: return(the_opcode(0x32, "buffer_mode",       NONE,   NONE, VARI));
  308.     case 96: return(the_opcode(0x35, "sound_effect",      NONE,   NONE, VARI));
  309.     case 80: return(the_opcode(0x36, "read_char",        STORE,   NONE, VARI));
  310.     case 81: return(the_opcode(0x37, "scan_table",       STORE, OBJECT, VARI));
  311.  
  312.     case 98: return(the_opcode(0x04, "nop",               NONE,   NONE, ZERO));
  313.  
  314.     case 82: return(the_opcode(0x08, "call_1s",           CALL,   NONE, ONE));
  315.     }
  316.   }
  317.  
  318.   if (version_number>=5)
  319.   { switch(i)
  320.     {
  321.     case 71: return(the_opcode(0x1a, "call_2n",          NCALL,   NONE, TWO));
  322.     case 99: return(the_opcode(0x1b, "set_colour",       NCALL,   NONE, TWO));
  323.    case 100: return(the_opcode(0x1c, "throw",            NCALL,   NONE, TWO));
  324.     case 90: return(the_opcode(0x24, "read",             STORE,   NONE, VARI));
  325.  
  326.     case 61: return(the_opcode(0x00, "save",             STORE,   NONE, EXTD));
  327.     case 62: return(the_opcode(0x01, "restore",          STORE,   NONE, EXTD));
  328.     case 85: return(the_opcode(0x02, "log_shift",        STORE,   NONE, EXTD));
  329.     case 91: return(the_opcode(0x03, "art_shift",        STORE,   NONE, EXTD));
  330.     case 86: return(the_opcode(0x04, "set_font",         STORE,   NONE, EXTD));
  331.     case 87: return(the_opcode(0x09, "save_undo",        STORE,   NONE, EXTD));
  332.     case 88: return(the_opcode(0x0A, "restore_undo",     STORE,   NONE, EXTD));
  333.  
  334.     case 56: return(the_opcode(0x38, "not",               NONE,   NONE, VARI));
  335.     case 73: return(the_opcode(0x39, "call_vn",          NCALL,   NONE, VARI));
  336.     case 74: return(the_opcode(0x3a, "call_vn2",         NCALL,   NONE, VARI));
  337.     case 97: return(the_opcode(0x3b, "tokenise",          NONE,   NONE, VARI));
  338.    case 101: return(the_opcode(0x3c, "encode_text",       NONE,   NONE, VARI));
  339.    case 102: return(the_opcode(0x3d, "copy_table",        NONE,   NONE, VARI));
  340.    case 103: return(the_opcode(0x3e, "print_table",       NONE,   NONE, VARI));
  341.     case 84: return(the_opcode(0x3f, "check_arg_count", BRANCH,   NONE, VARI));
  342.  
  343.     case 83: return(the_opcode(0x0F, "call_1n",          NCALL,   NONE, ONE));
  344.  
  345.    case 104: return(the_opcode(0x09, "catch",            STORE,   NONE, ZERO));
  346.    case 105: return(the_opcode(0x0F, "piracy",          BRANCH,   NONE, ZERO));
  347.     }
  348.   }
  349.  
  350.   if (version_number==6)
  351.   { switch(i)
  352.     {
  353.     case 92: return(the_opcode(0x05, "draw_picture",      NONE,   NONE, EXTD));
  354.     case 93: return(the_opcode(0x06, "picture_data",    BRANCH,   NONE, EXTD));
  355.     case 94: return(the_opcode(0x07, "erase_picture",     NONE,   NONE, EXTD));
  356.     case 106: return(the_opcode(0x08, "set_margins",       NONE,   NONE, EXTD));
  357.  
  358.     case 107: return(the_opcode(0x10, "move_window",       NONE,   NONE, EXTD));
  359.     case 108: return(the_opcode(0x11, "window_size",       NONE,   NONE, EXTD));
  360.     case 109: return(the_opcode(0x12, "window_style",      NONE,   NONE, EXTD));
  361.     case 110: return(the_opcode(0x13, "get_wind_prop",    STORE,   NONE, EXTD));
  362.     case 111: return(the_opcode(0x14, "scroll_window",     NONE,   NONE, EXTD));
  363.     case 112: return(the_opcode(0x15, "pop_stack",         NONE,   NONE, EXTD));
  364.     case 113: return(the_opcode(0x16, "read_mouse",        NONE,   NONE, EXTD));
  365.     case 114: return(the_opcode(0x17, "mouse_window",      NONE,   NONE, EXTD));
  366.     case 115: return(the_opcode(0x18, "push_stack",      BRANCH,   NONE, EXTD));
  367.     case 116: return(the_opcode(0x19, "put_wind_prop",     NONE,   NONE, EXTD));
  368.     case 117: return(the_opcode(0x1a, "print_form",        NONE,   NONE, EXTD));
  369.     case 118: return(the_opcode(0x1b, "make_menu",       BRANCH,   NONE, EXTD));
  370.     case 119: return(the_opcode(0x1c, "picture_table",     NONE,   NONE, EXTD));
  371.     }
  372.   }
  373.  
  374.   return(the_opcode(0xff,"???",INVALID,NONE,ZERO));
  375. }
  376.  
  377. /* ------------------------------------------------------------------------- */
  378. /*   Creating reserved words                                                 */
  379. /* ------------------------------------------------------------------------- */
  380.  
  381. #define CreateD_(x,y) prim_new_symbol(x,y,14,6)
  382. #define CreateC_(x,y) prim_new_symbol(x,y,15,6)
  383. #define CreateB_(x,y,z) prim_new_symbol(x,z+y*100,16,6)
  384. #define CreateA_(x,y) prim_new_symbol(x,y,17,6)
  385.  
  386. extern void stockup_symbols(void)
  387. {   char *r1="RET#TRUE", *r2="RET#FALSE";
  388.  
  389.     new_symbol("nothing",0,9);
  390.  
  391.     new_symbol("sp",0,4);    new_symbol("ret#true",1,4);
  392.     new_symbol("rtrue",1,4); new_symbol("ret#false",2,4);
  393.     new_symbol("rfalse",2,4);
  394.  
  395.     new_symbol("=",1,10);    new_symbol("==",1,10);
  396.     new_symbol(">",2,10);    new_symbol("<",3,10);
  397.     new_symbol("has",4,10);
  398.     new_symbol("near",5,10);
  399.     new_symbol("~=",6,10);   new_symbol("<=",7,10);
  400.     new_symbol(">=",8,10);
  401.     new_symbol("hasnt",9,10);  new_symbol("far",10,10);
  402.  
  403.     new_symbol("name",1,12);
  404.  
  405.     new_symbol("temp_global",239,2);
  406.     new_symbol("temp_global2",238,2);
  407.     new_symbol("temp_global3",237,2);
  408.     new_symbol("sys_glob0",0,2);
  409.     new_symbol("sys_glob1",1,2);
  410.     new_symbol("sys_glob2",2,2);
  411.  
  412.     CreateD_("ABBREVIATE", ABBREVIATE_CODE);
  413.     CreateD_("ATTRIBUTE",  ATTRIBUTE_CODE);
  414.     CreateD_("CONSTANT",   CONSTANT_CODE);
  415.     CreateD_("DICTIONARY", DICTIONARY_CODE);
  416.     CreateD_("END",        END_CODE);
  417.     CreateD_("INCLUDE",    INCLUDE_CODE);
  418.     CreateD_("GLOBAL",     GLOBAL_CODE);
  419.     CreateD_("OBJECT",     OBJECT_CODE);
  420.     CreateD_("PROPERTY",   PROPERTY_CODE);
  421.     CreateD_("RELEASE",    RELEASE_CODE);
  422.     CreateD_("SWITCHES",   SWITCHES_CODE);
  423.     CreateD_("STATUSLINE", STATUSLINE_CODE); 
  424.     CreateD_("VERB",       VERB_CODE);
  425.     CreateD_("TRACE",      TRACE_CODE);
  426.     CreateD_("NOTRACE",    NOTRACE_CODE);
  427.     CreateD_("ETRACE",     ETRACE_CODE);
  428.     CreateD_("NOETRACE",   NOETRACE_CODE);
  429.     CreateD_("BTRACE",     BTRACE_CODE);
  430.     CreateD_("NOBTRACE",   NOBTRACE_CODE);
  431.     CreateD_("LTRACE",     LTRACE_CODE);
  432.     CreateD_("NOLTRACE",   NOLTRACE_CODE);
  433.     CreateD_("ATRACE",     ATRACE_CODE);
  434.     CreateD_("NOATRACE",   NOATRACE_CODE);
  435.     CreateD_("LISTSYMBOLS", LISTSYMBOLS_CODE);
  436.     CreateD_("LISTOBJECTS", LISTOBJECTS_CODE);
  437.     CreateD_("LISTVERBS",  LISTVERBS_CODE);
  438.     CreateD_("LISTDICT",   LISTDICT_CODE);
  439.     CreateD_("[",          OPENBLOCK_CODE);
  440.     CreateD_("]",          CLOSEBLOCK_CODE);
  441.     CreateD_("SERIAL",     SERIAL_CODE);
  442.     CreateD_("DEFAULT",    DEFAULT_CODE);
  443.     CreateD_("STUB",       STUB_CODE);
  444.     CreateD_("VERSION",    VERSION_CODE);
  445.     CreateD_("IFV3",       IFV3_CODE);
  446.     CreateD_("IFV5",       IFV5_CODE);
  447.     CreateD_("IFDEF",      IFDEF_CODE);
  448.     CreateD_("IFNDEF",     IFNDEF_CODE);
  449.     CreateD_("ENDIF",      ENDIF_CODE);
  450.     CreateD_("IFNOT",      IFNOT_CODE);
  451.     CreateD_("LOWSTRING",  LOWSTRING_CODE);
  452.     CreateD_("CLASS",      CLASS_CODE);
  453.     CreateD_("FAKE_ACTION", FAKE_ACTION_CODE);
  454.     CreateD_("NEARBY",     NEARBY_CODE);
  455.     CreateD_("SYSTEM_FILE", SYSTEM_CODE);
  456.     CreateD_("REPLACE",    REPLACE_CODE);
  457.     CreateD_("EXTEND",     EXTEND_CODE);
  458.  
  459.     CreateB_("PRINT_ADDR", PRINT_ADDR_CODE,   49);
  460.     CreateB_("PRINT_CHAR", PRINT_CHAR_CODE,   32);
  461.     CreateB_("PRINT_PADDR", PRINT_PADDR_CODE, 54);
  462.     CreateB_("PRINT_OBJ",  PRINT_OBJ_CODE,    51);
  463.     CreateB_("PRINT_NUM",  PRINT_NUM_CODE,    33);
  464.     CreateB_("RESTORE",    RESTORE_CODE,      62);
  465.     CreateB_("SAVE",       SAVE_CODE,         61);
  466.     CreateB_("PRINT",      PRINT_CODE,        59);
  467.     CreateB_("PRINT_RET",  PRINT_RET_CODE,    60);
  468.     
  469.     CreateC_("REMOVE",     REMOVE_CODE);
  470.     CreateC_("RETURN",     RETURN_CODE);
  471.     CreateC_("DO",         DO_CODE);
  472.     CreateC_("FOR",        FOR_CODE);
  473.     CreateC_("IF",         IF_CODE);
  474.     CreateC_("OBJECTLOOP", OBJECTLOOP_CODE);
  475.     CreateC_("UNTIL",      UNTIL_CODE);
  476.     CreateC_("WHILE",      WHILE_CODE);
  477.     CreateC_("BREAK",      BREAK_CODE);
  478.     CreateC_("ELSE",       ELSE_CODE);
  479.     CreateC_("GIVE",       GIVE_CODE);
  480.     CreateC_("INVERSION",  INVERSION_CODE);
  481.     CreateC_("MOVE",       MOVE_CODE);
  482.     CreateC_("PUT",        PUT_CODE);
  483.     CreateC_("WRITE",      WRITE_CODE);
  484.     CreateC_("STRING",     STRING_CODE);
  485.     CreateC_("FONT",       FONT_CODE);
  486.     CreateC_("READ",       READ_CODE);
  487.     CreateC_("STYLE",      STYLE_CODE);
  488.     CreateC_("SPACES",     SPACES_CODE);
  489.     CreateC_("BOX",        BOX_CODE);
  490.  
  491.     CreateA_("JE",0);
  492.     CreateA_("JL",1);
  493.     CreateA_("JG",2);
  494.     CreateA_("JZ",42);
  495.     CreateA_("JUMP",53);
  496.     CreateA_("SREAD",31);
  497.     CreateA_("RANDOM",34);
  498.     CreateA_("RET",52);
  499.     CreateA_(r1,57);
  500.     CreateA_(r2,58);
  501.     CreateA_("RTRUE",57);
  502.     CreateA_("RFALSE",58);
  503.     CreateA_("RESTART",63);
  504.     CreateA_("RETSP",64);
  505.     CreateA_("REMOVE_OBJ",50);
  506.     CreateA_("PUT_PROP",30);
  507.     CreateA_("PUSH",35);
  508.     CreateA_("PULL",36);
  509.     CreateA_("POP",65);
  510.     CreateA_("GET_SIBLING",43);
  511.     CreateA_("GET_CHILD",44);
  512.     CreateA_("GET_PARENT",45);
  513.     CreateA_("GET_PROP_LEN",46);
  514.     CreateA_("GET_PROP",17);
  515.     CreateA_("GET_PROP_ADDR",18);
  516.     CreateA_("GET_NEXT_PROP",19);
  517.     CreateA_("SET_ATTR",10);
  518.     CreateA_("STORE",12);
  519.     CreateA_("SUB",21);
  520.     CreateA_("STOREW",28);
  521.     CreateA_("STOREB",29);
  522.     CreateA_("SPLIT_WINDOW",37);
  523.     CreateA_("SET_WINDOW",38);
  524.     CreateA_("OUTPUT_STREAM",39);
  525.     CreateA_("SOUND_EFFECT",41);
  526.     CreateA_("SHOW_SCORE",68);
  527.     CreateA_("DEC_CHK",3);
  528.     CreateA_("INC_CHK",4);
  529.     CreateA_("COMPARE_POBJ",5);
  530.     CreateA_("TEST",6);
  531.     CreateA_("OR",7);
  532.     CreateA_("AND",8);
  533.     CreateA_("TEST_ATTR",9);
  534.     CreateA_("CLEAR_ATTR",11);
  535.     CreateA_("LSTORE",13);
  536.     CreateA_("INSERT_OBJ",14);
  537.     CreateA_("LOADW",15);
  538.     CreateA_("LOADB",16);
  539.     CreateA_("ADD",20);
  540.     CreateA_("MUL",22);
  541.     CreateA_("DIV",23);
  542.     CreateA_("MOD",24);
  543.     CreateA_("VJE",25);
  544.     CreateA_("CALL",26);
  545.     CreateA_("ICALL",27);
  546.     CreateA_("INPUT_STREAM",40);
  547.     CreateA_("INC",47);
  548.     CreateA_("DEC",48);
  549.     CreateA_("LOAD",55);
  550.     CreateA_("NOT",56);
  551.     CreateA_("QUIT",66);
  552.     CreateA_("NEW_LINE",67);
  553.     CreateA_("VERIFY",69);
  554.  
  555.     CreateA_("CALL_2S",70);
  556.     CreateA_("CALL_2N",71);
  557.     CreateA_("CALL_VS",72);
  558.     CreateA_("CALL_VN",73);
  559.     CreateA_("CALL_VN2",74);
  560.     CreateA_("ERASE_WINDOW",75);
  561.     CreateA_("ERASE_LINE",76);
  562.     CreateA_("SET_CURSOR",77);
  563.     CreateA_("SET_TEXT_STYLE",78);
  564.     CreateA_("BUFFER_MODE",79);
  565.     CreateA_("READ_CHAR",80);
  566.     CreateA_("SCANW",81);
  567.     CreateA_("CALL_1S",82);
  568.     CreateA_("CALL_1N",83);
  569.     CreateA_("CHECK_NO_ARGS",84);
  570.  
  571.     CreateA_("LOG_SHIFT",85);
  572.     CreateA_("SET_FONT",86);
  573.     CreateA_("SAVE_UNDO",87);
  574.     CreateA_("RESTORE_UNDO",88);
  575.  
  576.     CreateA_("CALL_VS2",89);
  577.  
  578.     CreateA_("AREAD",90);
  579.     CreateA_("ART_SHIFT",91);
  580.     CreateA_("DRAW_PICTURE",92);
  581.     CreateA_("PICTURE_DATA",93);
  582.     CreateA_("ERASE_PICTURE",94);
  583.     CreateA_("INPUT_STREAM",95);
  584.     CreateA_("BEEP",96);
  585.     CreateA_("APARSE",97);
  586.  
  587.     CreateA_("NOP",98);
  588.     CreateA_("COLOUR",99);
  589.     CreateA_("THROW",100);
  590.     CreateA_("ENCRYPT",101);
  591.     CreateA_("COPY_TABLE",102);
  592.     CreateA_("PRINT_TABLE",103);
  593.     CreateA_("CATCH",104);
  594.     CreateA_("PIRACY",105);
  595.     CreateA_("SET_MARGINS",106);
  596.     CreateA_("MOVE_WINDOW",107);
  597.     CreateA_("WINDOW_SIZE",108);
  598.     CreateA_("WINDOW_STYLE",109);
  599.     CreateA_("GET_WIND_PROP",110);
  600.     CreateA_("SCROLL_WINDOW",111);
  601.     CreateA_("POP_STACK",112);
  602.     CreateA_("READ_MOUSE",113);
  603.     CreateA_("MOUSE_WINDOW",114);
  604.     CreateA_("PUSH_STACK",115);
  605.     CreateA_("PUT_WIND_PROP",116);
  606.     CreateA_("PRINT_FORM",117);
  607.     CreateA_("MAKE_MENU",118);
  608.     CreateA_("PICTURE_TABLE",119);
  609.  
  610.     CreateA_("IO_BUFFER_MODE",79);  /* Alias for BUFFER_MODE */
  611.     CreateA_("SAME_PARENT",5);      /* for COMPARE_POBJ */
  612.     CreateA_("SET_COLOUR",99);      /* for COLOUR */
  613.     CreateA_("RET_POPPED",64);      /* for RETSP */
  614.     CreateA_("SHOW_STATUS",68);     /* for SHOW_SCORE */
  615.     CreateA_("SCAN_TABLE",81);      /* for SCANW */
  616.     CreateA_("TOKENISE",97);        /* for APARSE */
  617.     CreateA_("ENCODE_TEXT",101);    /* for ENCRYPT */
  618.     CreateA_("CHECK_ARG_COUNT",84); /* for CHECK_NO_ARGS */
  619.  
  620. }
  621.  
  622. /* ------------------------------------------------------------------------- */
  623. /*   The abbreviations optimiser                                             */
  624. /* ------------------------------------------------------------------------- */
  625.  
  626. typedef struct tlb_s
  627. {   char text[4];
  628.     int intab, occurrences;
  629. } tlb;
  630. static tlb *tlbtab;
  631. static int no_occs;
  632.  
  633. static int32 *grandtable;
  634. static int *grandflags;
  635. typedef struct optab_s
  636. {   int  length;
  637.     int  popularity;
  638.     int  score;
  639.     int  location;
  640.     char text[64];
  641. } optab;
  642. static optab *bestyet, *bestyet2;
  643.  
  644. static int pass_no=0;
  645.  
  646. static void optimise_pass(void)
  647. {   int32 i; time_t t1, t2;
  648.     int j, j2, k, nl, matches, noflags, score, min, minat, x, scrabble, c;
  649.     for (i=0; i<256; i++) bestyet[i].length=0;
  650.     for (i=0; i<no_occs; i++)
  651.     {   if ((i!=(int) '\n')&&(tlbtab[i].occurrences!=0))
  652.         {   printf("Pass %d, %4d/%d '%s' (%d occurrences) ",
  653.                 pass_no, i, no_occs, tlbtab[i].text, tlbtab[i].occurrences);
  654.             t1=time(0);
  655.             for (j=0; j<tlbtab[i].occurrences; j++)
  656.             {   for (j2=0; j2<tlbtab[i].occurrences; j2++) grandflags[j2]=1;
  657.                 nl=2; noflags=tlbtab[i].occurrences;
  658.                 while ((noflags>=2)&&(nl<=62))
  659.                 {   nl++;
  660.                     for (j2=0; j2<nl; j2++)
  661.                         if (all_text[grandtable[tlbtab[i].intab+j]+j2]=='\n')
  662.                             goto FinishEarly;
  663.                     matches=0;
  664.                     for (j2=j; j2<tlbtab[i].occurrences; j2++)
  665.                     {   if (grandflags[j2]==1)
  666.                         {   x=grandtable[tlbtab[i].intab+j2]
  667.                               - grandtable[tlbtab[i].intab+j];
  668.                          if (((x>-nl)&&(x<nl))
  669.                             || (memcmp(all_text+grandtable[tlbtab[i].intab+j],
  670.                                        all_text+grandtable[tlbtab[i].intab+j2],
  671.                                        nl)!=0))
  672.                             {   grandflags[j2]=0; noflags--; }
  673.                             else matches++;
  674.                         }
  675.                     }
  676.                     scrabble=0;
  677.                     for (k=0; k<nl; k++)
  678.                     {   scrabble++;
  679.                         c=all_text[grandtable[tlbtab[i].intab+j+k]];
  680.                         if (c!=(int) ' ')
  681.                         {   if (chars_lookup[c]==127)
  682.                                 scrabble+=2;
  683.                             else
  684.                                 if (chars_lookup[c]>=26)
  685.                                     scrabble++;
  686.                         }
  687.                     }
  688.                     score=(matches-1)*(scrabble-2);
  689.                     min=score;
  690.                     for (j2=0; j2<256; j2++)
  691.                     {   if ((nl==bestyet[j2].length)
  692.                                 && (memcmp(all_text+bestyet[j2].location,
  693.                                        all_text+grandtable[tlbtab[i].intab+j],
  694.                                        nl)==0))
  695.                         {   j2=256; min=score; }
  696.                         else    
  697.                         {   if (bestyet[j2].score<min)
  698.                             {   min=bestyet[j2].score; minat=j2;
  699.                             }
  700.                         }
  701.                     }
  702.                     if (min!=score)
  703.                     {   bestyet[minat].score=score;
  704.                         bestyet[minat].length=nl;
  705.                         bestyet[minat].location=grandtable[tlbtab[i].intab+j];
  706.                         bestyet[minat].popularity=matches;
  707.                         for (j2=0; j2<nl; j2++) sub_buffer[j2]=
  708.                             all_text[bestyet[minat].location+j2];
  709.                         sub_buffer[nl]=0;
  710.                     }
  711.                 }
  712.                 FinishEarly: ;
  713.             }
  714.             t2=time(0)-t1;
  715.             printf(" (%d seconds)\n",t2);
  716.         }
  717.     }
  718. }
  719.  
  720. static int any_overlap(char *s1, char *s2)
  721. {   int a, b, i, j, flag;
  722.     a=strlen(s1); b=strlen(s2);
  723.     for (i=1-b; i<a; i++)
  724.     {   flag=0;
  725.         for (j=0; j<b; j++)
  726.             if ((0<=i+j)&&(i+j<=a-1))
  727.                 if (s1[i+j]!=s2[j]) flag=1;
  728.         if (flag==0) return(1);
  729.     }
  730.     return(0);
  731. }
  732.  
  733. #define MAX_TLBS 8000
  734.  
  735. extern void optimise_abbreviations(void)
  736. {   int32 i, t, max=0, MAX_GTABLE;
  737.     int j, j2, selected, available, maxat, nl;
  738.     tlb test;
  739.  
  740.     printf("Beginning calculation of optimal abbreviations...\n");
  741.  
  742.     tlbtab=my_calloc(sizeof(tlb), MAX_TLBS, "tlb table"); no_occs=0;
  743.     for (i=0; i<MAX_TLBS; i++) tlbtab[i].occurrences=0;
  744.  
  745.     bestyet=my_calloc(sizeof(optab), 256, "bestyet");
  746.     bestyet2=my_calloc(sizeof(optab), 64, "bestyet2");
  747.  
  748.             bestyet2[0].text[0]='.';
  749.             bestyet2[0].text[1]=' ';
  750.             bestyet2[0].text[2]=' ';
  751.             bestyet2[0].text[3]=0;
  752.  
  753.             bestyet2[1].text[0]=',';
  754.             bestyet2[1].text[1]=' ';
  755.             bestyet2[1].text[2]=0;
  756.  
  757.     for (i=0, t=0; all_text+i<all_text_p; i++)
  758.     {
  759.         if ((all_text[i]=='.') && (all_text[i+1]==' ') && (all_text[i+2]==' '))
  760.         {   all_text[i]='\n'; all_text[i+1]='\n'; all_text[i+2]='\n';
  761.             bestyet2[0].popularity++;
  762.         }
  763.  
  764.         if ((all_text[i]=='.') && (all_text[i+1]==' '))
  765.         {   all_text[i]='\n'; all_text[i+1]='\n';
  766.             bestyet2[0].popularity++;
  767.         }
  768.  
  769.         if ((all_text[i]==',') && (all_text[i+1]==' '))
  770.         {   all_text[i]='\n'; all_text[i+1]='\n';
  771.             bestyet2[1].popularity++;
  772.         }
  773.     }
  774.  
  775.     MAX_GTABLE=subtract_pointers(all_text_p,all_text)+1;
  776.     grandtable=my_calloc(4*sizeof(int32), MAX_GTABLE/4, "grandtable");
  777.  
  778.     for (i=0, t=0; all_text+i<all_text_p; i++)
  779.     {   test.text[0]=all_text[i];
  780.         test.text[1]=all_text[i+1];
  781.         test.text[2]=all_text[i+2];
  782.         test.text[3]=0;
  783.         if ((test.text[0]=='\n')||(test.text[1]=='\n')||(test.text[2]=='\n'))
  784.             goto DontKeep;
  785.         for (j=0; j<no_occs; j++)
  786.             if (strcmp(test.text,tlbtab[j].text)==0)
  787.                 goto DontKeep;
  788.         test.occurrences=0;
  789.         for (j=i+3; all_text+j<all_text_p; j++)
  790.         {   if ((all_text[i]==all_text[j])
  791.                  && (all_text[i+1]==all_text[j+1])
  792.                  && (all_text[i+2]==all_text[j+2]))
  793.                  {   grandtable[t+test.occurrences]=j;
  794.                      test.occurrences++;
  795.                      if (t+test.occurrences==MAX_GTABLE)
  796.                      {   printf("All %d cross-references used\n",
  797.                              MAX_GTABLE);
  798.                          goto Built;
  799.                      }
  800.                  }
  801.         }
  802.         if (test.occurrences>=2)
  803.         {   tlbtab[no_occs]=test;
  804.             tlbtab[no_occs].intab=t; t+=tlbtab[no_occs].occurrences;
  805.             if (max<tlbtab[no_occs].occurrences)
  806.                 max=tlbtab[no_occs].occurrences;
  807.             no_occs++;
  808.             if (no_occs==MAX_TLBS)
  809.             {   printf("All %d three-letter-blocks used\n",
  810.                     MAX_TLBS);
  811.                 goto Built;
  812.             }
  813.         }
  814.         DontKeep: ;
  815.     }
  816.  
  817.     Built:
  818.     grandflags=my_calloc(sizeof(int), max, "grandflags");
  819.  
  820.  
  821.     printf("Cross-reference table (%d entries) built...\n",no_occs);
  822.     /*  for (i=0; i<no_occs; i++)
  823.             printf("%4d %4d '%s' %d\n",i,tlbtab[i].intab,tlbtab[i].text,
  824.                 tlbtab[i].occurrences);
  825.     */
  826.  
  827.     for (i=0; i<64; i++) bestyet2[i].length=0; selected=2;
  828.     available=256;
  829.     while ((available>0)&&(selected<64))
  830.     {   printf("Pass %d\n", ++pass_no);
  831.  
  832.         optimise_pass();
  833.         available=0;
  834.         for (i=0; i<256; i++)
  835.             if (bestyet[i].score!=0)
  836.             {   available++;
  837.                 nl=bestyet[i].length;
  838.                 for (j2=0; j2<nl; j2++) bestyet[i].text[j2]=
  839.                     all_text[bestyet[i].location+j2];
  840.                 bestyet[i].text[nl]=0;
  841.             }
  842.  
  843. /*      printf("End of pass results:\n");
  844.         printf("\nno   score  freq   string\n");
  845.         for (i=0; i<256; i++)
  846.             if (bestyet[i].score>0)
  847.                 printf("%02d:  %4d   %4d   '%s'\n", i, bestyet[i].score,
  848.                     bestyet[i].popularity, bestyet[i].text);
  849. */
  850.  
  851.         do
  852.         {   max=0;
  853.             for (i=0; i<256; i++)
  854.                 if (max<bestyet[i].score)
  855.                 {   max=bestyet[i].score;
  856.                     maxat=i;
  857.                 }
  858.  
  859.             if (max>0)
  860.             {   bestyet2[selected++]=bestyet[maxat];
  861.  
  862.                 printf("Selection %2d: '%s' (repeated %d times, scoring %d)\n",
  863.                     selected,bestyet[maxat].text, bestyet[maxat].popularity,
  864.                     bestyet[maxat].score);
  865.  
  866.                 test.text[0]=bestyet[maxat].text[0];
  867.                 test.text[1]=bestyet[maxat].text[1];
  868.                 test.text[2]=bestyet[maxat].text[2];
  869.                 test.text[3]=0;
  870.  
  871.                 for (i=0; i<no_occs; i++)
  872.                     if (strcmp(test.text,tlbtab[i].text)==0)
  873.                         break;
  874.  
  875.                 for (j=0; j<tlbtab[i].occurrences; j++)
  876.                 {   if (memcmp(bestyet[maxat].text,
  877.                                all_text+grandtable[tlbtab[i].intab+j],
  878.                                bestyet[maxat].length)==0)
  879.                     {   for (j2=0; j2<bestyet[maxat].length; j2++)
  880.                             all_text[grandtable[tlbtab[i].intab+j]+j2]='\n';
  881.                     }
  882.                 }
  883.  
  884.                 for (i=0; i<256; i++)
  885.                     if ((bestyet[i].score>0)&&
  886.                         (any_overlap(bestyet[maxat].text,bestyet[i].text)==1))
  887.                     {   bestyet[i].score=0;
  888.                        /* printf("Discarding '%s' as overlapping\n",
  889.                             bestyet[i].text); */
  890.                     }
  891.             }
  892.         } while ((max>0)&&(available>0)&&(selected<64));
  893.     }
  894.  
  895.     printf("\nChosen abbreviations (in Inform syntax):\n\n");
  896.     for (i=0; i<selected; i++)
  897.         printf("Abbreviate \"%s\";\n", bestyet2[i].text);
  898. }
  899.