// ---- Занесение поименованной константы в список AddConstToTree(dword keystring,constvalue) dword ptr,newptr; // idrec structure { newptr=LocalAlloc(0x40,recsize); IF(EAX==NULL){ preerror("Compiler out of memory for identifier tree"); ExitProcess(e_outofmemory); } ptr=treestart; IF(EAX == NULL ) // Пустой список? treestart = newptr; ELSE{ for(;;){ // Поиск свободной ссылки ESI=ptr; EAX=lstrcmpA(DSDWORD[ESI+recid],keystring); ESI=ptr; IF(long EAX<0){ // ptr.left IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим DSDWORD[ESI+left]=newptr; BREAK; // ptr.left=newptr } ptr=DSDWORD[ESI+left]; } ELSE IF(EAX!=0){ // ptr.right IF(DSDWORD[ESI+right]==0){ // Нашли пустой правый - добавим DSDWORD[ESI+right]=newptr; BREAK; } ptr=DSDWORD[ESI+right]; } ELSE internalerror("string found in tree when trying to add to it"); } } // Формируем новую запись в списке ESI=newptr; DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1); lstrcpyA(DSDWORD[ESI+recid],keystring); ESI=newptr; DSDWORD[ESI+newid]= NULL; DSDWORD[ESI+rectok]=tk_number; DSDWORD[ESI+recnumber]=constvalue; DSDWORD[ESI+recpost]=0; DSDWORD[ESI+left]=NULL; DSDWORD[ESI+right]=NULL; DSDWORD[ESI+recmodline] = currmod<<16+linenumber; } // ---- Добавить локальную переменную в список AddLocalvar(dword str,tk,ltype,num) dword newptr; { newptr=LocalAlloc(0x40,local_size); IF(EAX==NULL){ preerror("Compiler out of memory for local symbol linked list"); ExitProcess(e_outofmemory); } IF(locallist==NULL)locallist = newptr; ELSE{ EAX=locallist; EBX>>16; EAX=FILENAMESIZE*EBX+#modules; EBX=EAX; wsprintfA(#mapstr,"File:%s, line=%-d:\n%s\n",EBX, DSDWORD[ESI+recmodline]&0xFFFF,DSDWORD[ESI+recsrc]); fprint(mapfile,#mapstr); ESI=ptr; LocalFree(DSDWORD[ESI+recsrc]); // Освободим память DSDWORD[ESI+recsrc]=0; } } numberofids++; } ESI=ptr; DisplayTreeAll(DSDWORD[ESI+left]); } } // ---- Вывод списка глобальных констант DisplayTreeConstants(dword ptr) { IF( ptr != NULL ){ ESI=ptr; DisplayTreeConstants(DSDWORD[ESI+right]); ESI=ptr; EAX=DSDWORD[ESI+rectok]; IF(EAX == tk_number){ wsprintfA(#mapstr,"#define %10ld /* %8lX hex */ %s\n", DSDWORD[ESI+recnumber],DSDWORD[ESI+recnumber],DSDWORD[ESI+recid]); fprint(mapfile,#mapstr); numberofids++; } ESI=ptr; DisplayTreeConstants(DSDWORD[ESI+left]); } } // ---- Вычисление значения беззнаково константы dword DoConstDwordMath() dword value; { IF(tok == tk_minus){ NextTok(); IF(tok != tk_number){ numexpected(); return(0); } number = -number; } IF(tok != tk_number){ numexpected(); return(0); } value = number; while(tok2isopperand()){ NextTok(); IF(tok2!=tk_number)return(value); switch(tok){ case tk_minus: value -= number2; break; case tk_plus: value += number2; break; case tk_xor: value ^= number2; break; case tk_and: value &= number2; break; case tk_or: value |= number2; break; case tk_mod: value = value % number2; BREAK; case tk_div: value = value / number2; BREAK; case tk_mult: value = value * number2; BREAK; case tk_rr: value >>= number2; BREAK; case tk_ll: value <<= number2; BREAK; case tk_xorminus: value ^= -number2; BREAK; case tk_andminus: value &= -number2; BREAK; case tk_orminus: value |= -number2; BREAK; /* case(tok==tk_modminus) value %= -number2; case(tok==tk_divminus) value /= -number2; case(tok==tk_multminus) value *= -number2; */ case tk_rrminus: value >>= -number2; BREAK; case tk_llminus: value <<= -number2; BREAK; } NextTok(); } return(value); } // ---- Вычисление значения знаковой константы long DoConstMath() long value; { IF(tok == tk_minus){ NextTok(); IF(tok != tk_number){ numexpected(); return(0); } number = -number; } IF(tok != tk_number){ numexpected(); return(0); } value = number; while(tok2isopperand()){ NextTok(); IF(tok2 != tk_number) return(value); switch(tok){ case tk_minus: value -= number2; break; case tk_plus: value += number2; break; case tk_xor: value ^= number2; break; case tk_and: value &= number2; break; case tk_or: value |= number2; break; case tk_mod: value = value % number2; BREAK; case tk_div: value = value / number2; BREAK; case tk_mult: value = value * number2; BREAK; case tk_rr: value >>= number2; BREAK; case tk_ll: value <<= number2; BREAK; case tk_xorminus: value ^= -number2; BREAK; case tk_andminus: value &= -number2; BREAK; case tk_orminus: value |= -number2; BREAK; /* case(tok==tk_modminus) value %= -number2; case(tok==tk_divminus) value /= -number2; case(tok==tk_multminus) value *= -number2; */ case tk_rrminus: value >>= -number2; BREAK; case tk_llminus: value <<= -number2; BREAK; } NextTok(); } return(value); } // ---- Вычисление значения знаковой константы long DoConstLongMath() long value; { value=DoConstMath(); NextTok(); return(value); } // ---- Следующий token - операция? dword tok2isopperand() { EAX=tok2; IF(EAX==tk_plus)||(EAX==tk_minus)||(EAX==tk_mult)||(EAX==tk_div)||(EAX==tk_mod)|| (EAX==tk_rr)||(EAX==tk_ll)||(EAX==tk_or)||(EAX==tk_and)||(EAX==tk_xor)|| (EAX==tk_divminus)||(EAX==tk_modminus)||(EAX==tk_multminus)||(EAX==tk_xorminus)|| (EAX==tk_orminus)||(EAX==tk_andminus)||(EAX==tk_llminus)||(EAX==tk_rrminus)return(1); return(0); } // ---- Следующий token закрывает выражение? dword tok2notstopper () { EAX=tok2; IF(EAX==tk_semicolon)||(EAX==tk_comma)||(EAX==tk_closebracket)|| (EAX==tk_openblock)EAX=0; ELSE EAX=1; } // ---- Поиск в списке локальных переменных SearchLocals(dword tok4,type4,string4,number4) { if( locallist != NULL ){ localptr = locallist; S00: ESI=EAX; //localptr; lstrcmpA(string4,ESI+localid); ESI=localptr; IF(EAX==0){ // Переменная найдена EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+localnumber]; EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+localtype]; EBX=tok4; EAX=DSDWORD[ESI+localtok]; DSDWORD[EBX]=EAX; IF(EAX==tk_local){ EBX=number4; DSDWORD[EBX]-=localsize; } ELSE IF(EAX==tk_param){ EBX=number4; EAX=DSDWORD[EBX]+4; DSDWORD[EBX]=EAX; IF(current_proc_type==cpt_far)DSDWORD[EBX]+=4; // move over seg on stack } ELSE IF(EAX!=tk_locallabel)&&(EAX!=tk_number)internalerror("Bad *tok4 value in SearchLocals"); } ELSE{ IF(DSDWORD[ESI+localnext]!=NULL){ localptr=DSDWORD[ESI+localnext]; $JMP S00 } } } } // ---- Поиск в списке глобальных идентификаторов dword SearchTree(dword tok4,type4,src4,post4,string4,number4) dword ptr; long cmpresult; { cmpresult=123; ptr = treestart; // Поиск свободной ссылки for(;;){ ESI=EAX; IF(ESI==0){ treeptr=NULL; return(0); // Not found } cmpresult = lstrcmpA(DSDWORD[ESI+recid],string4); ESI=ptr; IF(cmpresult<0)ptr=DSDWORD[ESI+left]; ELSE IF(cmpresult>0)ptr=DSDWORD[ESI+right]; ELSE BREAK; } EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+recnumber]; EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+rectype]; EBX=src4; DSDWORD[EBX]=DSDWORD[ESI+recsrc]; EBX=post4; DSDWORD[EBX]=DSDWORD[ESI+recpost]; EBX=tok4; EAX=DSDWORD[ESI+rectok]; DSDWORD[EBX]=EAX; IF(EAX==tk_string ){ EBX=number4; ECX=DSDWORD[EBX]; EDI=string4; ESI=DSDWORD[ESI+newid]; $REP $MOVSB } ELSE{ IF(DSDWORD[ESI+newid])lstrcpyA(string4,DSDWORD[ESI+newid]); } ESI=ptr; IF(lstrcmpA(DSDWORD[ESI+recid],string4)!=0) // Проверим: менялось ли имя идентификатора SearchTree(tok4,type4,src4,post4,string4,number4); // Да - повторим поиск treeptr = ptr; return(1); } // ---- Поиск неоткомпилированных еще ссылок dword SeekToDo(dword ptr) { IF(ptr!=NULL){ ESI=ptr; IF(SeekToDo(DSDWORD[ESI+right]))RETURN(1); ESI=ptr; EAX=DSDWORD[ESI+recpost]; IF(EAX>1){ treeptr=ptr; ESI=ptr; number=DSDWORD[ESI+recnumber]; type=DSDWORD[ESI+rectype]; modline=DSDWORD[ESI+recmodline]; src=DSDWORD[ESI+recsrc]; post=DSDWORD[ESI+recpost]; tok=DSDWORD[ESI+rectok]; RETURN(1); } ESI=ptr; IF(SeekToDo(DSDWORD[ESI+left]))RETURN(1); } return(0); } // ---- Поиск незакрытых ссылок SeekUndefined(dword ptr) { IF( ptr != NULL ){ ESI=ptr; SeekUndefined(DSDWORD[ESI+right]); ESI=ptr; EAX=DSDWORD[ESI+rectok]; IF(EAX==tk_undefproc){ wsprintfA(#mapstr,"'%s' undefined\n",DSDWORD[ESI+recid]); IF( makemapfile )fprint(mapfile,#mapstr); WRITESTR(#mapstr); } ESI=ptr; SeekUndefined(DSDWORD[ESI+left]); } }