Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. // ---- Занесение поименованной константы в список
  2. AddConstToTree(dword keystring,constvalue)
  3. dword ptr,newptr; // idrec structure
  4. {
  5.         newptr=LocalAlloc(0x40,recsize);
  6.         IF(EAX==NULL){
  7.                 preerror("Compiler out of memory for identifier tree");
  8.                 ExitProcess(e_outofmemory);
  9.         }
  10.         ptr=treestart;
  11.         IF(EAX == NULL ) // Пустой список?
  12.         treestart = newptr;
  13.         ELSE{
  14.                 for(;;){
  15. // Поиск свободной ссылки
  16.                         ESI=ptr;
  17.                         EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
  18.                         ESI=ptr;
  19.                         IF(long EAX<0){
  20.                         // ptr.left
  21.                                 IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим
  22.                                         DSDWORD[ESI+left]=newptr;
  23.                                         BREAK;  // ptr.left=newptr
  24.                                 }
  25.                                 ptr=DSDWORD[ESI+left];
  26.                         }
  27.                         ELSE IF(EAX!=0){
  28.                         // ptr.right
  29.                                 IF(DSDWORD[ESI+right]==0){      // Нашли пустой правый - добавим
  30.                                         DSDWORD[ESI+right]=newptr;
  31.                                         BREAK;
  32.                                 }
  33.                                 ptr=DSDWORD[ESI+right];
  34.                         }
  35.                         ELSE internalerror("string found in tree when trying to add to  it");
  36.                 }
  37.         }
  38. // Формируем новую запись в списке
  39.         ESI=newptr;
  40.         DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
  41.         lstrcpyA(DSDWORD[ESI+recid],keystring);
  42.         ESI=newptr;
  43.         DSDWORD[ESI+newid]= NULL;
  44.         DSDWORD[ESI+rectok]=tk_number;
  45.         DSDWORD[ESI+recnumber]=constvalue;
  46.         DSDWORD[ESI+recpost]=0;
  47.         DSDWORD[ESI+left]=NULL;
  48.         DSDWORD[ESI+right]=NULL;
  49.         DSDWORD[ESI+recmodline] = currmod<<16+linenumber;
  50. }
  51.  
  52. // ---- Добавить локальную переменную в список
  53. AddLocalvar(dword str,tk,ltype,num)
  54. dword newptr;
  55. {
  56.         newptr=LocalAlloc(0x40,local_size);
  57.         IF(EAX==NULL){
  58.                 preerror("Compiler out of memory for local symbol linked list");
  59.                 ExitProcess(e_outofmemory);
  60.         }
  61.         IF(locallist==NULL)locallist = newptr;
  62.         ELSE{
  63.                 EAX=locallist;
  64.                 EBX><EAX;       //ptr;
  65.                 for(;;){
  66.                         EAX=DSDWORD[EBX+localnext];
  67.                         IF(EAX==0)BREAK;
  68.                         EBX><EAX;
  69.                 }
  70.                 DSDWORD[EBX+localnext]=newptr;
  71.         }
  72.         EBX=newptr;
  73.         lstrcpyA(EBX+localid,str);
  74.         EBX=newptr;
  75.         DSDWORD[EBX+localtok] = tk;
  76.         DSDWORD[EBX+localtype] = ltype;
  77.         DSDWORD[EBX+localnumber] = num;
  78.         DSDWORD[EBX+localnext] = NULL;
  79.         localptr=EBX;
  80. }
  81.  
  82. // ---- Добавить идентификатор в список
  83. AddToTree(dword keystring)
  84. dword ptr,newptr;
  85. {
  86.         newptr=LocalAlloc(0x40,recsize);
  87.         IF(EAX==NULL)outofmemory();
  88.         ptr = treestart;
  89. //WRITESTR(keystring);WRITESTR("\n");
  90.         IF(EAX==NULL)treestart = newptr;
  91.         ELSE{
  92.                 for(;;){
  93. // Поиск свободной ссылки
  94.                         ESI=ptr;
  95.                         EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
  96.                         ESI=ptr;
  97.                         IF(long EAX<0){
  98.                         // ptr.left
  99.                                 IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим
  100.                                         DSDWORD[ESI+left]=newptr;
  101.                                         BREAK;  // ptr.left=newptr
  102.                                 }
  103.                                 ptr=DSDWORD[ESI+left];
  104.                         }
  105.                         ELSE IF(EAX!=0){
  106.                                 // ptr.right
  107.                                 IF(DSDWORD[ESI+right]==0){      // Нашли пустой правый - добавим
  108.                                         DSDWORD[ESI+right]=newptr;
  109.                                         BREAK;
  110.                                 }
  111.                                 ptr=DSDWORD[ESI+right];
  112.                         }
  113.                         ELSE internalerror("string found in tree when trying to add to  it");
  114.                 }
  115.         }
  116.         ESI=newptr;
  117.         DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
  118.         lstrcpyA(EAX,keystring);
  119.         IF(tok == tk_string){
  120.                 ESI=newptr;
  121.                 DSDWORD[ESI+newid] = LocalAlloc(0x40,number+1);
  122.                 IF( EAX == NULL )outofmemory();
  123.                 ECX=number;
  124.                 EDI=EAX;
  125.                 ESI=#string;
  126.                 $REP $MOVSB
  127.         }
  128.         ELSE{
  129.                 IF( lstrlenA(#string) == 0 ){
  130.                         ESI=newptr;
  131.                         DSDWORD[ESI+newid]=NULL;
  132.                 }
  133.                 ELSE{
  134.                         ESI=newptr;
  135.                         DSDWORD[ESI+newid]=LocalAlloc(0x40,lstrlenA(#string)+1);
  136.                         IF( EAX == NULL )outofmemory();
  137.                         lstrcpyA(EAX,#string);
  138.                 }
  139.         }
  140.         ESI=newptr;
  141.         DSDWORD[ESI+rectok] = tok;
  142.         DSDWORD[ESI+recnumber] = number;
  143.         DSDWORD[ESI+rectype] = type;
  144.         DSDWORD[ESI+recsrc] = src;
  145.         DSDWORD[ESI+recpost] = post;
  146.         DSDWORD[ESI+left] = NULL;
  147.         DSDWORD[ESI+right] = NULL;
  148.         DSDWORD[ESI+recmodline] = modline;
  149.         treeptr = newptr;
  150. }
  151.  
  152. // ---- Вывод всех идентификаторов
  153. void DisplayTree ()
  154. {       // dump all identifiers to MAP file
  155.         fprint(mapfile,"ALL GLOBAL IDENTIFIERS LIST:\n");
  156.         fprint(mapfile,"tok    type      number    post\tIDENTIFIER\n");
  157.         numberofids = 0;
  158.         DisplayTreeAll(treestart);
  159.         wsprintfA(#mapstr,"\n    %u Unique Global Identifiers.\n\n",numberofids);
  160.         fprint(mapfile,#mapstr);
  161.         fprint(mapfile,"GLOBAL CONSTANT IDENTIFIER LIST:\n");
  162.         numberofids = 0;
  163.         DisplayTreeConstants(treestart);
  164.         wsprintfA(#mapstr,"\n    %u Unique Global Constant Value Identifiers.\n\n",numberofids);
  165.         fprint(mapfile,#mapstr);
  166. }
  167.  
  168. // ---- Вывод всего списка идентифиакторов
  169. DisplayTreeAll(dword ptr)
  170. {
  171. if( ptr != NULL ){
  172.         ESI=ptr;
  173.         DisplayTreeAll(DSDWORD[ESI+right]);
  174.         ESI=ptr;
  175.         if(DSDWORD[ESI+rectok]-DSDWORD[ESI+recpost]!=tk_API){
  176.                 wsprintfA(#mapstr,"%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok],
  177.                         DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost],
  178.                         DSDWORD[ESI+recid]);
  179.                 fprint(mapfile,#mapstr);
  180.                 EAX=DSDWORD[ESI+newid];
  181.                 IF(EAX!=0){
  182.                         IF(lstrcmpA(DSDWORD[ESI+recid],EAX) != 0 ){
  183.                                 ESI=ptr;
  184.                                 wsprintfA(#mapstr,"Alias=%s\n",DSDWORD[ESI+newid]);
  185.                                 fprint(mapfile,#mapstr);
  186.                         }
  187.                 }
  188.                 IF(list){
  189.                         ESI=ptr;
  190.                         EAX=DSDWORD[ESI+recsrc];
  191.                         IF(EAX!=0){
  192.                                 EBX=DSDWORD[ESI+recmodline]>>16;
  193.                                 EAX=FILENAMESIZE*EBX+#modules;
  194.                                 EBX=EAX;
  195.                                 wsprintfA(#mapstr,"File:%s, line=%-d:\n%s\n",EBX,
  196.                                         DSDWORD[ESI+recmodline]&0xFFFF,DSDWORD[ESI+recsrc]);
  197.                                 fprint(mapfile,#mapstr);
  198.                                 ESI=ptr; LocalFree(DSDWORD[ESI+recsrc]);        // Освободим память
  199.                                 DSDWORD[ESI+recsrc]=0;
  200.                         }
  201.                 }
  202.                 numberofids++;
  203.         }
  204.         ESI=ptr;
  205.         DisplayTreeAll(DSDWORD[ESI+left]);
  206. }
  207. }
  208.  
  209. // ---- Вывод списка глобальных констант
  210. DisplayTreeConstants(dword ptr)
  211. {
  212.         IF( ptr != NULL ){
  213.                 ESI=ptr;
  214.                 DisplayTreeConstants(DSDWORD[ESI+right]);
  215.                 ESI=ptr;
  216.                 EAX=DSDWORD[ESI+rectok];
  217.                 IF(EAX == tk_number){
  218.                         wsprintfA(#mapstr,"#define %10ld /* %8lX hex */ %s\n",
  219.                                 DSDWORD[ESI+recnumber],DSDWORD[ESI+recnumber],DSDWORD[ESI+recid]);
  220.                         fprint(mapfile,#mapstr);
  221.                         numberofids++;
  222.                 }
  223.                 ESI=ptr;
  224.                 DisplayTreeConstants(DSDWORD[ESI+left]);
  225.         }
  226. }
  227.  
  228. // ---- Вычисление значения беззнаково  константы
  229. dword DoConstDwordMath()
  230. dword value;
  231. {
  232.         IF(tok == tk_minus){
  233.                 NextTok();
  234.                 IF(tok != tk_number){
  235.                         numexpected();
  236.                         return(0);
  237.                 }
  238.                 number = -number;
  239.         }
  240.         IF(tok != tk_number){
  241.                 numexpected();
  242.                 return(0);
  243.         }
  244.         value = number;
  245.         while(tok2isopperand()){
  246.                 NextTok();
  247.                 IF(tok2!=tk_number)return(value);
  248.                 switch(tok){
  249.                         case tk_minus:   value -= number2; break;
  250.                         case tk_plus:  value += number2;         break;
  251.                         case tk_xor:            value ^= number2;  break;
  252.                         case tk_and:            value &= number2;  break;
  253.                         case tk_or:     value |= number2;        break;
  254.                         case tk_mod:            value = value % number2; BREAK;
  255.                         case tk_div:            value = value / number2; BREAK;
  256.                         case tk_mult:   value = value * number2; BREAK;
  257.                         case tk_rr:     value >>= number2;                               BREAK;
  258.                         case tk_ll:     value <<= number2;                               BREAK;
  259.                         case tk_xorminus:  value ^= -number2;    BREAK;
  260.                         case tk_andminus:  value &= -number2;    BREAK;
  261.                         case tk_orminus:         value |= -number2;      BREAK;
  262. /*              case(tok==tk_modminus)  value %= -number2;
  263.                 case(tok==tk_divminus)  value /= -number2;
  264.                 case(tok==tk_multminus) value *= -number2; */
  265.                         case tk_rrminus:         value >>= -number2;     BREAK;
  266.                         case tk_llminus:         value <<= -number2;     BREAK;
  267.                 }
  268.                 NextTok();
  269.         }
  270.         return(value);
  271. }
  272.  
  273. // ---- Вычисление значения знаковой константы
  274. long DoConstMath()
  275. long value;
  276. {
  277.         IF(tok == tk_minus){
  278.                 NextTok();
  279.                 IF(tok != tk_number){
  280.                         numexpected();
  281.                         return(0);
  282.                 }
  283.                 number = -number;
  284.         }
  285.         IF(tok != tk_number){
  286.                 numexpected();
  287.                 return(0);
  288.         }
  289.         value = number;
  290.         while(tok2isopperand()){
  291.                 NextTok();
  292.                 IF(tok2 != tk_number) return(value);
  293.                 switch(tok){
  294.                         case tk_minus:   value -= number2; break;
  295.                         case tk_plus:  value += number2;         break;
  296.                         case tk_xor:            value ^= number2;  break;
  297.                         case tk_and:            value &= number2;  break;
  298.                         case tk_or:     value |= number2;        break;
  299.                         case tk_mod:            value = value % number2; BREAK;
  300.                         case tk_div:            value = value / number2; BREAK;
  301.                         case tk_mult:   value = value * number2; BREAK;
  302.                         case tk_rr:     value >>= number2;                               BREAK;
  303.                         case tk_ll:     value <<= number2;                               BREAK;
  304.                         case tk_xorminus:  value ^= -number2;    BREAK;
  305.                         case tk_andminus:  value &= -number2;    BREAK;
  306.                         case tk_orminus:         value |= -number2;      BREAK;
  307. /*              case(tok==tk_modminus)  value %= -number2;
  308.                 case(tok==tk_divminus)  value /= -number2;
  309.                 case(tok==tk_multminus) value *= -number2; */
  310.                         case tk_rrminus:         value >>= -number2;     BREAK;
  311.                         case tk_llminus:         value <<= -number2;     BREAK;
  312.                 }
  313.                 NextTok();
  314.         }
  315.         return(value);
  316. }
  317.  
  318. // ---- Вычисление значения знаковой константы
  319. long DoConstLongMath()
  320. long value;
  321. {
  322.         value=DoConstMath();
  323.         NextTok();
  324.         return(value);
  325. }
  326.  
  327. // ---- Следующий token - операция?
  328. dword tok2isopperand()
  329. {
  330.         EAX=tok2;
  331.         IF(EAX==tk_plus)||(EAX==tk_minus)||(EAX==tk_mult)||(EAX==tk_div)||(EAX==tk_mod)||
  332.         (EAX==tk_rr)||(EAX==tk_ll)||(EAX==tk_or)||(EAX==tk_and)||(EAX==tk_xor)||
  333.         (EAX==tk_divminus)||(EAX==tk_modminus)||(EAX==tk_multminus)||(EAX==tk_xorminus)||
  334.         (EAX==tk_orminus)||(EAX==tk_andminus)||(EAX==tk_llminus)||(EAX==tk_rrminus)return(1);
  335.         return(0);
  336. }
  337.  
  338. // ---- Следующий token закрывает выражение?
  339. dword tok2notstopper ()
  340. {
  341.         EAX=tok2;
  342.         IF(EAX==tk_semicolon)||(EAX==tk_comma)||(EAX==tk_closebracket)||
  343.         (EAX==tk_openblock)EAX=0;
  344.         ELSE EAX=1;
  345. }
  346.  
  347. // ---- Поиск в списке локальных переменных
  348. SearchLocals(dword tok4,type4,string4,number4)
  349. {
  350.         if( locallist != NULL ){
  351.                 localptr = locallist;
  352. S00:
  353.                 ESI=EAX;        //localptr;
  354.                 lstrcmpA(string4,ESI+localid);
  355.                 ESI=localptr;
  356.                 IF(EAX==0){     // Переменная найдена
  357.                         EBX=number4;
  358.                         DSDWORD[EBX]=DSDWORD[ESI+localnumber];
  359.                         EBX=type4;
  360.                         DSDWORD[EBX]=DSDWORD[ESI+localtype];
  361.                         EBX=tok4;
  362.                         EAX=DSDWORD[ESI+localtok];
  363.                         DSDWORD[EBX]=EAX;
  364.                         IF(EAX==tk_local){
  365.                                 EBX=number4;
  366.                                 DSDWORD[EBX]-=localsize;
  367.                         }
  368.                         ELSE IF(EAX==tk_param){
  369.                                 EBX=number4;
  370.                                 EAX=DSDWORD[EBX]+4;
  371.                                 DSDWORD[EBX]=EAX;
  372.                                 IF(current_proc_type==cpt_far)DSDWORD[EBX]+=4;  // move over seg on stack
  373.                         }
  374.                         ELSE IF(EAX!=tk_locallabel)&&(EAX!=tk_number)internalerror("Bad *tok4 value in SearchLocals");
  375.                 }
  376.                 ELSE{
  377.                         IF(DSDWORD[ESI+localnext]!=NULL){
  378.                                 localptr=DSDWORD[ESI+localnext];
  379.                                 $JMP S00
  380.                         }
  381.                 }
  382.         }
  383. }
  384.  
  385. // ---- Поиск в списке глобальных идентификаторов
  386. dword SearchTree(dword tok4,type4,src4,post4,string4,number4)
  387. dword ptr;
  388. long cmpresult;
  389. {
  390.         cmpresult=123;
  391.         ptr = treestart;
  392. // Поиск свободной ссылки
  393.         for(;;){
  394.                 ESI=EAX;
  395.                 IF(ESI==0){
  396.                         treeptr=NULL;
  397.                         return(0);      // Not found
  398.                 }
  399.                 cmpresult = lstrcmpA(DSDWORD[ESI+recid],string4);
  400.                 ESI=ptr;
  401.                 IF(cmpresult<0)ptr=DSDWORD[ESI+left];
  402.                 ELSE IF(cmpresult>0)ptr=DSDWORD[ESI+right];
  403.                 ELSE BREAK;
  404.         }
  405.         EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+recnumber];
  406.         EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+rectype];
  407.         EBX=src4; DSDWORD[EBX]=DSDWORD[ESI+recsrc];
  408.         EBX=post4; DSDWORD[EBX]=DSDWORD[ESI+recpost];
  409.         EBX=tok4; EAX=DSDWORD[ESI+rectok]; DSDWORD[EBX]=EAX;
  410.         IF(EAX==tk_string ){
  411.                 EBX=number4; ECX=DSDWORD[EBX]; EDI=string4;
  412.                 ESI=DSDWORD[ESI+newid]; $REP $MOVSB
  413.         }
  414.         ELSE{
  415.                 IF(DSDWORD[ESI+newid])lstrcpyA(string4,DSDWORD[ESI+newid]);
  416.         }
  417.         ESI=ptr;
  418.         IF(lstrcmpA(DSDWORD[ESI+recid],string4)!=0) // Проверим: менялось ли имя идентификатора
  419.                 SearchTree(tok4,type4,src4,post4,string4,number4);      // Да - повторим поиск
  420.         treeptr = ptr;
  421.         return(1);
  422. }
  423.  
  424. // ---- Поиск неоткомпилированных еще ссылок
  425. dword SeekToDo(dword ptr)
  426. {
  427.         IF(ptr!=NULL){
  428.                 ESI=ptr;
  429.                 IF(SeekToDo(DSDWORD[ESI+right]))RETURN(1);
  430.                 ESI=ptr; EAX=DSDWORD[ESI+recpost];
  431.                 IF(EAX>1){
  432.                         treeptr=ptr; ESI=ptr;
  433.                         number=DSDWORD[ESI+recnumber];
  434.                         type=DSDWORD[ESI+rectype]; modline=DSDWORD[ESI+recmodline];
  435.                         src=DSDWORD[ESI+recsrc];
  436.                         post=DSDWORD[ESI+recpost];
  437.                         tok=DSDWORD[ESI+rectok]; RETURN(1);
  438.                 }
  439.                 ESI=ptr;
  440.                 IF(SeekToDo(DSDWORD[ESI+left]))RETURN(1);
  441.         }
  442.         return(0);
  443. }
  444.  
  445. // ---- Поиск незакрытых ссылок
  446. SeekUndefined(dword ptr)
  447. {
  448.         IF( ptr != NULL ){
  449.                 ESI=ptr;
  450.                 SeekUndefined(DSDWORD[ESI+right]);
  451.                 ESI=ptr; EAX=DSDWORD[ESI+rectok];
  452.                 IF(EAX==tk_undefproc){
  453.                         wsprintfA(#mapstr,"'%s' undefined\n",DSDWORD[ESI+recid]);
  454.                         IF( makemapfile )fprint(mapfile,#mapstr);
  455.                         WRITESTR(#mapstr);
  456.                 }
  457.                 ESI=ptr;
  458.                 SeekUndefined(DSDWORD[ESI+left]);
  459.         }
  460. }
  461.  
  462.