Subversion Repositories Kolibri OS

Rev

Rev 9706 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #define _TOKC_
  2.  
  3. #include <fcntl.h>       /* O_ constant definitions */
  4. #include <unistd.h>      
  5. #include "tok.h"
  6.  
  7. void GetFileTime(int fd,struct ftime *buf);
  8.  
  9. #define MAXIF 32
  10.  
  11. //idrec *crec=NULL;
  12.  
  13. char invaliddecrem[]="invalid token to be decremented";
  14. char mesLOOPNZ[]="LOOPNZ";
  15. char mesIF[]="IF";
  16. char mesELSE[]="ELSE";
  17. char mesWHILE[]="WHILE";
  18. char mesFOR[]="FOR";
  19. char mesRETURN[]="RETURN";
  20. int tok,tok2; /* token holders current, next */
  21. unsigned char string[STRLEN],string2[STRLEN+20],
  22.   string3[STRLEN];      //ñîäåðæèò íå ïðåîáðàçîâàííóþ ñòðîêó
  23. unsigned int posts=0;            /* number of post entrys */
  24. postinfo *postbuf;
  25. unsigned int maxposts=MAXPOSTS;
  26. unsigned int secondcallnum=1;  /* # of different second calls and labels */
  27. unsigned int externnum=0;
  28. unsigned long postsize=0;                        /* total size of all post vars */
  29. unsigned int poststrptr=0;      /* post string index in output */
  30. unsigned int outptrsize=MAXDATA;        //ðàçìåð âûõîäíîãî áóôåðà äëÿ êîäà
  31. unsigned int outdatasize=MAXDATA;       //ðàçìåð âûõîäíîãî áóôåðà äëÿ äàííûõ
  32. long runfilesize;
  33. int error=0;             /* current error number holder */
  34. unsigned char dos1=0,dos2=0;            /* DOS version required for program execution */
  35. unsigned char cpu=0;    /* CPU required, 2 for 80286, 3 for 80386, ... */
  36. unsigned int paramsize=0;  /* byte size of all procedure parameters */
  37. unsigned int localsize=0;  /* byte size of all procedure local variables */
  38. unsigned int procedure_start=0; /* address of start of procedure */
  39. unsigned int current_proc_type;  /* current procedure type */
  40. int returntype;                                  /* return type, (void, byte, word, ...) */
  41. unsigned char warning;
  42. /*+++++++++++++++++++++++ Óñòàíîâêè ïî óìîë÷àíèþ +++++++++++++++++++++++*/
  43. unsigned char am32 = FALSE;                   // ðåæèì 32 áèòíîé àäðåñàöèè
  44. unsigned char comfile = file_com;               // output file format
  45. unsigned char optimizespeed = 1;                        // optimize for size or speed flag
  46. unsigned char alignword = 1;                                    // flag whether or not to align words
  47. unsigned char aligner = 0;                                              // value used to align words
  48. unsigned char header = 1;                                               // output SPHINX C-- Ver1 Ver2 header
  49. unsigned char chip = 0;                                                         // CPU optimization (286,386,486,...)
  50. unsigned char killctrlc = 0;                                    // add disable CTRL-C code in header
  51. unsigned int    stacksize = 2048;                       // stack size (2048 default)
  52. unsigned char splitdata=FALSE;        //îòäåëèòü äàííûå îò êîäà
  53. unsigned char AlignCycle=FALSE;       //âûðàâíèâàòü íà÷àëà öèêëîâ
  54. /*+++++++++++++++++++ end of flexable compiler options ++++++++++++++++++++*/
  55. unsigned char notdoneprestuff = TRUE; // flag if initial stuff has been entered
  56. unsigned int datasize=0,alignersize=0;  /* size of data and other */
  57. unsigned int outptr=0x100,outptrdata=0x100;                     /* ptr to output */
  58. unsigned char *output;
  59. unsigned char *outputdata=NULL;
  60. unsigned int linenumber=0;
  61. unsigned char dynamic_flag=0;   //ôëàã îáðàáîòêè äèíàìè÷åñêèõ ýëåìåíòîâ
  62.  
  63. unsigned char *input;    /* dynamic input buffer */
  64. unsigned int endinptr;           /* end index of input array */
  65. unsigned int inptr;              /* index in input buffer */
  66. unsigned char cha;               /* pipe byte for token production */
  67. char endoffile;                  /* end of input file flag */
  68. unsigned char insertmode=FALSE;
  69. unsigned int numblocks=0;       //íîìåð âëîæåííîãî áëîêà
  70. treelocalrec *tlr=NULL; //öåïî÷êà ëîêàëüíûõ áëîêîâ
  71. treelocalrec *btlr=NULL;        //öåïî÷êà èñïîëüçîâàíûõ ëîêàëüíûõ áëîêîâ
  72. RETLIST *listreturn=NULL;
  73. unsigned int numreturn=0;
  74. idrec *staticlist;
  75. unsigned char stat_reg[8];      //òàáëèöà çàíÿòîñòè ðåãèñòðîâ
  76.  
  77. int sizestack=0;        //ðàçìåð íå êîìïåíñèðîâàííûõ ïàðàìåòðîâ ôóíêöèé
  78. unsigned char addstack=TRUE;
  79.  
  80. extern char shorterr[];
  81. extern unsigned long long li[];
  82.  
  83. /*-----------------01.05.98 19:22-------------------
  84.  äîïîëíèòåëüíûå ïåðåìåííûå äëÿ ðåàëèçàöèè BREAK CONTINUE
  85. --------------------------------------------------*/
  86. #define MAXIN 100       //ìàêñèìàëüíàÿ âëîæåíîñòü öèêëîâ
  87. unsigned int numbr=0;   //ñ÷åò÷èê îáùåãî ÷èñëà öèêëîâ LOOP DO-WHILE...
  88. unsigned int listbr[MAXIN];     //òàáëèöà íîìåðîâ öèêëîâ
  89. unsigned int usebr[MAXIN];      //èñïîëüçîâàíî break
  90. unsigned int useco[MAXIN];      //èñïîëüçîâàíî continue
  91. unsigned int curbr=0,curco=0;   //òåêóùàÿâëîæåíîñòü öèêëîâ
  92. unsigned int startStartup=0x100;
  93. unsigned int endStartup=0;
  94. unsigned char useStartup=FALSE;
  95. unsigned char notpost=FALSE;
  96. int retproc;
  97. int lastcommand;        //ïîñëåäíèé îïåðàòîð â áëîêå
  98. unsigned char FastCallApi=TRUE; //ðàçðåøèòü áûñòðûé âûçîâ API ïðîöåäóð
  99. unsigned char FixUp=FALSE;      //Äåëàòü ëè òàáëèöó ïåðåìåùåíèé
  100. unsigned char AlignProc=FALSE;
  101. //------- ðàáîòà ñ union ---------------------------------------------
  102. char param[256];        //áóôåð äëÿ ïàðàìåòðîâ ïðîöåäóðû
  103. char *BackTextBlock;    //áóôåð äëÿ ïåðåíåñåííîãî òåêñòà
  104. int SizeBackBuf=0,MaxSizeBackBuf;
  105. struct FILEINFO *startfileinfo=NULL;
  106. unsigned int totalmodule=0;
  107. unsigned int currentfileinfo;
  108. unsigned char setzeroflag;      //îïåðàöèÿ ìåíÿåò zero flag
  109. unsigned char notunreach=FALSE;
  110. unsigned int initBP=0;
  111. int inlineflag=0;  // flag for disabling entry and exit codes production
  112. unsigned char fstatic=FALSE;
  113.  
  114. unsigned long addESP=0; //äîáàâêà ñòåêà
  115. unsigned char blockproc=FALSE;  //èäåòðàçáîðêà áëîêà ôóíêöèè
  116.  
  117. unsigned int   updatelocalvar(char *str,int tok,unsigned int num);
  118. void setuprm();
  119. void doloop(unsigned int typeb);                                                         /* both short and long loops */
  120. void doBREAK(unsigned char typeb);
  121. void doCONTINUE(unsigned char typeb);
  122. void dowhile(unsigned int typeb);
  123. void MakeContinue(unsigned char typeb);
  124. void dofor(unsigned int typeb);
  125. void dodo();
  126. void globalvar();       /* both initialized and unitialized combined */
  127. void doswitch();
  128. void CalcRegPar(int reg,int def,char *&ofsstr);
  129. void JXorJMP();
  130. int loadinputfile(char *inpfile);
  131. int SaveStartUp(int size,char *var_name);
  132. void LoadData(unsigned int size,int filehandle);
  133. void SetNewTok(int type,int typev);
  134. void doreturn(int type=tokens);         /* do return(...); */
  135. void notnegit(int notneg);
  136. void insertcode();               // force code procedure at specified location
  137. void interruptproc();
  138. void dobigif();
  139. void doif(void);
  140. void doasmblock();
  141. void declareextern();
  142. unsigned long dounion(int,int);
  143. void RunBackText();
  144. int FindDublString(int segm,unsigned int len,int term);
  145. void *liststring=NULL;  //öåïî÷êà èíôîðìàöèîííûõ áëîêîâ î ñòðîêàõ
  146. void GetNameLabel(int type,int num);
  147. void CheckPosts();
  148. SAVEPAR *SRparam(int save,SAVEPAR *par);        //save or restore global param compiler
  149. void AddRetList(int pos,int line,int type);
  150. void CheckRealizable();
  151. void declare_procedure(int oflag,int orm,int npointr);
  152. void labelindata();
  153. void AddRegistr(int razr,int reg);
  154. void ClearRegister();
  155. int GetRegister(int mode=0);
  156. void RegAddNum(int reg);
  157. void dowhilefast(unsigned int typeb);
  158. int getrazr(int type);
  159. void RestoreSaveReg();
  160. void killlocals(/*int endp=TRUE*/);
  161. void leaveproc();
  162. int IsSaveReg();
  163. void CorrectParamVar();
  164.  
  165. extern void ManyLogicCompare();
  166. extern void maxdataerror();
  167. extern void CompareOr();
  168. extern void dynamiclabelerror();
  169. extern void retvoid();
  170. extern int numberbreak;
  171.  
  172. SAVEREG savereg;
  173. SAVEREG *psavereg=&savereg;
  174.  
  175. int loadfile(char *filename,int firstflag)
  176. {
  177.         int hold;
  178.         for(int i=0;i<=numfindpath;i++){
  179.                 char *path = findpath[(firstflag==0?i:numfindpath-i)]; // FIXME! (íóæíî âûÿñíèòü, ïî÷åìó path ìîæåò áûòü ðàâåí "\0")
  180.                 if(path && strlen(path)) {
  181.                         sprintf((char *)string2,"%s%s", path, filename);
  182.                 } else {
  183.                         strcpy((char *)string2, filename);
  184.                 }
  185. #ifndef _WIN32_
  186.                 for(char* p=(char *)string2; *p; ++p) if(*p=='\\') *p='/';
  187. #endif
  188.                 if((hold=loadinputfile((char *)string2))!=-2)break;
  189.                 if(firstflag==2||(firstflag==0&&(i+1)==numfindpath))break;
  190.         }
  191.         if(hold==-2){
  192.                 unableopenfile(filename); //ñîîáùåíèå î îøèáêå
  193.                 exit(e_cannotopeninput);        //çàâåðøèòü ðàáîòó åñëè íå ñìîãëè çàãðóçèòü ôàéë
  194.         }
  195.         return hold;
  196. }
  197.  
  198. void compilefile(char *filename,int firstflag)
  199. {
  200. int hold;
  201.  
  202.         hold=loadfile(filename,firstflag);
  203.         if(hold==1||hold==-1)return;
  204.         if(strcmp(filename,"startup.h--")==0)startupfile=currentfileinfo;
  205.  
  206.         inptr=0;
  207.         endoffile=0;
  208.         startline=(char*)input;
  209.         endinput=startline+endinptr;
  210.         warning=gwarning;
  211.         nextchar();
  212.         cha2=cha; //ñèìâîë èç áóôåðà
  213.         inptr2=inptr;   //çàïîìí óêàçàòåëü íà ñëåä ñèìâîë
  214.         linenum2=1;   //íîìåð ñòðîêè
  215.         {       //ïðîâåðêà íà ôàéë ðåñóðñîâ è åãî îáðàáîòêà
  216.                 char *a;
  217.                 if((a=strrchr(filename,'.'))!=NULL){
  218.                         if(stricmp(a,".rc")==0){
  219.                                 input_res();
  220.                                 free(input);
  221.                                 return;
  222.                         }
  223.                 }
  224.         }
  225.  
  226.         nexttok();    //îïð òèï ïåðâîãî è âòîðîãî òîêåíà
  227.         while(tok!=tk_eof){     //öèêë ïîêà íå êîí÷èòñÿ ôàéë
  228.                 while(tok==tk_question){
  229.                         directive();//îáðàáîòêà äèðåêòèâ
  230.                         if(tok==tk_semicolon)nexttok();
  231.                 }
  232.                 usedirectiv=FALSE;
  233.                 if(notdoneprestuff==TRUE)doprestuff();//startup
  234.                 switch(tok){
  235.                         case tk_ID:
  236.                         case tk_id:
  237.                                 if(FindTeg(TRUE)!=NULL){
  238.                                         InitStruct();
  239.                                         break;
  240.                                 }
  241.                                 if(tok2==tk_colon){
  242.                                         labelindata();
  243.                                         break;
  244.                                 }
  245.                         case tk_far:
  246.                         case tk_cdecl:
  247.                         case tk_pascal:
  248.                         case tk_stdcall:
  249.                         case tk_fastcall:
  250.                         case tk_declare:
  251.                         case tk_undefproc:
  252.                         case tk_float:
  253.                         case tk_long:
  254.                         case tk_dword:
  255.                         case tk_word:
  256.                         case tk_byte:
  257.                         case tk_char:
  258.                         case tk_int:
  259.                         case tk_void:
  260.                         case tk_export:
  261.                         case tk_qword:
  262.                         case tk_double:
  263.                         case tk_fpust:
  264.                                 if((hold=testInitVar())==FALSE)define_procedure();
  265.                                 else if(hold==TRUE)globalvar();
  266.                                 break;
  267.                         case tk_struct: InitStruct(); break;
  268.                         case tk_interrupt: interruptproc(); break;
  269.                         case tk_at: insertcode(); break;        //âñòàâêà ðåãèñòðîâîé ïðîöåäóðû
  270.                         case tk_colon:
  271.                                 nexttok();
  272.                                 dynamic_flag=2;
  273.                                 break;// îïð äèíàìè÷åñêîé  ïðîöåäóðû
  274.                         case tk_inline:
  275.                                 if(testInitVar()){
  276.                                         preerror("Bad header dynamic function");
  277.                                         nexttok();
  278.                                 }
  279.                                 dynamic_proc();
  280.                                 break;
  281.                         case tk_static:
  282.                                 fstatic=2;
  283.                                 nexttok();
  284.                                 break;
  285.                         case tk_enum: doenum(); break;
  286.                         case tk_from: nexttok(); dofrom(); nextseminext(); break;
  287.                         case tk_extract: nexttok(); doextract(); seminext(); break;
  288.                         case tk_loop:
  289.                         case tk_while:
  290.                         case tk_do:
  291.                         case tk_else:
  292.                         case tk_ELSE:
  293.                         case tk_if:
  294.                         case tk_IF:
  295.                         case tk_interruptproc:
  296.                         case tk_proc:
  297.                         case tk_charvar:
  298.                         case tk_intvar:
  299.                         case tk_bytevar:
  300.                         case tk_longvar:
  301.                         case tk_dwordvar:
  302.                         case tk_floatvar:
  303.                         case tk_qwordvar:
  304.                         case tk_doublevar:
  305.                         case tk_wordvar: idalreadydefined(); break;
  306.                         case tk_reg32:
  307.                         case tk_debugreg:
  308.                         case tk_controlreg:
  309.                         case tk_testreg:
  310.                         case tk_reg:
  311.                         case tk_seg:
  312.                         case tk_beg:
  313.                         case tk_reg64:
  314.                                 preerror("register name cannot be used as an identifier");
  315.                                 nexttok();
  316.                         case tk_eof: break;
  317.                         case tk_locallabel: internalerror("local label token found outside function block."); break;
  318.                         case tk_extern: declareextern(); break;
  319.                         case tk_union: dynamic_flag=0; dounion(TRUE,fstatic==0?0:f_static); break;
  320.                         case tk_semicolon: nexttok(); break;
  321.                         case tk_asm:
  322.                                 if(tok2==tk_openbrace)doasmblock();
  323.                                 else doasm();
  324.                                 break;
  325.                         case tk_idasm: doasm(TRUE); break;
  326.                         case tk_dollar: doasm(FALSE); break;
  327.                         default: unuseableinput();
  328. /*                              while(itok.type==tp_stopper&&tok!=tk_eof)*/nexttok();
  329.                                 break;
  330.                 }
  331.                 if(fstatic)fstatic--;
  332.                 else if(dynamic_flag)dynamic_flag--;
  333.         }
  334.         (startfileinfo+currentfileinfo)->stlist=staticlist;
  335.         free(input);
  336. }
  337.  
  338. /* ------------------- output procedures start ------------------- */
  339. int CheckCodeSize()
  340. //ïðîâåðêà ðàçìåðà áóôåðà äëÿ êîäà
  341. {
  342.         if(!am32){
  343.                 maxoutputerror();
  344.                 return FALSE;
  345.         }
  346.         outptrsize+=MAXDATA;
  347.         output=(unsigned char *)REALLOC(output,outptrsize);
  348.         if(splitdata==FALSE)outputdata=output;
  349.         return TRUE;
  350. }
  351.  
  352. int CheckDataSize()
  353. //ïðîâåðêà ðàçìåðà áóôåðà äëÿ êîäà
  354. {
  355.         if(!am32){
  356.                 maxoutputerror();
  357.                 return FALSE;
  358.         }
  359.         outdatasize+=MAXDATA;
  360.         outputdata=(unsigned char *)REALLOC(outputdata,outdatasize);
  361.         return TRUE;
  362. }
  363.  
  364. void  op(int byte)
  365. {
  366.         if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return;
  367.         output[outptr++]=(unsigned char)byte;
  368.         if(splitdata==FALSE)outptrdata=outptr;
  369.         retproc=FALSE;
  370. }
  371.  
  372. void  opd(int byte)
  373. {
  374.         if(splitdata==FALSE){
  375.                 if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return;
  376.                 output[outptr++]=(unsigned char)byte;
  377.                 outptrdata=outptr;
  378.         }
  379.         else{
  380.                 if(outptrdata>=outdatasize&&CheckDataSize()==FALSE)return;
  381.                 outputdata[outptrdata++]=(unsigned char)byte;
  382.         }
  383. }
  384.  
  385. void CorrectOfsBit(int bitofs)
  386. {
  387.         bitofs=(bitofs+7)/8;
  388.         if(splitdata)outptrdata+=bitofs;
  389.         else{
  390.                 outptr+=bitofs;
  391.                 outptrdata=outptr;
  392.         }
  393. }
  394.  
  395. long GetBitMask(int ofs,int size)
  396. {
  397.         return (~((li[size]-1)<<ofs));
  398. }
  399.  
  400. void opb(unsigned long num,unsigned int ofs,unsigned int size)
  401. {
  402. int s;
  403. //ïðîâåðèòü âûõîä çà ãðàíèöû áëîêà ïàìÿòè
  404.         s=(ofs+size+7)/8;
  405.         if(splitdata==FALSE){
  406.                 if((outptr+s+8)>=outptrsize&&CheckCodeSize()==FALSE)return;
  407.         }
  408.         else{
  409.                 if((outptrdata+s+8)>=outdatasize&&CheckDataSize()==FALSE)return;
  410.         }
  411.         if(size!=32)num=num&(li[size]-1);
  412.         s=outptrdata+ofs/8;
  413.         ofs=ofs%8;
  414.         *(long *)&outputdata[s]&=GetBitMask(ofs,size);
  415.         *(long *)&outputdata[s]|=(num<<ofs);
  416. //      printf("ofs=%Xh mask=%X value=%X\n",s,GetBitMask(ofs,size),(num<<ofs));
  417.         if((ofs+size)>32){
  418.                 *(long *)&outputdata[s+4]&=GetBitMask(0,ofs+size-32);
  419.                 *(long *)&outputdata[s+4]|=(num>>(64-ofs-size));
  420. //              printf("continue ofs=%Xh mask=%X value=%X\n",s+4,GetBitMask(0,ofs+size-32),num>>(64-ofs-size));
  421.         }
  422. }
  423.  
  424. void  outword(unsigned int num)
  425. {
  426.         op(num);
  427.         op(num/256);
  428. }
  429.  
  430. void  outwordd(unsigned int num)
  431. {
  432.         opd(num);
  433.         opd(num/256);
  434. }
  435.  
  436. void  outdword(unsigned long num)
  437. {
  438.         outword((unsigned int)(num&0xFFFFL));
  439.         outword((unsigned int)(num/0x10000L));
  440. }
  441.  
  442. void  outdwordd(unsigned long num)
  443. {
  444.         outwordd((unsigned int)(num&0xFFFFL));
  445.         outwordd((unsigned int)(num/0x10000L));
  446. }
  447.  
  448. void  outqword(unsigned long long num)
  449. {
  450.         outdword((unsigned long)(num&0xFFFFFFFFL));
  451.         outdword((unsigned long)(num/0x100000000LL));
  452. }
  453.  
  454. void  outqwordd(unsigned long long num)
  455. {
  456.         outdwordd((unsigned long)(num&0xFFFFFFFFL));
  457.         outdwordd((unsigned long)(num/0x100000000LL));
  458. }
  459.  
  460. void  doasmblock()
  461. {
  462.         nexttok();
  463.         useasm=TRUE;
  464.         expecting(tk_openbrace);
  465.         for(;;){
  466.                 if(tok==tk_closebrace)break;
  467.                 if(tok==tk_eof){
  468.                         unexpectedeof();
  469.                         break;
  470.                 }
  471.                 lastcommand=tok;
  472.                 if(dbg)AddLine();
  473.                 doasm(TRUE);
  474.         }
  475.         useasm=FALSE;
  476.         nexttok();
  477. }
  478.  
  479. void doblock()
  480. {
  481.         expecting(tk_openbrace);
  482.         doblock2();
  483. /*      for(;;){
  484.                 if(tok==tk_closebrace)break;
  485.                 if(tok==tk_eof){
  486.                         unexpectedeof();
  487.                         break;
  488.                 }
  489.                 docommand();
  490.         }
  491.         RestoreStack();*/
  492. }
  493.  
  494. void doblock2()
  495. {
  496.         for(;;){
  497.                 if(tok==tk_closebrace)break;
  498.                 if(tok==tk_eof){
  499.                         unexpectedeof();
  500.                         break;
  501.                 }
  502.                 docommand();
  503.         }
  504.         if(numblocks==1&&addstack&&sizestack&&localsize&&am32&&ESPloc&&IsSaveReg()==FALSE){
  505.                 localsize+=sizestack;
  506.                 sizestack=0;
  507.         }
  508.         else RestoreStack();
  509. }
  510.  
  511. void gotodo()
  512. {
  513.         nexttok();
  514.         if(gotol(0))nexttok();
  515.         seminext();
  516. }
  517.  
  518. void GOTOdo()
  519. {
  520.         nexttok();
  521.         if(GOTO())nexttok();
  522.         seminext();
  523. }
  524.  
  525. void docommand()                 /* do a single command */
  526. {
  527. unsigned int useflag;
  528.         useflag=0;
  529.         if(dbg)AddLine();
  530. //loops:
  531.         lastcommand=tok;
  532. //      printf("tok=%d %s\n",tok,itok.name);
  533.         switch(tok){
  534.                 case tk_ID: useflag++;
  535.                 case tk_id:
  536.                         if((useflag=doid((char)useflag,tk_void))!=tokens){
  537.                                 nextseminext();
  538.                                 if(useflag==tk_fpust)preerror("function returned parametr in FPU stack");
  539.                         }
  540.                         else if(tok!=tk_closebrace)docommand();
  541.                         break;
  542.                 case tk_apiproc:
  543.                 case tk_undefproc:
  544.                 case tk_declare:
  545.                         if(doanyundefproc()!=tokens)nextseminext();
  546.                         else if(tok!=tk_closebrace)docommand();
  547.                         break;
  548.                 case tk_proc:
  549.                         doanyproc();
  550.                         nextseminext();
  551.                         break;
  552.                 case tk_interruptproc:
  553.                         outword(0x0E9C);        //pushf //push cs
  554.                         useflag=itok.post;
  555.                         callloc(itok.number);
  556.                         nexttok();
  557.                         expecting(tk_openbracket);
  558.                         expecting(tk_closebracket);
  559. #ifdef OPTVARCONST
  560.                         FreeGlobalConst();
  561. #endif
  562.                         seminext();
  563.                         clearregstat(useflag);
  564.                         break;
  565.                 case tk_bits:
  566.                         dobits();
  567.                         break;
  568.                 case tk_charvar: useflag=1;
  569.                 case tk_bytevar:
  570.                         dobytevar(useflag);
  571.                         break;
  572.                 case tk_intvar: useflag=1;
  573.                 case tk_wordvar:
  574.                         do_d_wordvar(useflag,r16);
  575.                         break;
  576.                 case tk_longvar: useflag=1;
  577.                 case tk_dwordvar:
  578.                         do_d_wordvar(useflag,r32);
  579.                         break;
  580.                 case tk_doublevar:
  581.                         useflag=4;
  582.                 case tk_floatvar:
  583.                         dofloatvar(useflag,tk_floatvar,tk_semicolon);
  584.                         break;
  585.                 case tk_qwordvar:
  586.                         doqwordvar();
  587.                         break;
  588.                 case tk_fpust:
  589.                         dofloatstack(itok.number);
  590.                         break;
  591.                 case tk_structvar:
  592.                         dostruct();
  593.                         break;
  594.                 case tk_pointer:
  595.                         dopointer();
  596.                         break;
  597.                 case tk_mult:
  598.                         dovalpointer();
  599.                         break;
  600.                 case tk_RETURN:
  601.                 case tk_return:
  602.                         RestoreStack();
  603. #ifdef OPTVARCONST
  604.                         ClearLVIC();
  605. #endif
  606.                         doreturn(tok);
  607.                         CheckRealizable();
  608.                         break;
  609.                 case tk_at:
  610.                         nexttok();
  611.                         if(tok2==tk_colon){
  612.                                 LLabel();
  613.                                 if(tok!=tk_closebrace)docommand();
  614.                         }
  615.                         else if(macros(tk_void)!=0)nextseminext();
  616.                         break;
  617.                 case tk_if: RestoreStack(); doif();     break;
  618.                 case tk_IF: RestoreStack(); dobigif(); break;
  619.                 case tk_loopnz:
  620.                 case tk_LOOPNZ:
  621.                 case tk_loop: RestoreStack(); doloop(tok);      break;
  622.                 case tk_while:
  623.                 case tk_WHILE: RestoreStack(); dowhilefast(tok); break;
  624.                 case tk_do: RestoreStack(); dodo();     break;
  625.                 case tk_for:
  626.                 case tk_FOR: RestoreStack(); dofor(tok); break;
  627.                 case tk_reg32: doreg_32((unsigned int)itok.number,r32); break;
  628.                 case tk_reg: doreg_32((unsigned int)itok.number,r16); break;
  629.                 case tk_beg: dobeg((unsigned int)itok.number); break;
  630.                 case tk_reg64: doreg64(itok.number); break;
  631.                 case tk_seg: doseg((unsigned int)itok.number); break;
  632.                 case tk_openbrace:
  633.                         startblock();
  634.                         doblock();
  635.                         nexttok();
  636.                         endblock();
  637.                         break;
  638.                 case tk_from: nexttok(); dofrom(); nextseminext();      break;
  639.                 case tk_extract: nexttok(); doextract(); seminext(); break;
  640.                 case tk_minus: useflag=8;
  641.                 case tk_not:
  642.                         notnegit(useflag);
  643.                         nextseminext();
  644.                         break;
  645.                 case tk_locallabel: RestoreStack(); define_locallabel(); break;
  646.                 case tk_camma:
  647.                 case tk_semicolon: nexttok();   break;
  648.                 case tk_else:
  649.                         preerror("else without preceeding if or IF");
  650.                         nexttok();
  651.                         break;
  652.                 case tk_ELSE:
  653.                         preerror("ELSE without preceeding IF or if");
  654.                         nexttok();
  655.                         break;
  656.                 case tk_eof: unexpectedeof(); break;
  657.                 case tk_void:
  658.                 case tk_long:
  659.                 case tk_dword:
  660.                 case tk_word:
  661.                 case tk_byte:
  662.                 case tk_int:
  663.                 case tk_char:
  664.                         preerror("cannot declare variables within function { } block");
  665.                         nexttok();
  666.                         break;
  667.                 case tk_GOTO:
  668.                         RestoreStack();
  669.                         GOTOdo();
  670.                         CheckRealizable();
  671.                         break;
  672.                 case tk_goto:
  673.                         RestoreStack();
  674.                         gotodo();
  675.                         CheckRealizable();
  676.                         break;
  677.                 case tk_BREAK:
  678.                         RestoreStack();
  679.                         doBREAK(BREAK_SHORT);
  680.                         CheckRealizable();
  681.                         break;
  682.                 case tk_break:
  683.                         RestoreStack();
  684.                         doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32));
  685.                         CheckRealizable();
  686.                         break;
  687.                 case tk_CONTINUE:
  688.                         RestoreStack();
  689.                         doCONTINUE(CONTINUE_SHORT);
  690.                         CheckRealizable();
  691.                         break;
  692.                 case tk_continue:
  693.                         RestoreStack();
  694.                         doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32));
  695.                         CheckRealizable();
  696.                         break;
  697.                 case tk_asm:
  698.                         if(tok2==tk_openbrace)doasmblock();
  699.                         else doasm();
  700.                         break;
  701.                 case tk_idasm:
  702.                         useflag=TRUE;
  703.                 case tk_dollar:
  704.                         doasm(useflag);
  705.                         break;
  706.                 case tk_SWITCH:
  707.                 case tk_switch: RestoreStack(); doswitch(); break;
  708.                 case tk_delete: dodelete(); break;
  709.                 case tk_new: donew(); seminext(); break;
  710.                 case tk_question:
  711. //                      calcnumber=FALSE;
  712.                         while(tok==tk_question)directive();
  713.                         break;
  714. /*              case tk_openbracket:
  715.                         nexttok();
  716.                         nexttok();
  717.                         expectingoperand(tk_closebracket);
  718.                         goto loops;*/
  719.                 default: unuseableinput(); break;
  720.         }
  721.         notunreach=FALSE;
  722. }
  723.  
  724. void doBREAK(unsigned char typeb)
  725. {
  726.         if(curbr==0)preerror("'BREAK' or 'break' use only in loop, do-while..");
  727.         else MakeBreak(typeb);
  728.         nextseminext();
  729. }
  730.  
  731. void doCONTINUE(unsigned char typeb)
  732. {
  733.         if(curco==0)preerror("'CONTINUE' or 'continue' use only in loop, do-while..");
  734.         else MakeContinue(typeb);
  735.         nextseminext();
  736. }
  737.  
  738. void MakeBreak(unsigned char typeb)
  739. {
  740. unsigned int nbr=0;
  741.         if(tok2==tk_number){
  742.                 nexttok();
  743.                 nbr=itok.number;
  744.                 if(nbr>=curbr)preerror("'BREAK' or 'break' on incorrect number skip cycle");
  745.         }
  746.         numberbreak=nbr;
  747.         nbr=curbr-1-nbr;
  748.         if(usebr[nbr]==0){
  749.                 GetNameLabel(tk_break,nbr);
  750.                 addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE);
  751.                 usebr[nbr]=secondcallnum;
  752.                 secondcallnum++;
  753.         }
  754.         addacall(usebr[nbr],typeb);
  755.         if(typeb==BREAK_SHORT)outword(0x00EB);  // JMP SHORT
  756.         else jumploc0();
  757. }
  758.  
  759. void MakeContinue(unsigned char typeb)
  760. {
  761. unsigned int nbr=0;
  762.         if(tok2==tk_number){
  763.                 nexttok();
  764.                 nbr=itok.number;
  765.                 if(nbr>=curco)preerror("'CONTINUE' or 'continue' on incorrect number skip cycle");
  766.         }
  767.         nbr=curco-1-nbr;
  768.         if(useco[nbr]==0){
  769.                 GetNameLabel(tk_continue,nbr);
  770. //              printf("%s nbr=%d\n",(char *)string2,nbr);
  771.                 addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE);
  772.                 useco[nbr]=secondcallnum;
  773.                 secondcallnum++;
  774.         }
  775.         addacall(useco[nbr],typeb);
  776.         if(typeb==CONTINUE_SHORT)outword(0x00EB);       // JMP SHORT
  777.         else jumploc0();
  778. }
  779.  
  780. int CheckExitProc()
  781. {
  782.         if(strcmp(itok.name,"EXIT")==0||strcmp(itok.name,"ABORT")==0)return TRUE;
  783.         return FALSE;
  784. }
  785.  
  786. void LLabel()
  787. {
  788. localrec *ptr;
  789. #ifdef OPTVARCONST
  790.         ClearLVIC();
  791. #endif
  792.         RestoreStack();
  793.         clearregstat();
  794.         switch(tok){
  795.                 case tk_id:
  796.                 case tk_ID:
  797.                         FindOff((unsigned char *)itok.name,CS);
  798.                         ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
  799.                         if(FixUp)ptr->rec.flag=f_reloc;
  800.                         break;
  801.                 case tk_undefproc:
  802.                         ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);//äîáàâèòü â ëîêàëüíûé ñïèñîê
  803.                         if(FixUp)ptr->rec.flag=f_reloc;
  804.                         updatecall((unsigned int)itok.number,outptr,procedure_start);//îáðàáîòàòü ðàííèå îáðàùåíèÿ
  805.                         break;
  806.                 default:
  807.                         preerror("error declaretion local label");
  808.                         break;
  809.         }
  810.         nexttok();
  811.         nexttok();
  812. }
  813.  
  814. void AddApiToPost(unsigned int num)
  815. {
  816.         CheckPosts();
  817.         (postbuf+posts)->type=CALL_32I;
  818.         (postbuf+posts)->loc=outptr;
  819.         (postbuf+posts)->num=num;
  820.         posts++;
  821.         outdword(0);
  822. }
  823.  
  824. /* ---------------------- Procedure Calling Starts -------------------- */
  825.  
  826. int doanyundefproc(int jumpsend)
  827. {
  828. unsigned int cnum,snum;
  829. int returnvalue;
  830. int regs;
  831. char fname[IDLENGTH];
  832.         if(tok2==tk_colon){     // if a label
  833. #ifdef OPTVARCONST
  834.                 ClearLVIC();
  835. #endif
  836.                 RestoreStack();
  837.                 clearregstat();
  838.                 if(CidOrID()==tk_ID){//local label that has been used, but not placed
  839.                         localrec *ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
  840.                         if(FixUp)ptr->rec.flag=f_reloc;
  841.                         updatecall((unsigned int)itok.number,outptr,procedure_start);//îáðàáîòàòü ðàííèå îáðàùåíèÿ
  842.                 }
  843.                 else{   //ãëîáàëüíàÿ ìåòêà
  844.                         tok=tk_proc;
  845.                         itok.number=outptr;
  846.                         string[0]=0;
  847.                         updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0);
  848.                 }
  849.                 nexttok();      // move past id
  850.                 nexttok();      // move past :
  851.                 return(tokens);
  852.         }
  853.         if(tok2==tk_openbracket){
  854.                 strcpy(fname,itok.name);
  855.                 if(tok==tk_declare){    //ñìåíèòü ñòàòóñ ïðîöåäóðû ñ îáúÿâëåíîé íà íåèçâåñòíóþ
  856.                         tok=tk_undefproc;
  857.                         updatetree();
  858.                         if(itok.flag&f_classproc)AddUndefClassProc();
  859.                 }
  860.                 cnum=(unsigned int)itok.number;
  861.                 regs=itok.post;
  862.                 returnvalue=itok.rm;
  863.                 unsigned int tproc=itok.flag;
  864.                 unsigned char apiproc=FALSE;
  865.                 unsigned int oaddESP=addESP;
  866.                 int sizestack=-1;
  867.                 if(tok==tk_apiproc){
  868.                         apiproc=TRUE;
  869.                         sizestack=itok.size;    //ðàçìåð ñòåêà ïîä ïàðàìåòðû
  870.                 }
  871. #ifdef OPTVARCONST
  872.                 if(tproc&f_useidx)ClearLVIC();
  873.                 else FreeGlobalConst();
  874. #endif
  875.                 int exitproc=CheckExitProc();
  876.                 snum=initparamproc();
  877.                 if(sizestack!=-1){
  878.                         if(snum>(unsigned int)sizestack)extraparam(fname);
  879.                         else if(snum<(unsigned int)sizestack)missingpar(fname);
  880.                 }
  881.                 if((tproc&f_typeproc)!=tp_cdecl){
  882.                         snum=0;
  883.                         addESP=oaddESP;
  884.                 }
  885.                 if(FastCallApi==TRUE&&apiproc!=FALSE){
  886.                         if(jumpsend)outword(0x25ff);
  887.                         else outword(0x15FF);
  888.                         AddApiToPost(cnum);
  889.                 }
  890.                 else{
  891.                         addacall(cnum,(unsigned char)((tproc&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR)));
  892.                         if(jumpsend)jumploc0();
  893.                         else callloc0();                /* produce CALL [#] */
  894.                 }
  895.                 clearregstat(regs);
  896.                 if(snum!=0&&jumpsend==FALSE)CorrectStack(snum);
  897.                 retproc=exitproc;
  898.                 return(returnvalue);
  899.         }
  900.         thisundefined(itok.name);
  901.         nexttok();
  902.         return(tk_long);
  903. }
  904.  
  905. void CorrectStack(unsigned int num)
  906. {
  907.         if(addstack){
  908.                 sizestack+=num;
  909. //              printf("%s(%d)> Add %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,num);
  910.         }
  911.         else{
  912.                 if(short_ok(num)){
  913.                         outword(0xC483);
  914.                         op(num);
  915.                 }
  916.                 else{
  917.                         outword(0xC481);
  918.                         if(am32==FALSE)outword(num);
  919.                         else outdword(num);
  920.                 }
  921.                 addESP-=num;
  922.         }
  923. }
  924.  
  925. unsigned int initparamproc()
  926. {
  927. unsigned int typep=itok.flag,snum=0;
  928. ITOK ostructadr=structadr;
  929.         strcpy(param,(char *)string);
  930.         nexttok();
  931.         switch(typep&f_typeproc){
  932.                 case tp_cdecl:
  933.                 case tp_stdcall:
  934.                         snum=swapparam();
  935.                         break;
  936.                 case tp_pascal:
  937.                         doparams();
  938.                         break;
  939.                 case tp_fastcall:
  940.                         doregparams();
  941.                         break;
  942.         }
  943. //      if(crec)printf("after doparams num=%08X\n",crec->recnumber);
  944.         if((typep&f_classproc)&&(!(typep&f_static))){
  945.                 if((current_proc_type&f_static)&&structadr.sib==THIS_PARAM                            )return snum;
  946.                 structadr=ostructadr;
  947.                 if(structadr.sib==THIS_PARAM){
  948.                         if(structadr.number==0){
  949.                                 op(0xff);
  950.                                 if(ESPloc&&am32){
  951.                                         int num;
  952.                                         num=localsize+addESP+4;
  953.                                         if(short_ok(num,TRUE)){
  954.                                                 outword(0x2474);
  955.                                                 op(num);
  956.                                         }
  957.                                         else{
  958.                                                 outword(0x24B4);
  959.                                                 outdword(num);
  960.                                         }
  961.                                 }
  962.                                 else outword(am32==FALSE?0x0476:0x0875);//push[ebp+4]
  963.                         }
  964.                         else{
  965.                                 int reg=GetRegister(1);
  966.                                 op(0x8B);
  967.                                 if(ESPloc&&am32){
  968.                                         int num;
  969.                                         num=localsize+addESP+4;
  970.                                         if(short_ok(num,TRUE)){
  971.                                                 op(4+reg*8+64);
  972.                                                 op(0x24);
  973.                                                 op(num);
  974.                                         }
  975.                                         else{
  976.                                                 op(4+reg*8+128);
  977.                                                 op(0x24);
  978.                                                 outdword(num);
  979.                                         }
  980.                                 }
  981.                                 else{
  982.                                         op((am32==FALSE?6:5)+reg*8+64);
  983.                                         op((am32==FALSE?4:8));//mov ESI,[ebp+4]
  984.                                 }
  985.                                 RegAddNum(reg);
  986.                                 op(0x50+reg);   //push reg
  987.                                 warningreg(regs[am32][reg]);
  988.                         }
  989.                 }
  990.                 else if(structadr.sib==THIS_REG){
  991.                         if(structadr.number/*size*/!=0){
  992.                                 int reg=GetRegister(1);
  993.                                 if(reg==structadr.rm)RegAddNum(reg);
  994.                                 else{
  995.                                         if(am32==FALSE){
  996.                                                 switch(structadr.rm){
  997.                                                         case BX:
  998.                                                                 structadr.rm=7;
  999.                                                                 break;
  1000.                                                         case DI:
  1001.                                                                 structadr.rm=5;
  1002.                                                                 break;
  1003.                                                         case SI:
  1004.                                                                 structadr.rm=4;
  1005.                                                                 break;
  1006.                                                         case BP:
  1007.                                                                 structadr.rm=6;
  1008.                                                                 break;
  1009.                                                         default:
  1010.                                                                 regBXDISIBPexpected();
  1011.                                                 }
  1012.                                                 structadr.sib=CODE16;
  1013.                                         }
  1014.                                         else structadr.sib=CODE32;
  1015.                                         structadr.rm|=(structadr.number<128?rm_mod01:rm_mod10);
  1016.                                         op(0x8d);       //lea reg [reg2+num]
  1017.                                         op(structadr.rm+reg*8);
  1018.                                         outaddress(&structadr);
  1019.                                 }
  1020.                                 op(0x50+reg);
  1021.                                 warningreg(regs[am32][reg]);
  1022.                         }
  1023.                         else op(0x50+structadr.rm);
  1024.                 }
  1025.                 else if(structadr.sib==THIS_NEW){
  1026.                         RunNew(structadr.number);
  1027.                         op(0x50);
  1028.                 }
  1029.                 else if(structadr.sib==THIS_ZEROSIZE){
  1030.                         outword(0x6a);  //push 0
  1031.                 }
  1032.                 else{
  1033. //                      printf("post=%d\n",structadr.post);
  1034.                         if(structadr.post==LOCAL){
  1035.                                 int reg=GetRegister(1);
  1036.                                 structadr.post=0;
  1037.                                 outseg(&structadr,2);
  1038.                                 op(0x8d);
  1039.                                 op(structadr.rm+reg*8);
  1040.                                 outaddress(&structadr);
  1041.                                 op(0x50+reg);
  1042.                                 warningreg(regs[am32][reg]);
  1043.                         }
  1044.                         else{
  1045.                                 if(strinf.bufstr){
  1046.                                         int reg=GetRegister(1);
  1047.                                         int newreg;
  1048.                                         if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,reg))!=NOINREG){
  1049.                                                 if(newreg!=SKIPREG){
  1050.                                                         if(am32==FALSE&&newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt;
  1051.                                                         waralreadinitreg(regs[am32][reg],regs[am32][newreg]);
  1052.                                                         reg=newreg;
  1053.                                                 }
  1054.                                                 free(strinf.bufstr);
  1055.                                                 goto cont1;
  1056.                                         }
  1057. noopt:
  1058.                                         if(newreg=CheckMassiv(strinf.bufstr,strinf.size,reg)!=-1)reg=newreg;
  1059. cont1:
  1060.                                         strinf.bufstr=NULL;
  1061.                                         RegAddNum(reg);
  1062.                                         op(0x50+reg);
  1063.                                 }
  1064.                                 else{
  1065.                                         op(0x68);
  1066.                                         if(structadr.post/*&&structadr.post!=USED_DIN_VAR*/)setwordpost(&structadr);
  1067.                                         else if(FixUp)AddReloc();
  1068.                                         if(am32==FALSE)outword((unsigned int)structadr.number);
  1069.                                         else outdword(structadr.number);
  1070.                                 }
  1071.                         }
  1072.                 }
  1073.                 snum+=(am32==FALSE?2:4);
  1074.                 addESP+=(am32==FALSE?2:4);
  1075.         }
  1076.         if(typep&f_far)op(0x0e);        //push cs
  1077.         return snum;
  1078. }
  1079.  
  1080. int doanyproc(int jumpsend)
  1081. {
  1082. unsigned int cloc,snum;
  1083. int returnvalue,dynamicindex;
  1084. int regs;
  1085.         if(tok2==tk_colon){
  1086.                 preerror("dublication global label");
  1087.                 nexttok();
  1088.                 return 0;
  1089.         }
  1090.         cloc=(unsigned int)itok.number;  /* get address or handle */
  1091.         returnvalue=itok.rm;
  1092.         regs=itok.post;
  1093. //      printf("regs=%08X name=%s\n",regs,itok.name);
  1094.         int flag=itok.flag;
  1095.         if(itok.npointr)dopointerproc();
  1096.         else{
  1097.                 if((itok.flag&f_inline)!=0&&(useinline==TRUE||(useinline==2&&optimizespeed))){
  1098.                         if(macros(tk_void)!=0)return(returnvalue);
  1099.                 }
  1100.                 dynamicindex=itok.segm;
  1101.  
  1102. //      printf("%s %08X seg=%d\n",rec->recid/*itok.name*/,itok.flag,itok.segm);
  1103.                 if(itok.segm==DYNAMIC){
  1104.                         itok.segm=DYNAMIC_USED;
  1105.                         updatetree();
  1106.                 }
  1107.                 unsigned int oaddESP=addESP;
  1108.                 snum=initparamproc();
  1109.                 if((flag&f_typeproc)!=tp_cdecl){
  1110.                         snum=0;
  1111.                         addESP=oaddESP;
  1112.                 }
  1113.                 if(dynamicindex<NOT_DYNAMIC){   //äèíàìè÷åñêàÿ ïðîöåäóðà
  1114.                         addacall(cloc,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));
  1115.                         if(jumpsend)jumploc0();
  1116.                         else{
  1117.                                 callloc0();
  1118.                                 if(snum!=0)CorrectStack(snum);
  1119.                         }
  1120.                 }
  1121.                 else{
  1122.                         if(jumpsend)jumploc(cloc);
  1123.                         else{
  1124.                                 callloc(cloc);
  1125.                                 if(snum!=0)CorrectStack(snum);
  1126.                         }
  1127.                 }
  1128.         }
  1129. #ifdef OPTVARCONST
  1130.         if(flag&f_useidx)ClearLVIC();
  1131.         else FreeGlobalConst();
  1132. #endif
  1133.         clearregstat(regs);
  1134.         return(returnvalue);
  1135. }
  1136.  
  1137. int  doid(char uppercase,int expectedreturn)
  1138. {
  1139. int cnum;
  1140.         if(tok2==tk_colon){     // if a label
  1141. #ifdef OPTVARCONST
  1142.                 ClearLVIC();
  1143. #endif
  1144.                 RestoreStack();
  1145.                 clearregstat();
  1146.                 cnum=FindOff((unsigned char *)itok.name,CS);
  1147.                 if(uppercase){
  1148.                         localrec *ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
  1149.                         if(FixUp)ptr->rec.flag=f_reloc;
  1150.                 }
  1151.                 else{
  1152.                         tok=tk_proc;
  1153.                         itok.rm=tk_void;
  1154.                         itok.number=outptr;
  1155.                         itok.segm=NOT_DYNAMIC;
  1156.                         itok.flag=0;
  1157.                         string[0]=0;
  1158.                         itok.type=tp_ucnovn;
  1159.                         addtotree(itok.name);
  1160.                         itok.rec->count=cnum;
  1161.                 }
  1162.                 nexttok();      // move past id
  1163.                 nexttok();      // move past :
  1164.                 return(tokens);
  1165.         }
  1166.         if(tok2==tk_openbracket){
  1167.                 if((cnum=CheckMacros())!=tokens)return cnum;
  1168.                 tobedefined(am32==FALSE?CALL_NEAR:CALL_32,expectedreturn);
  1169.                 cnum=posts-1;
  1170.                 param[0]=0;
  1171.                 int flag=itok.flag;
  1172.                 int exitproc=CheckExitProc();
  1173.                 unsigned int oaddESP=addESP;
  1174.                 if(itok.flag==tp_stdcall){
  1175.                         nexttok();
  1176.                         swapparam();
  1177.                 }
  1178.                 else{
  1179.                         nexttok();
  1180.                         if(uppercase)doregparams();
  1181.                         else doparams();
  1182.                 }
  1183.                 (postbuf+cnum)->loc=outptr+1;
  1184.                 callloc0();                     /* produce CALL [#] */
  1185.                 clearregstat();
  1186.                 addESP=oaddESP;
  1187. #ifdef OPTVARCONST
  1188.                 if(flag&f_useidx)ClearLVIC();
  1189.                 else FreeGlobalConst();
  1190. #endif
  1191.                 retproc=exitproc;
  1192.                 return(expectedreturn);
  1193.         }
  1194.         thisundefined(itok.name);
  1195.         return(tk_long);
  1196. }
  1197.  
  1198. int typesize(int vartype) // âîçâðàùàåò ðàçìåð â áàéòàõ êîäà âîçâðàòà
  1199. {
  1200.         switch(vartype){
  1201.                 case tk_char:
  1202.                 case tk_byte:  return(1);
  1203.                 case tk_int:
  1204.                 case tk_word:  return(2);
  1205.                 case tk_float:
  1206.                 case tk_dword:
  1207.                 case tk_long:  return(4);
  1208.                 case tk_double:
  1209.                 case tk_qword: return 8;
  1210.         }
  1211.         return(0);
  1212. }
  1213.  
  1214. void FpuSt2Number()
  1215. {
  1216.         op66(r32);  //push EAX
  1217.         op(0x50);
  1218.         CheckInitBP();
  1219.         fistp_stack();
  1220.         RestoreBP();
  1221.         fwait3();
  1222.         op66(r32);
  1223.         op(0x58);       //pop EAX
  1224.         if(cpu<3)cpu=3;
  1225. }
  1226.  
  1227. void FpuSt2QNumber()
  1228. {
  1229.         op66(r32);  //push EAX
  1230.         op(0x50);
  1231.         op66(r32);  //push EAX
  1232.         op(0x50);
  1233.         CheckInitBP();
  1234.         fistp_stack(4);
  1235.         RestoreBP();
  1236.         fwait3();
  1237.         op66(r32);
  1238.         op(0x58+EDX);   //pop EAX
  1239.         op66(r32);
  1240.         op(0x58);       //pop EAX
  1241.         if(cpu<3)cpu=3;
  1242. }
  1243.  
  1244. void fwait3_4()
  1245. {
  1246.         if(chip<4)op(0x9B);
  1247. }
  1248.  
  1249. void  convert_returnvalue(int expectedreturn,int actualreturn)
  1250. {
  1251.         if(expectedreturn==tk_void)return; //17.09.05 17:52
  1252.         if(actualreturn==tk_void/*||expectedreturn==tk_void*/){
  1253.                 retvoid();
  1254.                 return;
  1255.         }
  1256.         switch(expectedreturn){
  1257.                 case tk_byte:
  1258.                 case tk_char:
  1259.                 case tk_word:
  1260.                 case tk_int:
  1261.                   if(actualreturn==tk_float||actualreturn==tk_double){
  1262.                                 op66(r32);
  1263.                                 op(0x50);
  1264.                                 FloatToNumer(actualreturn==tk_float?0:4);
  1265.                         }
  1266.                         else if(actualreturn==tk_fpust)FpuSt2Number();
  1267.                         else if(expectedreturn==tk_word||expectedreturn==tk_int){
  1268.                                 if(actualreturn==tk_char)cbw();
  1269.                                 else if(actualreturn==tk_byte)xorAHAH();
  1270.                         }
  1271.                         break;
  1272.                 case tk_long:
  1273.                 case tk_dword:
  1274.                         switch(actualreturn){
  1275.                                 case tk_char:
  1276.                                         op66(r32);
  1277.                                         op(0x0F); outword(0xC0BE);      //MOVSX EAX,AL
  1278.                                         break;
  1279.                                 case tk_byte:   /* MOVZX EAX,AL */
  1280.                                         op66(r32);
  1281.                                         op(0x0F); outword(0xC0B6);
  1282.                                         break;
  1283.                                 case tk_word:  /* MOVZX EAX,AX */
  1284.                                         op66(r32);
  1285.                                         op(0x0F); outword(0xC0B7);
  1286.                                         break;
  1287.                                 case tk_int:    /* MOVSX EAX,AX */
  1288.                                         op66(r32);
  1289.                                         op(0x0F); outword(0xC0BF);
  1290.                                         break;
  1291.                                 case tk_double:
  1292.                                 case tk_fpust:
  1293.                                         FpuSt2Number();
  1294.                                         break;
  1295. //                              case tk_double:
  1296.                                 case tk_float:
  1297.                                         op66(r32);
  1298.                                         op(0x50);
  1299.                                         FloatToNumer(/*actualreturn==tk_float?0:4*/);
  1300.                                         break;
  1301.                         }
  1302.                         if(cpu<3)cpu=3;
  1303.                         break;
  1304.                 case tk_qword:
  1305.                         switch(actualreturn){
  1306.                                 case tk_char:
  1307.                                         op66(r32);
  1308.                                         op(0x0F); outword(0xC0BE);      //MOVSX EAX,AL
  1309.                                         cwdq(r32);
  1310.                                         break;
  1311.                                 case tk_byte:   /* MOVZX EAX,AL */
  1312.                                         op66(r32);
  1313.                                         op(0x0F); outword(0xC0B6);
  1314.                                         ZeroReg(EDX,r32);
  1315.                                         break;
  1316.                                 case tk_word:  /* MOVZX EAX,AX */
  1317.                                         op66(r32);
  1318.                                         op(0x0F); outword(0xC0B7);
  1319.                                 case tk_dword:
  1320.                                         ZeroReg(EDX,r32);
  1321.                                         break;
  1322.                                 case tk_int:    /* MOVSX EAX,AX */
  1323.                                         op66(r32);
  1324.                                         op(0x0F); outword(0xC0BF);
  1325.                                 case tk_long:
  1326.                                         cwdq(r32);
  1327.                                         break;
  1328.                                 case tk_fpust:
  1329.                                 case tk_double:
  1330.                                         FpuSt2QNumber();
  1331.                                         break;
  1332.                                 case tk_float:
  1333.                                         op66(r32);
  1334.                                         op(0x50);
  1335.                                         FloatToNumer(actualreturn==tk_float?0:4);
  1336.                                         cwdq(r32);
  1337.                                         break;
  1338.                         }
  1339.                         if(cpu<3)cpu=3;
  1340.                         break;
  1341.                 case tk_fpust:
  1342.                         if(tok2==tk_semicolon)break;
  1343.                         switch(actualreturn){
  1344.                                 case tk_char:
  1345.                                         CheckInitBP();
  1346.                                         cbw();
  1347.                                         op66(r32);
  1348.                                         outword(0xDF50);        //push EAX
  1349.                                         goto endfxld;   //fild ss[bp-4]/[esp]
  1350.                                 case tk_byte:
  1351.                                         CheckInitBP();
  1352.                                         xorAHAH();
  1353.                                         op66(r32);
  1354.                                         outword(0xDF50);        //push EAX
  1355.                                         goto endfxld;   //fild ss[bp-4]/[esp]
  1356.                                 case tk_word:
  1357.                                         CheckInitBP();
  1358.                                         op66(r16);
  1359.                                         outword(0x6A);  //push 0
  1360.                                         op66(r16);
  1361.                                         outword(0xDB50);        //push AX
  1362.                                         goto endfxld;   //fild ss[bp-4]/[esp]
  1363.                                 case tk_int:
  1364.                                         CheckInitBP();
  1365.                                         op66(r32);
  1366.                                         outword(0xDF50);        //push eax
  1367.                                         goto endfxld;   //fild ss[bp-4]/[esp]
  1368.                                 case tk_dword:
  1369.                                         CheckInitBP();
  1370.                                         op66(r32);              //push 0L
  1371.                                         outword(0x6A);
  1372.                                         op66(r32);
  1373.                                         op(0x50);       //push EAX
  1374.                                         fildq_stack();
  1375.                                         RestoreBP();
  1376.                                         op66(r32);
  1377.                                         op(0x58);       //pop eax
  1378.                                         op66(r32);
  1379.                                         op(0x58);       //pop eax
  1380.                                         break;
  1381.                                 case tk_long:
  1382.                                         CheckInitBP();
  1383.                                         op66(r32);
  1384.                                         outword(0xDB50);        //push EAX
  1385.                                         goto endfxld;   //fild ss[bp-4]/[esp]
  1386.                                 case tk_float:
  1387.                                         CheckInitBP();
  1388.                                         op66(r32);
  1389.                                         outword(0xd950);        //push EAX
  1390. endfxld:
  1391.                                         fld_stack(4+localsize);
  1392.                                         RestoreBP();
  1393.                                         op66(r32);
  1394.                                         op(0x58);       //pop eax
  1395.                                         break;
  1396.                                 case tk_qword:
  1397. //                              case tk_double:
  1398.                                         CheckInitBP();
  1399.                                         op66(r32);
  1400.                                         op(0x50+EDX);   //push EDX
  1401.                                         op66(r32);
  1402.                                         op(0x50);       //push EAX
  1403. /*                                      if(actualreturn==tk_double){
  1404.                                                 op(0xDD);
  1405.                                                 fld_stack(8+localsize);
  1406.                                         }
  1407.                                         else*/ fildq_stack();
  1408.                                         RestoreBP();
  1409.                                         op66(r32);
  1410.                                         op(0x58);       //pop eax
  1411.                                         op66(r32);
  1412.                                         op(0x58);       //pop eax
  1413.                                         break;
  1414.                         }
  1415.                         if(cpu<3)cpu=3;
  1416.                         break;
  1417.                 default:
  1418. //                      printf("expectedreturn=%d %s %d\n",expectedreturn,(startfileinfo+currentfileinfo)->filename,linenumber);
  1419.                         break;
  1420.         }
  1421. }
  1422.  
  1423. int  procdo(int expectedreturn)
  1424. {
  1425. int actualreturn;
  1426. char idflag=0;
  1427.         switch(tok){
  1428.                 case tk_ID:     idflag++;
  1429.                 case tk_id:
  1430.                         actualreturn=doid(idflag,expectedreturn);
  1431.                         break;
  1432.                 case tk_proc:
  1433.                         actualreturn=doanyproc();
  1434.                         break;
  1435.                 case tk_apiproc:
  1436.                 case tk_undefproc:
  1437.                 case tk_declare:
  1438. //                      if((actualreturn=doanyundefproc())==tk_void)actualreturn=expectedreturn;
  1439.                         actualreturn=doanyundefproc(); //17.09.05 17:56
  1440.                         break;
  1441.                 default: internalerror("Bad tok in procdo();"); break;
  1442.         }
  1443.         convert_returnvalue(expectedreturn,actualreturn);
  1444.         return actualreturn;
  1445. }
  1446.  
  1447. /* +++++++++++++++++++++++ loops and ifs start ++++++++++++++++++++++++ */
  1448.  
  1449. void endcmpfloat()
  1450. {
  1451.         fwait3();
  1452.         outword(0xE0DF);//fstsw ax
  1453.         op(0x9E);
  1454.         RestoreBP();
  1455. }
  1456.  
  1457. int  outcmp(int swapped,int ctok,ITOK *cstok,char *&cbuf,SINFO *cstr,int ctok2,ITOK *cstok2,char *&cbuf2,SINFO *cstr2,int typet)
  1458. {
  1459. unsigned char err=0;
  1460. int typef=0;
  1461. int vop=0;
  1462. long long lnumber;
  1463. unsigned int ofs;
  1464. int i,reg,reg1;
  1465.         if(typet<r16)typet=r16;
  1466.         switch(ctok){
  1467.                 case tk_reg64:
  1468.                         reg=cstok->number/256;
  1469.                         switch(ctok2){
  1470.                                 case tk_reg64:
  1471.                                         reg1=cstok2->number/256;
  1472.                                         for(i=0;i<2;i++){
  1473.                                                 op66(r32);
  1474.                                           op(0x39);     //cmp reg,reg
  1475.                                                 op(0xC0+reg+reg1*8);
  1476.                                                 if(i==1)break;
  1477.                                                 outword(0x75);
  1478.                                                 ofs=outptr;
  1479.                                                 reg=cstok->number&255;
  1480.                                                 reg1=cstok2->number&255;
  1481.                                         }
  1482.                                         output[ofs-1]=outptr-ofs;
  1483.                                         break;
  1484.                                 case tk_number:
  1485.                                 case tk_postnumber:
  1486.                                 case tk_undefofs:
  1487.                                         lnumber=cstok2->lnumber>>32;
  1488.                                         for(i=0;i<2;i++){
  1489.                                                 op66(r32);
  1490.                                         //ïðîâåðêà íà âîçìîæíîñòü áîëåå êîðîòêîãî êîäà
  1491.                                                 if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
  1492.                                                         short_ok(lnumber,TRUE)){
  1493.                                                         if(!lnumber){
  1494.                                                                 op(0x85);       //test reg,reg
  1495.                                                                 op(0xc0+reg*9);
  1496.                                                         }
  1497.                                                         else{
  1498.                                                                 op(0x83);       //cmp reg,
  1499.                                                                 op(0xF8+reg);
  1500.                                                                 op(lnumber);
  1501.                                                         }
  1502.                                                 }
  1503.                                                 else{
  1504.                                                         if(reg==AX)op(0x3D);
  1505.                                                         else{
  1506.                                                                 op(0x81);
  1507.                                                                 op(0xF8+reg);
  1508.                                                         }
  1509.                                                         if(i==1){
  1510.                                                                 if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1511.                                                                 else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1512.                                                                 if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
  1513.                                                         }
  1514.                                                         outdword(cstok2->number);
  1515.                                                 }
  1516.                                                 if(i==1)break;
  1517.                                                 outword(0x75);
  1518.                                                 ofs=outptr;
  1519.                                                 reg=cstok->number&255;
  1520.                                         }
  1521.                                         output[ofs-1]=outptr-ofs;
  1522.                                         break;
  1523.                                 default:
  1524.                                         if(swapped)err=1;
  1525.                                         else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
  1526.                                         break;
  1527.                         }
  1528.                         break;
  1529.                 case tk_reg32:
  1530.                 case tk_reg:
  1531.                         switch(ctok2){
  1532.                                 case tk_reg:
  1533.                                 case tk_reg32:
  1534.                                         if(ctok!=ctok2)err=1;
  1535.                                         else{
  1536.                                                 op66(typet);
  1537.                                           op(0x39);     //cmp reg,reg
  1538.                                                 op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
  1539.                                         }
  1540.                                         break;
  1541.                                 case tk_number:
  1542.                                         if(cstok2->number==0&&(cstok2->flag&f_reloc)==0){
  1543.                                                 op66(typet);
  1544.                                                 op(0x85);       //test reg,reg
  1545.                                                 op(0xc0+(unsigned int)cstok->number*9);
  1546.                                                 break;
  1547.                                         }
  1548.                                 case tk_postnumber:
  1549.                                 case tk_undefofs:
  1550.                                         op66(typet);
  1551.                                         //ïðîâåðêà íà âîçìîæíîñòü áîëåå êîðîòêîãî êîäà
  1552.                                         if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
  1553.                                                         short_ok(cstok2->number,ctok==tk_reg?FALSE:TRUE)){
  1554.                                                 op(0x83);       //cmp reg,
  1555.                                                 op(0xF8+(unsigned int)cstok->number);
  1556.                                                 op(cstok2->number);
  1557.                                                 break;
  1558.                                         }
  1559.                                         if(cstok->number==AX)op(0x3D);
  1560.                                         else{
  1561.                                                 op(0x81);
  1562.                                                 op(0xF8+(unsigned int)cstok->number);
  1563.                                         }
  1564.                                         if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1565.                                         else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1566.                                         if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
  1567.                                         if(ctok==tk_reg)outword((unsigned int)cstok2->number);
  1568.                                         else outdword(cstok2->number);
  1569.                                         break;
  1570.                                 default:
  1571.                                         if(swapped)err=1;
  1572.                                         else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
  1573.                                         break;
  1574.                         }
  1575.                         break;
  1576.                 case tk_qwordvar:
  1577.                         cstok->number+=4;
  1578.                         compressoffset(cstok);
  1579.                         switch(ctok2){
  1580.                                 case tk_postnumber:
  1581.                                 case tk_number:
  1582.                                 case tk_undefofs:
  1583.                                         lnumber=cstok2->lnumber>>32;
  1584.                                         CheckAllMassiv(cbuf,8,cstr,cstok);
  1585.                                         for(i=0;i<2;i++){
  1586.                                                 op66(r32);
  1587.                                                 outseg(cstok,2);
  1588.                                         //ïðîâåðêà íà âîçìîæíîñòü áîëåå êîðîòêîãî êîäà
  1589.                                                 if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
  1590.                                                                 short_ok(lnumber,1)){
  1591.                                                         op(0x83);
  1592.                                                         op(0x38+cstok->rm);
  1593.                                                         outaddress(cstok);
  1594.                                                         op(lnumber);
  1595.                                                 }
  1596.                                                 else{
  1597.                                                         op(0x81);
  1598.                                                         op(0x38+cstok->rm);
  1599.                                                         outaddress(cstok);
  1600.                                                         if(i==1){
  1601.                                                                 if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1602.                                                                 else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1603.                                                                 if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
  1604.                                                         }
  1605.                                                         outdword(lnumber);
  1606.                                                 }
  1607.                                                 if(i==1)break;
  1608.                                                 outword(0x75);
  1609.                                                 ofs=outptr;
  1610.                                                 cstok->number-=4;
  1611.                                                 compressoffset(cstok);
  1612.                                                 lnumber=cstok2->lnumber;
  1613.                                         }
  1614.                                         output[ofs-1]=outptr-ofs;
  1615.                                         break;
  1616.                                 case tk_reg64:
  1617.                                         CheckAllMassiv(cbuf,8,cstr,cstok);
  1618.                                         reg=cstok2->number/256;
  1619.                                         for(i=0;i<2;i++){
  1620.                                                 op66(r32);
  1621.                                                 outseg(cstok,2);
  1622.                                                 op(0x39); /* CMP [word],AX */
  1623.                                                 op(cstok->rm+reg*8);
  1624.                                                 outaddress(cstok);
  1625.                                                 if(i==1)break;
  1626.                                                 reg=cstok2->number&255;
  1627.                                                 outword(0x75);
  1628.                                                 ofs=outptr;
  1629.                                                 cstok->number-=4;
  1630.                                                 compressoffset(cstok);
  1631.                                         }
  1632.                                         output[ofs-1]=outptr-ofs;
  1633.                                         break;
  1634.                                 default:
  1635.                                         i=EAX|(EDX*256);
  1636.                                         getintoreg64(i);
  1637.                                         doregmath64(i);
  1638.                                         CheckAllMassiv(cbuf,8,cstr,cstok);
  1639.                                         reg=EDX;
  1640.                                         for(i=0;i<2;i++){
  1641.                                                 op66(r32);
  1642.                                                 outseg(cstok,2);
  1643.                                                 op(0x39); /* CMP [word],AX */
  1644.                                                 op(cstok->rm+reg*8);
  1645.                                                 outaddress(cstok);
  1646.                                                 if(i==1)break;
  1647.                                                 reg=EAX;
  1648.                                                 outword(0x75);
  1649.                                                 ofs=outptr;
  1650.                                                 cstok->number-=4;
  1651.                                                 compressoffset(cstok);
  1652.                                         }
  1653.                                         output[ofs-1]=outptr-ofs;
  1654.                                         break;
  1655.                         }
  1656.                         break;
  1657.                 case tk_intvar:
  1658.                 case tk_wordvar:
  1659.                         if(swapped&&typet==r32)typet=r16;
  1660.                 case tk_longvar:
  1661.                 case tk_dwordvar:
  1662.                         switch(ctok2){
  1663.                                 case tk_reg32:
  1664.                                 case tk_reg:
  1665.                                         CheckAllMassiv(cbuf,typet,cstr,cstok);
  1666.                                         op66(typet);
  1667.                                   outseg(cstok,2);
  1668.                                         op(0x39);
  1669.                                         op((unsigned int)cstok2->number*8+cstok->rm);
  1670.                                         outaddress(cstok);
  1671.                                         break;
  1672.                                 case tk_postnumber:
  1673.                                 case tk_number:
  1674.                                 case tk_undefofs:
  1675.                                         CheckAllMassiv(cbuf,typet,cstr,cstok);
  1676.                                         op66(typet);
  1677.                                         outseg(cstok,2);
  1678.                                         //ïðîâåðêà íà âîçìîæíîñòü áîëåå êîðîòêîãî êîäà
  1679.                                         if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
  1680.                                                         short_ok(cstok2->number,typet/2-1)){
  1681.                                                 op(0x83);
  1682.                                                 op(0x38+cstok->rm);
  1683.                                                 outaddress(cstok);
  1684.                                                 op(cstok2->number);
  1685.                                                 break;
  1686.                                         }
  1687.                                         op(0x81);
  1688.                                         op(0x38+cstok->rm);
  1689.                                         outaddress(cstok);
  1690.                                         if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1691.                                         else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1692.                                         if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
  1693.                                         if(typet==r16)outword((unsigned int)cstok2->number);
  1694.                                         else outdword(cstok2->number);
  1695.                                         break;
  1696.                                 case tk_charvar:
  1697.                                 case tk_intvar:
  1698.                                         getinto_e_ax(1,ctok2,cstok2,cbuf2,cstr2,typet);
  1699.                                         CheckAllMassiv(cbuf,typet,cstr,cstok);
  1700.                                         op66(typet);
  1701.                                         outseg(cstok,2);
  1702.                                         op(0x39);       /* CMP [word],AX */
  1703.                                         op(cstok->rm);
  1704.                                         outaddress(cstok);
  1705.                                         break;
  1706.                                 default:
  1707.                                         getinto_e_ax(0,ctok2,cstok2,cbuf2,cstr2,typet);
  1708. //                                      ClearReg(AX);
  1709.                                         CheckAllMassiv(cbuf,typet,cstr,cstok);
  1710.                                         op66(typet);
  1711.                                         outseg(cstok,2);
  1712.                                         op(0x39); /* CMP [word],AX */
  1713.                                         op(cstok->rm);
  1714.                                         outaddress(cstok);
  1715.                                         break;
  1716.                         }
  1717.                         break;
  1718.                 case tk_number:
  1719.                         if(ctok2==tk_postnumber){
  1720.                                 op(0xB8);        /* MOV AX,# */
  1721.                                 if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
  1722.                                 if(am32==FALSE)outword((unsigned int)cstok->number);
  1723.                                 else outdword(cstok->number);
  1724.                                 op(0x3D);                /* CMP AX,# */
  1725.                                 (cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1726.                                 if(am32==FALSE)outword((unsigned int)cstok2->number);
  1727.                                 else outdword(cstok2->number);
  1728.                         }
  1729.                         if(ctok2==tk_number){
  1730.                                 if(cstok2->rm!=tk_float&&cstok->rm!=tk_float){
  1731.                                         if((unsigned long)cstok2->number<256&&(unsigned long)cstok->number<256){
  1732.                                                 op(0xB0);       //mov al,number
  1733.                                                 op(cstok->number);
  1734.                                                 op(0x3C);       //cmp Al,number
  1735.                                                 op(cstok2->number);
  1736.                                         }
  1737.                                         else if((unsigned long)cstok2->number<65536&&               cstok->number<65536){
  1738.                                                 op66(r16);
  1739.                                                 op(0xB8); /* MOV AX,# */
  1740.                                                 if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
  1741.                                                 outword((unsigned int)cstok->number);
  1742.                                                 op66(r16);
  1743.                                                 op(0x3D);       /* CMP AX,# */
  1744.                                                 if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1745.                                                 outword((unsigned int)cstok2->number);
  1746.                                         }
  1747.                                         else{
  1748.                                                 op66(r32);
  1749.                                                 op(0xB8); /* MOV AX,# */
  1750.                                                 if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
  1751.                                                 outdword(cstok->number);
  1752.                                                 op66(r32);
  1753.                                                 op(0x3D);       /* CMP AX,# */
  1754.                                                 if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1755.                                                 outdword(cstok2->number);
  1756.                                         }
  1757.                                 }
  1758.                                 else{
  1759.                                         op(0x55);       //push bp
  1760.                                         outword(0xe589);//mov bp,sp
  1761.                                         op66(r32);
  1762.                                         if(short_ok(cstok->number,TRUE)){       //push num
  1763.                                                 op(0x6A);
  1764.                                                 op(cstok->number);
  1765.                                         }
  1766.                                         else{
  1767.                                                 op(0x68);
  1768.                                                 outdword(cstok->number);
  1769.                                         }
  1770.                                         op66(r32);
  1771.                                         if(short_ok(cstok2->number,TRUE)){      //push num
  1772.                                                 op(0x6A);
  1773.                                                 op(cstok2->number);
  1774.                                         }
  1775.                                         else{
  1776.                                                 op(0x68);
  1777.                                                 outdword(cstok2->number);
  1778.                                         }
  1779.                                         outword(am32==FALSE?0x46d9:0x45d9);
  1780.                                         op(0xfC);//fld ssdword[bp-4]
  1781.                                         op(0xD8);
  1782.                                         outword(0xF85e - am32); //fcomp [bp-8]
  1783.                                         endcmpfloat();
  1784.                                 }
  1785.                         }
  1786.                         else{
  1787.                                 if(swapped)err=1;
  1788.                                 else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
  1789.                         }
  1790.                         break;
  1791.                 case tk_postnumber:
  1792.                         if(ctok2==tk_number||ctok2==tk_postnumber){
  1793.                                 op(0xB8); /* MOV AX,# */
  1794.                                 (cstok->flag&f_extern)==0?setwordpost(cstok):setwordext(&cstok->number);
  1795.                                 if(am32==FALSE)outword((unsigned int)cstok->number);
  1796.                                 else outdword(cstok->number);
  1797.                                 op(0x3D);       /* CMP AX,# */
  1798.                                 if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
  1799.                                 else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
  1800.                                 if(am32==FALSE)outword((unsigned int)cstok2->number);
  1801.                                 else outdword(cstok2->number);
  1802.                         }
  1803.                         else{
  1804.                                 if(swapped)err=1;
  1805.                                 else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
  1806.                         }
  1807.                         break;
  1808.                 case tk_charvar:
  1809.                 case tk_bytevar:
  1810.                         switch(ctok2){
  1811.                                 case tk_number:
  1812.                                         CheckAllMassiv(cbuf,1,cstr,cstok);
  1813.                                         outseg(cstok,2);
  1814.                                         op(0x80);  /* CMP [byte],# */
  1815.                                         op(0x38+cstok->rm);
  1816.                                         outaddress(cstok);
  1817.                                         op((unsigned int)cstok2->number);
  1818.                                         break;
  1819.                                 case tk_reg:
  1820.                                 case tk_reg32:
  1821.                                         if(cstok2->number>3)goto defchar;
  1822.                                 case tk_beg:
  1823.                                         CheckAllMassiv(cbuf,1,cstr,cstok);
  1824.                                         outseg(cstok,2);
  1825.                                         op(0x38);        /* CMP [byte],beg */
  1826.                                         op((unsigned int)cstok2->number*8+cstok->rm);
  1827.                                         outaddress(cstok);
  1828.                                         break;
  1829.                                 default:
  1830. defchar:
  1831.                                         getintoal(ctok2,cstok2,cbuf2,cstr2);
  1832.                                         CheckAllMassiv(cbuf,1,cstr,cstok);
  1833.                                         outseg(cstok,2);
  1834.                                         op(0x38);       /* CMP [byte],AL */
  1835.                                         op(cstok->rm);
  1836.                                         outaddress(cstok);
  1837.                                         break;
  1838.                         }
  1839.                         break;
  1840.                 case tk_beg:
  1841.                         switch(ctok2){
  1842.                                 case tk_number:
  1843.                                         if(cstok2->number==0){
  1844.                                                 op(0x84);       //test beg,beg
  1845.                                                 op(0xc0+(unsigned int)cstok->number*9);
  1846.                                                 break;
  1847.                                         }
  1848.                                         if((unsigned int)cstok->number==AL)op(0x3C);
  1849.                                         else{
  1850.                                                 op(0x80);
  1851.                                                 op(0xF8+(unsigned int)cstok->number);
  1852.                                         }
  1853.                                         op((unsigned int)cstok2->number);
  1854.                                         break;
  1855.                                 case tk_beg:
  1856.                                         op(0x38);
  1857.                                         op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
  1858.                                         break;
  1859.                                 case tk_reg:
  1860.                                         if((unsigned int)cstok2->number<=BX){   /* CMP beg,beg */
  1861.                                                 op(0x38);
  1862.                                                 op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
  1863.                                         }
  1864.                                         else{
  1865.                                                 op66(r16);
  1866.                                                 op(0x89);                                       /* MOV AX,reg */
  1867.                                                 op(0xC0+(unsigned int)cstok2->number*8);
  1868.                                                 op(0x38);                       /* CMP beg,AL */
  1869.                                                 op(0xC0+(unsigned int)cstok->number);
  1870.                                         }
  1871.                                         break;
  1872.                                 default:
  1873.                                         if(swapped)err=1;
  1874.                                         else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
  1875.                                 break;
  1876.                         }
  1877.                         break;
  1878.                 case tk_doublevar:
  1879.                         vop=4;
  1880.                         goto cont_float;
  1881.                 case tk_fpust:
  1882.                         typef++;
  1883.                         if(cstok->type==tp_modif)typef++;
  1884.                         else{
  1885.                                 if(cstok->number!=0){
  1886.                                         op(0xd9);       //fld st(x)
  1887.                                         op(0xC0+cstok->number);
  1888.                                         typef++;
  1889.                                 }
  1890.                         }
  1891.                 case tk_floatvar:
  1892. cont_float:
  1893.                         switch(ctok2){
  1894.                                 case tk_beg:
  1895.                                         CheckInitBP();
  1896.                                         switch(cstok2->rm){
  1897.                                                 case tk_char:
  1898.                                                 case tk_int:
  1899.                                                 case tk_long:
  1900.                                                         outword(0xBE0F);        /* MOVSX AX,beg */
  1901.                                                         op(0xC0+(unsigned int)cstok2->number);
  1902.                                                         break;
  1903.                                                 default:
  1904.                                                         if((optimizespeed&&chip>3&&chip<7)||cstok2->number==AL){
  1905.                                                                 xorAHAH();
  1906.                                                                 if(cstok2->number!=AL){
  1907.                                                                         op(0x88);
  1908.                                                                         op(0xC0+cstok2->number*8);      //mov al,beg
  1909.                                                                 }
  1910.                                                         }
  1911.                                                         else{
  1912.                                                                 outword(0xB60F);        // MOVZX AX,beg
  1913.                                                                 op(0xC0+(unsigned int)cstok2->number);
  1914.                                                         }
  1915.                                                         break;
  1916.                                         }
  1917.                                         outword(0xDF50);        //push AX
  1918.                                         fld_stack(2+localsize);
  1919.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  1920.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  1921.                                         else{
  1922.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  1923.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  1924.                                                 outseg(cstok,2);        //fcomp var
  1925.                                                 op(0xd8+vop);
  1926.                                                 op(cstok->rm+0x18);
  1927.                                                 outaddress(cstok);
  1928.                                         }
  1929.                                         op(0x58);       // pop EAX
  1930.                                         endcmpfloat();
  1931.                                         swapped=1;
  1932.                                         break;
  1933.                                 case tk_reg:
  1934.                                         CheckInitBP();
  1935.                                         op66(r32);
  1936.                                         switch(cstok2->rm){
  1937.                                                 case tk_char:
  1938.                                                 case tk_int:
  1939.                                                 case tk_long:
  1940.                                                         outword(0xBF0F);        /* MOVSX EAX,reg */
  1941.                                                         break;
  1942.                                                 default:
  1943.                                                         if(optimizespeed&&chip>3&&chip<7&&cstok2->number!=AX){
  1944.                                                                 outword(0xC031);        // xor EAX,EAX
  1945.                                                                 op66(r16);
  1946.                                                                 op(0x8B);
  1947.                                                         }
  1948.                                                         else outword(0xB70F);   // MOVZX EAX,reg
  1949.                                                         break;
  1950.                                         }
  1951.                                         op(0xC0+(unsigned int)cstok2->number);
  1952.                                         op66(r32);
  1953.                                         outword(0xDB50);        //push EAX
  1954.                                         fld_stack(4+localsize);
  1955.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  1956.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  1957.                                         else{
  1958.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  1959.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  1960.                                                 outseg(cstok,2);        //fcomp var
  1961.                                                 op(0xd8+vop);
  1962.                                                 op(cstok->rm+0x18);
  1963.                                                 outaddress(cstok);
  1964.                                         }
  1965.                                         op66(r32);
  1966.                                         op(0x58);       // pop EAX
  1967.                                         endcmpfloat();
  1968.                                         swapped=1;
  1969.                                         break;
  1970.                                 case tk_reg32:
  1971.                                         CheckInitBP();
  1972.                                         if(cstok2->rm==tk_float){
  1973.                                                 op66(r32);
  1974.                                                 op(0x50+(unsigned int)cstok2->number);  //push reg32
  1975.                                                 op(0xd9);
  1976.                                                 fld_stack(4+localsize);
  1977.                                                 if(typef==2)outword(0xD9DE);    //FCOMPP
  1978.                                                 else if(typef==1)outword(0xD9D8);       //FCOMP
  1979.                                                 else{
  1980.                                                         if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  1981.                                                         CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  1982.                                                         outseg(cstok,2);        //fcomp var
  1983.                                                         op(0xd8+vop);
  1984.                                                         op(cstok->rm+0x18);
  1985.                                                         outaddress(cstok);
  1986.                                                 }
  1987.                                                 op66(r32);
  1988.                                                 op(0x58);       // pop EAX
  1989.                                         }
  1990.                                         else{
  1991.                                                 if(cstok2->rm!=tk_char&&cstok2->rm!=tk_int&&cstok2->rm!=tk_long){
  1992.                                                         typet=tk_word;
  1993.                                                         op66(r32);
  1994.                                                         outword(0x6a);  //$push 0
  1995.                                                         if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  1996.                                                 }
  1997.                                                 op66(r32);
  1998.                                                 op(0x50+cstok2->number); //push reg32
  1999.                                                 if(typet!=r16)fildq_stack();
  2000.                                                 else{
  2001.                                                         op(0xdb);
  2002.                                                         fld_stack(4+localsize);
  2003.                                                 }
  2004.                                                 if(typef==2)outword(0xD9DE);    //FCOMPP
  2005.                                                 else if(typef==1)outword(0xD9D8);       //FCOMP
  2006.                                                 else{
  2007.                                                         if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  2008.                                                         CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2009.                                                         outseg(cstok,2);        //fcomp var
  2010.                                                         op(0xd8+vop);
  2011.                                                         op(cstok->rm+0x18);
  2012.                                                         outaddress(cstok);
  2013.                                                 }
  2014.                                                 if(typet!=r16){
  2015.                                                         if(optimizespeed||am32==FALSE){
  2016.                                                                 outword(0xC483);
  2017.                                                                 op(8);
  2018.                                                         }
  2019.                                                         else{
  2020.                                                                 op(0x58);       // pop EAX
  2021.                                                                 op(0x58);       // pop EAX
  2022.                                                         }
  2023.                                                 }
  2024.                                                 else{
  2025.                                                         op66(r32);
  2026.                                                         op(0x58);       // pop EAX
  2027.                                                 }
  2028.                                         }
  2029.                                         endcmpfloat();
  2030.                                         swapped=1;
  2031.                                         break;
  2032.                                 case tk_charvar:
  2033.                                         CheckAllMassiv(cbuf2,1,cstr2,cstok2);
  2034.                                         outseg(cstok2,3);       /* MOVSX AX,[charvar] */
  2035.                                         outword(0xBE0F); op(cstok2->rm);
  2036.                                         outaddress(cstok2);
  2037.                                         CheckInitBP();
  2038.                                         outword(0xdf50);        //push ax
  2039.                                         fld_stack(2+localsize);
  2040.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  2041.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  2042.                                         else{
  2043.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  2044.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2045.                                                 outseg(cstok,2);        //fcomp var
  2046.                                                 op(0xd8+vop);
  2047.                                                 op(cstok->rm+0x18);
  2048.                                                 outaddress(cstok);
  2049.                                         }
  2050.                                         op(0x58);       // pop EAX
  2051.                                         endcmpfloat();
  2052.                                         swapped=1;
  2053.                                         break;
  2054.                                 case tk_intvar:
  2055.                                         CheckAllMassiv(cbuf2,2,cstr2,cstok2);
  2056.                                         outseg(cstok2,2);
  2057.                                         if(typef){
  2058.                                                 op(0xDE);       //ficomp var2
  2059.                                                 op(cstok2->rm+0x08+typef*8);
  2060.                                                 outaddress(cstok2);
  2061.                                         }
  2062.                                         else{
  2063.                                                 op(0xdf);       //fild var
  2064.                                                 op(cstok2->rm);
  2065.                                                 outaddress(cstok2);
  2066.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2067.                                                 outseg(cstok,2);        //fcomp var
  2068.                                                 op(0xd8+vop);
  2069.                                                 op(cstok->rm+0x18);
  2070.                                                 outaddress(cstok);
  2071.                                                 swapped=1;
  2072.                                         }
  2073.                                         fwait3_4();
  2074.                                         outword(0xE0DF);//fstsw ax
  2075.                                         op(0x9E);
  2076.                                         break;
  2077.                                 case tk_bytevar:
  2078.                                         CheckAllMassiv(cbuf2,1,cstr2,cstok2);
  2079.                                         if(optimizespeed&&chip>3&&chip<7){
  2080.                                                 outword(0xC031);
  2081.                                                 outseg(cstok2,2);
  2082.                                                 op(0x8A);
  2083.                                         }
  2084.                                         else{
  2085.                                                 outseg(cstok2,3);
  2086.                                                 outword(0xB60F);
  2087.                                         }
  2088.                                         op(cstok2->rm); // MOVZX regL,[byte]
  2089.                                         outaddress(cstok2);
  2090.                                         CheckInitBP();
  2091.                                         outword(0xDF50);        //push ax
  2092.                                         fld_stack(2+localsize);
  2093.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  2094.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  2095.                                         else{
  2096.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  2097.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2098.                                                 outseg(cstok,2);        //fcomp var
  2099.                                                 op(0xd8+vop);
  2100.                                                 op(cstok->rm+0x18);
  2101.                                                 outaddress(cstok);
  2102.                                         }
  2103.                                         op(0x58);       // pop EAX
  2104.                                         endcmpfloat();
  2105.                                         swapped=1;
  2106.                                         break;
  2107.                                 case tk_wordvar:
  2108.                                         CheckInitBP();
  2109.                                         op66(r16);
  2110.                                         outword(0x6a);  //push 0
  2111.                                         CheckAllMassiv(cbuf2,2,cstr2,cstok2);
  2112.                                         op66(r16);
  2113.                                         outseg(cstok2,2); //push var
  2114.                                         op(0xFF);
  2115.                                         op(cstok2->rm+0x30);
  2116.                                         outaddress(cstok2);
  2117.                                         op(0xDB);
  2118.                                         fld_stack(4+localsize);
  2119.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  2120.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  2121.                                         else{
  2122.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
  2123.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2124.                                                 outseg(cstok,2);        //fcomp var
  2125.                                                 op(0xd8+vop);
  2126.                                                 op(cstok->rm+0x18);
  2127.                                                 outaddress(cstok);
  2128.                                         }
  2129.                                         op66(r32);
  2130.                                         op(0x58);       // pop EAX
  2131.                                         endcmpfloat();
  2132.                                         swapped=1;
  2133.                                         break;
  2134.                                 case tk_dwordvar:
  2135.                                         CheckInitBP();
  2136.                                         op66(r32);      //push 0L
  2137.                                         outword(0x6a);
  2138.                                         CheckAllMassiv(cbuf2,4,cstr2,cstok2);
  2139.                                         op66(r32);      //push var
  2140.                                         outseg(cstok2,2);
  2141.                                         op(0xFF);
  2142.                                         op(cstok2->rm+0x30);
  2143.                                         outaddress(cstok2);
  2144.                                         fildq_stack();
  2145.                                         if(typef==2)outword(0xD9DE);    //FCOMPP
  2146.                                         else if(typef==1)outword(0xD9D8);       //FCOMP
  2147.                                         else{
  2148.                                                 if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=8;
  2149.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2150.                                                 outseg(cstok,2);        //fcomp var
  2151.                                                 op(0xd8+vop);
  2152.                                                 op(cstok->rm+0x18);
  2153.                                                 outaddress(cstok);
  2154.                                         }
  2155.                                         if(optimizespeed||am32==FALSE){
  2156.                                                 outword(0xC483);
  2157.                                                 op(8);
  2158.                                         }
  2159.                                         else{
  2160.                                                 op(0x58);       // pop EAX
  2161.                                                 op(0x58);       // pop EAX
  2162.                                         }
  2163.                                         endcmpfloat();
  2164.                                         swapped=1;
  2165.                                         break;
  2166.                                 case tk_longvar:
  2167.                                         CheckAllMassiv(cbuf2,4,cstr2,cstok2);
  2168.                                         outseg(cstok2,2);
  2169.                                         if(typef){
  2170.                                                 op(0xDA);       //ficomp var2
  2171.                                                 op(cstok2->rm+0x08+typef*8);
  2172.                                                 outaddress(cstok2);
  2173.                                         }
  2174.                                         else{
  2175.                                                 op(0xdb);       //fild var
  2176.                                                 op(cstok2->rm);
  2177.                                                 outaddress(cstok2);
  2178.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2179.                                                 outseg(cstok,2);        //fcomp var
  2180.                                                 op(0xd8+vop);
  2181.                                                 op(cstok->rm+0x18);
  2182.                                                 outaddress(cstok);
  2183.                                                 swapped=1;
  2184.                                         }
  2185.                                         endcmpfloat();
  2186.                                         break;
  2187.                                 case tk_number:
  2188.                                         if(!typef){
  2189.                                                 CheckAllMassiv(cbuf,4,cstr,cstok);
  2190.                                                 outseg(cstok,2);        //fld val
  2191.                                                 op(0xd9);
  2192.                                                 op(cstok->rm);
  2193.                                                 outaddress(cstok);
  2194.                                         }
  2195.                                         if(cstok2->rm!=tk_double&&cstok2->rm!=tk_float){
  2196.                                                 cstok2->dnumber=cstok2->lnumber;
  2197.                                                 cstok2->rm=tk_double;
  2198.                                         }
  2199.                                         else if(vop==4&&cstok2->rm==tk_float){
  2200.                                                 cstok2->dnumber=cstok2->fnumber;
  2201.                                                 cstok2->rm=tk_double;
  2202.                                         }
  2203.                                         if(am32&&(cstok2->rm==tk_float&&cstok2->fnumber==0.0)||
  2204.                                         (cstok2->rm==tk_double&&cstok2->dnumber==0.0)||cstok2->lnumber==0){
  2205.                                                 outword(0xe4d9);        //ftst
  2206.                                                 if(typef!=1)outword(0xC0DD);    //ffree
  2207.                                         }
  2208.                                         else{
  2209.                                                 op66(r32);
  2210.                                                 int rm;
  2211.                                                 rm=(am32==FALSE?0x1eD8:0x1DD8);
  2212.                                                 if(typef==1)rm-=0x800;
  2213.                                                 if(cstok2->rm==tk_double||vop==4)rm+=4;
  2214.                                                 outword(rm);    //fcom(p)
  2215.                                                 AddFloatConst(cstok2->lnumber,cstok2->rm);
  2216.                                                 outword(0);
  2217.                                                 if(am32)outword(0);
  2218.                                         }
  2219.                                         endcmpfloat();
  2220.                                         break;
  2221.                                 case tk_floatvar:
  2222.                                         if(!typef){
  2223.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2224.                                                 outseg(cstok,2);        //fld val
  2225.                                                 op(0xd9+vop);
  2226.                                                 op(cstok->rm);
  2227.                                                 outaddress(cstok);
  2228.                                         }
  2229.                                         CheckAllMassiv(cbuf2,4,cstr2,cstok2);
  2230.                                         outseg(cstok2,2);       //fcomp var
  2231.                                         op(0xd8);
  2232.                                         op(cstok2->rm+(typef==1?0x10:0x18));
  2233.                                         outaddress(cstok2);
  2234.                                         endcmpfloat();
  2235.                                         break;
  2236.                                 case tk_doublevar:
  2237.                                         if(!typef){
  2238.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2239.                                                 outseg(cstok,2);        //fld val
  2240.                                                 op(0xd9+vop);
  2241.                                                 op(cstok->rm);
  2242.                                                 outaddress(cstok);
  2243.                                         }
  2244.                                         CheckAllMassiv(cbuf2,8,cstr2,cstok2);
  2245.                                         outseg(cstok2,2);       //fcomp var
  2246.                                         op(0xd8+4);
  2247.                                         op(cstok2->rm+(typef==1?0x10:0x18));
  2248.                                         outaddress(cstok2);
  2249.                                         endcmpfloat();
  2250.                                         break;
  2251.                                 case tk_fpust:
  2252.                                         if(typef==2){   //fcomp
  2253.                                                 if(chip>=7){    //fcomip
  2254.                                                         op(0xDF);
  2255.                                                         op(0xF0+cstok2->number+1);
  2256.                                                         swapped=1;
  2257.                                                         break;
  2258.                                                 }
  2259.                                                 op(0xD8);
  2260.                                                 op(0xD8+cstok2->number+1);
  2261.                                         }
  2262.                                         else if(typef==1){      //fcom
  2263.                                                 if(chip>=7){    //fcomi
  2264.                                                         op(0xDB);
  2265.                                                         op(0xF0+cstok2->number);
  2266.                                                         swapped=1;
  2267.                                                         break;
  2268.                                                 }
  2269.                                                 op(0xD8);
  2270.                                                 op(0xD0+cstok2->number);
  2271.                                         }
  2272.                                         else{
  2273.                                                 if(cstok2->type!=tp_modif){
  2274.                                                         op(0xd9);       //fld st(x)
  2275.                                                         op(0xC0+cstok2->number);
  2276.                                                 }
  2277.                                                 CheckAllMassiv(cbuf,4+vop,cstr,cstok);
  2278.                                                 outseg(cstok,2);        //fcomp var
  2279.                                                 op(0xd8+vop);
  2280.                                                 op(cstok->rm+0x18);
  2281.                                                 outaddress(cstok);
  2282.                                         }
  2283.                                         endcmpfloat();
  2284.                                         swapped=1;
  2285.                                         break;
  2286.                                 default:
  2287.                                         err=1;
  2288.                                         break;
  2289.                         }
  2290.                         break;
  2291.                 default: err=1; break;
  2292.         }
  2293.         if(err)preerror("unable to create comparison, check restrictions");
  2294.         return(swapped);
  2295. }
  2296.  
  2297. int CheckCompareTok(int reg)
  2298. {
  2299. int comparetok=tk_equalto;
  2300.         if(itok.type==tp_compare)comparetok=tok;
  2301.         else unknowncompop();
  2302.         getoperand(reg);
  2303.         return comparetok;
  2304. }
  2305.  
  2306. int typenumber(int vtok)
  2307. {
  2308.         switch(vtok){
  2309.                 case tk_char:
  2310.                 case tk_beg:
  2311.                 case tk_byte:
  2312.                         return tk_byte;
  2313.                 case tk_int:
  2314.                 case tk_reg:
  2315.                 case tk_word:
  2316.                         return tk_word;
  2317.                 case tk_reg64:
  2318.                 case tk_qword:
  2319.                         return tk_qword;
  2320.                 case tk_floatvar:
  2321.                 case tk_float:
  2322.                         return tk_float;
  2323.                 case tk_doublevar:
  2324.                 case tk_double:
  2325.                         return tk_double;
  2326.         }
  2327.         return tk_dword;
  2328. }
  2329.  
  2330. #ifdef OPTVARCONST
  2331. int constructcompare(int invertflag,unsigned int startloc,LVIC *comconst)
  2332. #else
  2333. int constructcompare(int invertflag,unsigned int startloc)
  2334. #endif
  2335. /* build cmp for IF, if and do {} while */
  2336. {
  2337. int comparetok=0,jumptype,vartype=tokens,notflag=FALSE;
  2338. int ittok,ittok2=tokens,type2=tokens;//,retcompare=tokens;
  2339. int razr=r_undef;
  2340. char *ibuf,*ibuf2;
  2341. ITOK htok,htok2;
  2342. SINFO hstr,hstr2;
  2343. int preg=(am32==TRUE?EAX:SI);
  2344. int use_cxz=0;
  2345. char *ofsstr=NULL,*ofsstr2=NULL;
  2346. int usereg=-1;
  2347. int usereg2=-1;
  2348.  
  2349. //////04.10.04 13:45
  2350. int bracket=0;
  2351. unsigned char oinline=useinline;
  2352.         useinline=0;
  2353.         do{
  2354.                 nexttok();
  2355. //              printf("tok=%d tok2=%d\n",tok,tok2);
  2356.                 if(tok==tk_openbracket)bracket++;
  2357.                 if(tok==tk_not)notflag=(notflag+1)%2;
  2358.         }while(tok2==tk_openbracket||tok2==tk_not);
  2359.         if(bracket==0)expected('(');
  2360. /////////////////
  2361.  
  2362.         setzeroflag=FALSE;
  2363.         ofsstr=GetLecsem(tk_closebracket,tk_eof,tp_compare);
  2364.         getoperand();   //NEW 04.10.04 13:45
  2365.         if(tok==tk_openbracket){
  2366.                 bracket++;
  2367.                 getoperand();
  2368.         }
  2369.         if(tok==tk_not){
  2370.                 notflag=(notflag+1)%2;
  2371.                 getoperand();
  2372.         }
  2373.         switch(tok){
  2374.                 case tk_closebracket:
  2375.                         useinline=oinline;
  2376.                         getoperand();
  2377.                         return voidcompr;
  2378.                 case tk_asm:
  2379.                         if(tok2==tk_openbrace){
  2380.                                 nexttok();
  2381.                                 type2=tok;
  2382.                         }
  2383.                 case tk_dollar:
  2384.                         nexttok();
  2385.                 case tk_idasm:
  2386.                         if(stricmp(itok.name,"test")==0){
  2387.                                 if(iTest(1)==FALSE)InvOperComp();
  2388.                                 ittok=0x75;
  2389.                                 if(type2==tk_openbrace)expecting(tk_closebrace);
  2390.                                 goto endcomp;
  2391.                         }
  2392.                         else preerror("Only 'TEST' possible use in compare");
  2393.                         break;
  2394.                 case tk_qword:
  2395.                 case tk_double:
  2396.                         razr+=4;
  2397.                 case tk_beg:
  2398.                 case tk_reg32:
  2399.                 case tk_reg: vartype=tok; break;
  2400.                 case tk_float:
  2401.                 case tk_long:
  2402.                 case tk_dword:
  2403.                         razr+=2;
  2404.                 case tk_int:
  2405.                 case tk_word:
  2406.                         razr++;
  2407.                 case tk_char:
  2408.                 case tk_byte:
  2409.                         razr++;
  2410.                         vartype=tok;
  2411.                         getoperand();
  2412.                         if(tok==tk_closebracket&&bracket>1){
  2413.                                 bracket--;
  2414.                                 getoperand();
  2415.                         }
  2416.                         break;
  2417.                 case tk_undefproc:
  2418.                 case tk_declare:
  2419. //                      if(itok.rm==tk_void)itok.rm=(am32==FALSE?tk_word:tk_dword);
  2420.                 case tk_proc:
  2421.                 case tk_apiproc:
  2422.                         vartype=itok.rm;
  2423.                         if(vartype==tokens)vartype=(am32==FALSE?tk_word:tk_dword);
  2424.                         else if(vartype==tk_void&&(itok.flag&f_retproc)==0){
  2425.                                 retvoid();
  2426.                                 vartype=itok.rm=(am32==FALSE?tk_word:tk_dword);
  2427.                         }
  2428.                         if(ofsstr){
  2429.                                 free(ofsstr);
  2430.                                 ofsstr=NULL;
  2431.                         }
  2432.                         break;
  2433.                 case tk_bytevar: vartype=tk_byte;       break;
  2434.                 case tk_charvar: vartype=tk_char; break;
  2435.                 case tk_intvar: vartype=tk_int; break;
  2436.                 case tk_wordvar: vartype=tk_word; break;
  2437.                 case tk_dwordvar: vartype=tk_dword; break;
  2438.                 case tk_longvar: vartype=tk_long; break;
  2439.                 case tk_floatvar: vartype=tk_float; break;
  2440.                 case tk_qwordvar: vartype=tk_qword; break;
  2441.                 case tk_fpust:
  2442.                 case tk_doublevar: vartype=tk_double; break;
  2443.                 case tk_bits:
  2444.                         int i;
  2445.                         i=itok.bit.ofs+itok.bit.siz;
  2446.                         if(i<=64){
  2447.                                 vartype=tk_dword;
  2448.                                 razr=r64;
  2449.                         }
  2450.                         if(i<=32){
  2451.                                 vartype=tk_dword;
  2452.                                 razr=r32;
  2453.                         }
  2454.                         if(i<=16){
  2455.                                 vartype=tk_word;
  2456.                                 razr=r16;
  2457.                         }
  2458.                         if(i<=8){
  2459.                                 vartype=tk_byte;
  2460.                                 razr=r8;
  2461.                         }
  2462.                         break;
  2463.                 case tk_at:
  2464.                         if(ofsstr){
  2465.                                 free(ofsstr);
  2466.                                 ofsstr=NULL;
  2467.                         }
  2468.                         nexttok();
  2469.                         if(itok.flag&f_retproc){
  2470.                                 comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1;
  2471. //                              notflag=(notflag==FALSE?TRUE:FALSE);
  2472.                                 vartype=tk_ID;
  2473.                                 ittok2=macros(vartype);
  2474.                                 if(tok2==tk_closebracket){
  2475.                                         nexttok();
  2476.                                         ittok=0x70+comparetok-tk_overflowflag;
  2477.                                         goto endcomp;
  2478.                                 }
  2479.                                 if(ittok2==0){
  2480.                                         vartype=itok.rm;
  2481.                                         break;
  2482.                                 }
  2483.                                 goto mac1;
  2484.                         }
  2485.                         if((itok.flag&f_typeproc)==tp_fastcall&&itok.segm!=NOT_DYNAMIC)vartype=itok.rm;
  2486.                         else vartype=tk_ID;
  2487.                         if((ittok2=macros(vartype))==0){
  2488.                                 vartype=itok.rm;
  2489.                                 break;
  2490.                         }
  2491. mac1:
  2492.                         vartype=ittok2;
  2493.                         switch(vartype){
  2494.                                 case tk_byte:
  2495.                                 case tk_char:   tok=tk_beg; break;
  2496.                                 case tk_int:
  2497.                                 case tk_word:   tok=tk_reg; break;
  2498.                                 case tk_float:
  2499.                                 case tk_dword:
  2500.                                 case tk_long:   tok=tk_reg32; break;
  2501.                                 case tk_double:
  2502.                                 case tk_qword: tok=tk_reg64; break;
  2503.                                 default:
  2504.                                         preerror("Macro has a return type of void");
  2505.                                         tok=tk_reg;
  2506.                                         vartype=tk_word;
  2507.                                         break;
  2508.                         }
  2509.                         itok.number=AX;  // or AL or EAX
  2510.                         break;
  2511.                 default:
  2512.                         if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){
  2513.                                 ittok=0x70+tok-tk_overflowflag;
  2514.                                 nexttok();
  2515.                                 if(tok!=tk_closebracket&&(tok==tk_oror||tok==tk_andand||tok==tk_notequal||tok==tk_equalto)){
  2516.                                         int oper;
  2517.                                         int oper2;
  2518.                                         oper=tok;
  2519.                                         nexttok();
  2520.                                         ittok^=notflag;
  2521.                                         notflag=0;
  2522.                                         if(tok==tk_not){
  2523.                                                 notflag=TRUE;
  2524.                                                 nexttok();
  2525.                                         }
  2526.                                         if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){
  2527.                                                 ittok-=0x70;
  2528.                                                 ittok2=tok-tk_overflowflag;
  2529.                                                 ittok2^=notflag;
  2530.                                                 notflag=0;
  2531.                                                 nexttok();
  2532.                                                 switch(oper){
  2533.                                                         case tk_oror:
  2534.                                                                 if((ittok==2&&ittok2==4)||(ittok==4&&ittok2==2))ittok=6;
  2535.                                                                 else if(ittok==4&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1;
  2536.                                                                 else unknowncompop();
  2537.                                                                 break;
  2538.                                                         case tk_andand:
  2539.                                                                 if((ittok==3&&ittok2==5)||(ittok==5&&ittok2==3))ittok=7;
  2540.                                                                 else if(ittok==5&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1;
  2541.                                                                 else unknowncompop();
  2542.                                                                 break;
  2543.                                                         case tk_notequal:
  2544.                                                                 if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=12;
  2545.                                                                 else unknowncompop();
  2546.                                                                 break;
  2547.                                                         case tk_equalto:
  2548.                                                                 if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=13;
  2549.                                                                 else unknowncompop();
  2550.                                                                 break;
  2551.                                                 }
  2552.                                                 if(tok!=tk_closebracket&&(tok==tk_notequal||tok==tk_equalto)){
  2553.                                                         oper2=tok;
  2554.                                                         nexttok();
  2555.                                                         if(tok==tk_not){
  2556.                                                                 notflag=TRUE;
  2557.                                                                 nexttok();
  2558.                                                         }
  2559.                                                         if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){
  2560.                                                                 ittok2=tok-tk_overflowflag;
  2561.                                                                 ittok2^=notflag;
  2562.                                                                 notflag=0;
  2563.                                                                 nexttok();
  2564.                                                                 if(oper2==tk_notequal){
  2565.                                                                         if(oper==tk_oror&&((ittok==5&&ittok2==8)||(ittok==13&&ittok2==0)))ittok=14;
  2566.                                                                         else unknowncompop();
  2567.                                                                 }
  2568.                                                                 else{
  2569.                                                                         if(oper==tk_andand&&((ittok==6&&ittok2==8)||(ittok==14&&ittok2==0)))ittok=15;
  2570.                                                                         else unknowncompop();
  2571.                                                                 }
  2572.                                                         }
  2573.                                                         else unknowncompop();
  2574.                                                 }
  2575.                                         }
  2576.                                         else unknowncompop();
  2577.                                         ittok+=0x70;
  2578.                                 }
  2579.                                 goto endcomp;
  2580.                         }
  2581.                         vartype=(am32==FALSE?tk_word:tk_dword);
  2582.                         break;
  2583.         }
  2584.         CheckMinusNum();
  2585.         if(itok2.type!=tp_compare&&tok2!=tk_closebracket){      //ñëîæíûé îïåðàíä
  2586.                 if(ofsstr){
  2587.                         int retreg;
  2588.                         razr=getrazr(vartype);
  2589.                         if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){
  2590.                                 GetEndLex(tk_closebracket,tk_semicolon,tp_compare);
  2591.                                 nexttok();
  2592.                                 if(razr==r16)ittok=tk_reg;
  2593.                                 else if(razr==r32)ittok=tk_reg32;
  2594.                                 else ittok=tk_beg;
  2595.                                 usereg=htok.number=retreg==SKIPREG?AX:retreg;
  2596.                                 goto nn1;
  2597.                         }
  2598.                 }
  2599.                 comparetok=0;//èñïîëüçóåòñÿ âðåìåííî íå ïîñìûñëó
  2600.                 ittok=tok;
  2601.                 htok=itok;
  2602.                 ibuf=NULL;
  2603.                 hstr.bufstr=NULL;
  2604.                 ittok2=tok2;
  2605.                 preg=BX;
  2606.                 switch(tok2){
  2607.                         case tk_assign:
  2608.                         case tk_plusplus:
  2609.                         case tk_minusminus:
  2610.                         case tk_divequals:
  2611.                         case tk_minusequals:
  2612.                         case tk_multequals:
  2613.                         case tk_plusequals:
  2614.                                 switch(tok){
  2615.                                         case tk_charvar: comparetok=1;
  2616.                                         case tk_bytevar:
  2617.                                                 if((comparetok=dobytevar(comparetok,0))==tk_reg||comparetok==tk_beg){
  2618.                                                         usereg=htok.number=AX;
  2619.                                                         ittok=tk_beg;
  2620.                                                 }
  2621.                                                 break;
  2622.                                         case tk_intvar: comparetok=1;
  2623.                                         case tk_wordvar:
  2624.                                                 if((comparetok=do_d_wordvar(comparetok,r16,0))==tk_reg){
  2625.                                                         usereg=htok.number=AX;
  2626.                                                         ittok=tk_reg;
  2627.                                                 }
  2628.                                                 break;
  2629.                                         case tk_longvar: comparetok=1;
  2630.                                         case tk_dwordvar:
  2631.                                                 if((comparetok=do_d_wordvar(comparetok,r32,0))==tk_reg32){
  2632.                                                         usereg=htok.number=AX;
  2633.                                                         ittok=tk_reg32;
  2634.                                                 }
  2635.                                                 break;
  2636.                                         case tk_floatvar:
  2637.                                                 if(dofloatvar(0,tk_fpust,0)==tk_fpust){
  2638.                                                         ittok=tk_fpust;
  2639.                                                         htok.type=tp_modif;
  2640.                                                 }
  2641.                                                 break;
  2642.                                         case tk_qwordvar:
  2643.                                                 if((comparetok=doqwordvar(0))==tk_reg64){
  2644.                                                         ittok=tk_reg64;
  2645.                                                         usereg=htok.number=EAX|(EDX*256);
  2646.                                                 }
  2647.                                                 break;
  2648.                                         case tk_reg64:
  2649.                                                 usereg=itok.number;
  2650.                                                 getintoreg64(itok.number);
  2651.                                                 doregmath64(itok.number);
  2652.                                                 comparetok=tk_reg64;
  2653.                                                 break;
  2654.                                         case tk_reg32:
  2655.                                                 usereg=itok.number;
  2656.                                                 comparetok=doreg_32((unsigned int)itok.number,r32,0);
  2657. //                                              printf("comparetok=%d\n",comparetok);
  2658.                                                 break;
  2659.                                         case tk_reg:
  2660.                                                 usereg=itok.number;
  2661.                                                 comparetok=doreg_32((unsigned int)itok.number,r16,0);
  2662.                                                 break;
  2663.                                         case tk_beg:
  2664.                                                 usereg=itok.number;
  2665.                                                 comparetok=dobeg((unsigned int)itok.number,0);
  2666.                                                 break;
  2667.                                         default: InvOperComp(); break;
  2668.                                 }
  2669.                                 if(ittok<tk_floatvar&&(!(comparetok>=tk_overflowflag&&comparetok<=tk_plusflag))){
  2670.                                         if(ittok2!=tk_assign&&ittok2!=tk_divequals&&ittok2!=tk_multequals){
  2671.                                                 if(tok==tk_closebracket){
  2672.                                                         ittok=0x75;
  2673.                                                         goto endcomp;
  2674.                                                 }
  2675.                                                 if(tok2==tk_number&&itok2.number==0){
  2676.                                                         if((ittok2==tk_plusplus||ittok2==tk_minusminus)&&
  2677.                                                                         tok!=tk_notequal&&tok!=tk_equalto)break;
  2678.                                                         comparetok=CheckCompareTok(BX);
  2679.                                                         nexttok();
  2680.                                                         goto createopcode;
  2681.                                                 }
  2682.                                         }
  2683.                                 }
  2684.                                 break;
  2685.                         default:
  2686.                                 switch(vartype){
  2687.                                         case tk_int: comparetok=do_e_axmath(1,r16,&ofsstr); ittok=tk_reg; break;
  2688.                                         case tk_reg:
  2689.                                         case tk_word: comparetok=do_e_axmath(0,r16,&ofsstr); ittok=tk_reg; break;
  2690.                                         case tk_char: comparetok=doalmath(1,&ofsstr); ittok=tk_beg; break;
  2691.                                         case tk_beg:
  2692.                                         case tk_byte: comparetok=doalmath(0,&ofsstr); ittok=tk_beg; break;
  2693.                                         case tk_long: comparetok=do_e_axmath(1,r32,&ofsstr); ittok=tk_reg32; break;
  2694.                                         case tk_reg32:
  2695.                                         case tk_dword:
  2696.                                                 comparetok=do_e_axmath(0,r32,&ofsstr);
  2697.                                                 ittok=tk_reg32;
  2698.                                                 break;
  2699.                                         case tk_qword:
  2700.                                                 usereg=htok.number=EAX|(EDX*256);
  2701.                                                 getintoreg64(usereg);
  2702.                                                 doregmath64(usereg);
  2703.                                                 comparetok=ittok=tk_reg64;
  2704.                                                 break;
  2705.                                         case tk_float:
  2706.                                                 doeaxfloatmath(tk_fpust);
  2707.                                                 ittok=tk_fpust;
  2708.                                                 htok.type=tp_modif;
  2709.                                                 break;
  2710.                                         default:
  2711.                                                 if(itok.flag&f_retproc){
  2712.                                                         comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1;
  2713. //                                                      printf("tok=%d flag=%08X comparetok=%u %s\n",tok,itok.flag,comparetok,itok.name);
  2714. //                                                      notflag=(notflag==FALSE?TRUE:FALSE);
  2715.                                                         switch(tok){
  2716.                                                                 case tk_undefproc:
  2717.                                                                 case tk_declare:
  2718.                                                                 case tk_apiproc:
  2719.                                                                         doanyundefproc();
  2720.                                                                         break;
  2721.                                                                 case tk_proc:
  2722.                                                                         doanyproc();
  2723.                                                                         break;
  2724.                                                         }
  2725.                                                         nexttok();
  2726.                                                         if(tok!=tk_closebracket){
  2727.                                                                 retvoid();
  2728.                                                                 do{
  2729.                                                                         nexttok();
  2730.                                                                 }while(tok!=tk_closebracket);
  2731.                                                         }
  2732.                                                 }
  2733.                                                 else{
  2734.                                                         internalerror("Bad vartype value in constructcompare();");
  2735.                                                         tok=tk_reg; break;
  2736.                                                 }
  2737.                                 }
  2738.                                 if(ittok!=tk_reg64)usereg=htok.number=AX;                       // same value as AL and EAX
  2739.                 }
  2740.                 RestoreStack();
  2741.         }
  2742.         else{
  2743. #ifdef OPTVARCONST
  2744.                 CheckConstVar3(&tok,&itok,razr);
  2745. #endif
  2746.                 if(tok>=tk_charvar&&tok<=tk_doublevar){
  2747.                         switch(vartype){
  2748.                                 case tk_int: tok=tk_intvar; break;
  2749.                                 case tk_word: tok=tk_wordvar; break;
  2750.                                 case tk_char: tok=tk_charvar; break;
  2751.                                 case tk_byte: tok=tk_bytevar; break;
  2752.                                 case tk_long: tok=tk_longvar; break;
  2753.                                 case tk_dword: tok=tk_dwordvar; break;
  2754.                                 case tk_float: tok=tk_floatvar; break;
  2755.                                 case tk_qword: tok=tk_qwordvar; break;
  2756.                                 case tk_double: tok=tk_doublevar; break;
  2757.                         }
  2758.                 }
  2759.                 else if(tok==tk_number){
  2760.                         if(tok2==tk_closebracket){
  2761.                                 invertflag=(itok.number==0?zerocompr:voidcompr);
  2762.                                 nexttok();
  2763.                                 getoperand();
  2764.                                 useinline=oinline;
  2765.                                 return invertflag;
  2766.                         }
  2767.                         if(itok.rm==tk_float)vartype=tk_float;
  2768.                 }
  2769.                 else if(tok==tk_bits){
  2770.                         bits2reg(AX,razr);
  2771.                         switch(razr){
  2772.                                 case r64:
  2773.                                 case r32:
  2774.                                         tok=tk_reg32;
  2775.                                         break;
  2776.                                 case r16:
  2777.                                         tok=tk_reg;
  2778.                                         break;
  2779.                                 case r8:
  2780.                                         tok=tk_beg;
  2781.                                         break;
  2782.                         }
  2783.                         itok.number=0;
  2784.                 }
  2785.                 if(tok==tk_beg||tok==tk_reg||tok==tk_reg32)itok.rm=vartype;     //òèï ñîäåðæèìîãî â reg32
  2786.                 ittok=tok;
  2787.                 htok=itok;
  2788.                 ibuf=bufrm;
  2789.                 bufrm=NULL;
  2790.                 hstr=strinf;
  2791.                 strinf.bufstr=NULL;
  2792.                 nexttok();
  2793.         }
  2794. nn1:
  2795.         if(razr==r_undef){
  2796.                 switch(vartype){
  2797.                         case tk_qword:
  2798.                         case tk_double:
  2799.                                 razr+=4;
  2800.                         case tk_long:
  2801.                         case tk_dword:
  2802.                         case tk_float:
  2803.                         case tk_reg32:
  2804.                                 razr+=2;
  2805.                         case tk_int:
  2806.                         case tk_word:
  2807.                         case tk_reg:
  2808.                                 razr++;
  2809.                         case tk_char:
  2810.                         case tk_byte:
  2811.                         case tk_beg:
  2812.                                 razr++;
  2813.                 }
  2814.         }
  2815.         if(tok!=tk_closebracket){       //ñðàâíåíèå
  2816.                 ofsstr2=GetLecsem(tk_closebracket);
  2817.                 comparetok=CheckCompareTok(preg);
  2818.                 if(tok>=tk_char&&tok<=tk_double){
  2819.                         type2=tok;
  2820.                         if(ofsstr2)free(ofsstr2);
  2821.                         ofsstr2=GetLecsem(tk_closebracket);
  2822.                         getoperand(preg);
  2823.                 }
  2824.                 if(tok==tk_minus){
  2825.                         if(CheckMinusNum()==FALSE){
  2826.                                 preerror("only negative of constants valid within compairsons");
  2827.                                 nexttok();
  2828.                         }
  2829.                 }
  2830. #ifdef OPTVARCONST
  2831.                 CheckConstVar3(&tok,&itok,razr);
  2832. #endif
  2833.                 if(tok==tk_number){
  2834.                         switch(vartype){
  2835.                                 case tk_long:
  2836.                                 case tk_int:
  2837.                                 case tk_char:
  2838.                                         htok2.number=doconstlongmath();
  2839.                                         itok.flag=(unsigned char)postnumflag;
  2840.                                         break;
  2841.                                 case tk_dword:
  2842.                                 case tk_reg32:
  2843.                                 case tk_beg:
  2844.                                 case tk_reg:
  2845.                                 case tk_word:
  2846.                                 case tk_byte:
  2847.                                         htok2.number=doconstdwordmath();
  2848.                                         itok.flag=(unsigned char)postnumflag;
  2849.                                         break;
  2850.                                 case tk_float:
  2851.                                         htok2.number=doconstfloatmath();
  2852.                                         break;
  2853.                                 case tk_reg64:
  2854.                                 case tk_qword:
  2855.                                         htok2.lnumber=doconstqwordmath();
  2856.                                         itok.flag=(unsigned char)postnumflag;
  2857.                                         break;
  2858.                                 case tk_double:
  2859.                                         htok2.lnumber=doconstdoublemath();
  2860.                                         break;
  2861.                         }
  2862.                         htok2.rm=typenumber(vartype);
  2863.                         ittok2=tk_number;
  2864.                         htok2.flag=itok.flag;
  2865.                 }
  2866.                 else{
  2867.                         if(ittok>=tk_charvar&&ittok<=tk_doublevar&&(tok==tk_proc||tok==tk_id||
  2868.                                         tok==tk_undefproc||tok==tk_declare||tok==tk_apiproc||tok==tk_ID||
  2869.                                         itok2.type==tp_opperand||(tok>=tk_charvar&&tok<=tk_doublevar))){
  2870.                                 if(ofsstr2){
  2871.                                         int retreg;
  2872.                                         razr=getrazr(vartype);
  2873.                                         if((retreg=CheckIDZReg(ofsstr2,AX,razr))!=NOINREG){
  2874.                                                 GetEndLex(tk_closebracket);
  2875.                                                 usereg2=retreg==SKIPREG?AX:retreg;
  2876.                                                 if(razr==r16)ittok2=tk_reg;
  2877.                                                 else if(razr==r32)ittok2=tk_reg32;
  2878.                                                 else ittok2=tk_beg;
  2879.                                                 htok2.number=usereg2;
  2880.                                                 nexttok();
  2881.                                                 goto en2;
  2882.                                         }
  2883.                                 }
  2884.                                 int sign=0;
  2885.                                 switch(ittok){
  2886.                                         case tk_charvar: sign=1;
  2887.                                         case tk_bytevar:
  2888.                                                 doalmath(sign,&ofsstr2);
  2889.                                                 usereg2=htok2.number=AX;
  2890.                                                 ittok2=tk_beg;
  2891.                                                 break;
  2892.                                         case tk_intvar: sign=1;
  2893.                                         case tk_wordvar:
  2894.                                                 do_e_axmath(sign,r16,&ofsstr2);
  2895.                                                 usereg2=htok2.number=AX;
  2896.                                                 ittok2=tk_reg;
  2897.                                                 break;
  2898.                                         case tk_longvar: sign=1;
  2899.                                         case tk_dwordvar:
  2900.                                                 do_e_axmath(sign,r32,&ofsstr2);
  2901.                                                 usereg2=htok2.number=AX;
  2902.                                                 ittok2=tk_reg32;
  2903.                                                 break;
  2904.                                         case tk_floatvar:
  2905.                                                 doeaxfloatmath(tk_fpust);
  2906.                                                 ittok2=tk_fpust;
  2907.                                                 htok2.type=tp_modif;
  2908.                                                 htok2.number=0;
  2909.                                                 ClearReg(AX);
  2910.                                                 break;
  2911.                                         case tk_doublevar:
  2912.                                                 doeaxfloatmath(tk_fpust,0,4);
  2913.                                                 ittok2=tk_fpust;
  2914.                                                 htok2.type=tp_modif;
  2915.                                                 htok2.number=0;
  2916.                                                 ClearReg(AX);
  2917.                                                 break;
  2918.                                         case tk_qwordvar:
  2919.                                                 usereg2=htok2.number=EAX|(EDX*256);
  2920.                                                 getintoreg64(usereg2);
  2921.                                                 doregmath64(usereg2);
  2922.                                                 ittok2=tk_reg64;
  2923.                                                 ClearReg(AX);
  2924.                                                 ClearReg(DX);
  2925.                                                 break;
  2926.                                 }
  2927.                         }
  2928.                         else{
  2929.                                 if(tok==tk_bits){
  2930.                                         int i=itok.bit.ofs+itok.bit.siz;
  2931.                                         int vops;
  2932.                                         if(i<=64)vops=r64;
  2933.                                         if(i<=32)vops=r32;
  2934.                                         if(i<=16)vops=r16;
  2935.                                         if(i<=8)vops=r8;
  2936.                                         if(vops<razr)vops=razr;
  2937.                                         i=AX;
  2938.                                         if((ittok==tk_reg32||ittok==tk_reg||ittok==tk_beg)&&htok.number==0)i=CX;
  2939.                                         bits2reg(i,vops);
  2940.                                         switch(razr){
  2941.                                                 case r64:
  2942.                                                 case r32:
  2943.                                                         tok=tk_reg32;
  2944.                                                         break;
  2945.                                                 case r16:
  2946.                                                         tok=tk_reg;
  2947.                                                         break;
  2948.                                                 case r8:
  2949.                                                         tok=tk_beg;
  2950.                                                         break;
  2951.                                         }
  2952.                                         itok.number=i;
  2953.                                         ClearReg(i);
  2954.                                 }
  2955.                                 switch(tok){
  2956.                                         case tk_beg:
  2957.                                         case tk_reg:
  2958.                                         case tk_reg32:
  2959.                                                 itok.rm=type2;  //òèï ñîäåðæèìîãî â reg32
  2960.                                                 if((ittok==tk_reg32||ittok==tk_reg||ittok==tk_beg)&&
  2961.                                                                 htok.number==itok.number)preerror("Comparison two identical registers");
  2962.                                                 break;
  2963.                                 }
  2964.                                 int next=TRUE;
  2965.                                 int sign=0;
  2966.                                 if(ittok==tk_reg32){
  2967.                                         if(ofsstr2){
  2968.                                                 int retreg;
  2969.                                                 int treg;
  2970.                                                 treg=(htok.number==0?DX:AX);
  2971.                                                 razr=r32;
  2972.                                                 if((retreg=CheckIDZReg(ofsstr2,treg,r32))!=NOINREG){
  2973.                                                         if(retreg==SKIPREG)retreg=treg;
  2974.                                                         if(retreg!=htok.number){
  2975.                                                                 GetEndLex(tk_closebracket);
  2976.                                                                 ittok2=tk_reg32;
  2977.                                                                 htok2.number=usereg2=retreg;
  2978.                                                                 nexttok();
  2979.                                                                 goto en2;
  2980.                                                         }
  2981.                                                 }
  2982.                                         }
  2983.                                         switch(tok){
  2984.                                                 case tk_intvar:
  2985.                                                         sign=1;
  2986.                                                 case tk_wordvar:
  2987.                                                         if(htok.number!=0){
  2988.                                                                 do_e_axmath(sign,r32,&ofsstr2);
  2989.                                                                 usereg2=itok.number=0;
  2990.                                                         }
  2991.                                                         else{
  2992.                                                                 getintoreg_32(DX,r32,sign,&ofsstr2);
  2993.                                                                 usereg2=itok.number=DX;
  2994.                                                         }
  2995.                                                         warningreg(regs[1][itok.number]);
  2996.                                                         next=FALSE;
  2997.                                                         ittok2=tk_reg32;
  2998.                                                         htok2=itok;
  2999.                                         }
  3000.                                 }
  3001.                                 if(next){
  3002.                                         ittok2=tok;
  3003.                                         htok2=itok;
  3004.                                         ibuf2=bufrm;
  3005.                                         bufrm=NULL;
  3006.                                         hstr2=strinf;
  3007.                                         strinf.bufstr=NULL;
  3008.                                         nexttok();
  3009.                                 }
  3010.                         }
  3011.                         RestoreStack();
  3012.                 }
  3013.         }
  3014.         else{   // !=0
  3015.                 if((comparetok>=tk_overflowflag)&&(comparetok<=tk_plusflag)){
  3016.                         ittok=0x70+comparetok-tk_overflowflag;
  3017.                         goto endcomp;
  3018.                 }
  3019.                 htok2.rm=typenumber(vartype);
  3020.                 comparetok=tk_notequal;
  3021.                 ittok2=tk_number;
  3022.                 htok2.number=0;
  3023.                 htok2.flag=0;
  3024.         }
  3025.         if(ittok2==tk_number&&htok2.number==0&&(htok2.flag&f_reloc)==0){
  3026.                 if(setzeroflag){
  3027.                         if(comparetok==tk_notequal){
  3028.                                 ittok=0x75;
  3029.                                 goto endcomp;
  3030.                         }
  3031.                         if(comparetok==tk_equalto){
  3032.                                 ittok=0x74;
  3033.                                 goto endcomp;
  3034.                         }
  3035.                 }
  3036.                 if(htok.number==CX&&optimizespeed==0){
  3037.                         if(ittok==tk_reg||ittok==tk_reg32){
  3038.                                 if(comparetok==tk_notequal)use_cxz=notflag==0?cxnzcompr:cxzcompr;
  3039.                                 else if(comparetok==tk_equalto)use_cxz=notflag==TRUE?cxnzcompr:cxzcompr;
  3040.                         }
  3041.                 }
  3042.         }
  3043. en2:
  3044.         if(ittok>=tk_charvar&&ittok<=tk_floatvar){
  3045.                 if(ofsstr){
  3046.                         int retreg;
  3047.                         razr=getrazr(vartype);
  3048.                         if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){
  3049.                                 usereg=retreg==SKIPREG?AX:retreg;
  3050.                                 if(!((ittok2==tk_reg||ittok2==tk_reg32||ittok2==tk_beg)&&usereg==htok2.number)){
  3051.                                         if(razr==r16)ittok=tk_reg;
  3052.                                         else if(razr==r32)ittok=tk_reg32;
  3053.                                         else ittok=tk_beg;
  3054.                                         htok.number=usereg;
  3055.                                         if(ibuf){
  3056.                                                 free(ibuf);
  3057.                                                 ibuf=NULL;
  3058.                                         }
  3059.                                         if(hstr.bufstr){
  3060.                                                 free(hstr.bufstr);
  3061.                                                 hstr.bufstr=NULL;
  3062.                                         }
  3063.                                 }
  3064.                                 else{
  3065.                                         usereg=-1;
  3066.                                 }
  3067.                         }
  3068.                         else{
  3069.                                 if(ittok==tk_floatvar)ClearReg(AX);
  3070.                                 else if(ittok>=tk_intvar&&ittok<tk_floatvar){
  3071.                                         switch(ittok2){
  3072.                                                 case tk_reg:
  3073.                                                 case tk_reg32:
  3074.                                                 case tk_number:
  3075.                                                 case tk_postnumber:
  3076.                                                 case tk_undefofs:
  3077.                                                         break;
  3078.                                                 default:
  3079.                                                         usereg2=0;
  3080.                                                         break;
  3081.                                         }
  3082.                                 }
  3083.                                 else{
  3084.                                         switch(ittok2){
  3085.                                                 case tk_reg:
  3086.                                                 case tk_reg32:
  3087.                                                         ClearReg(AX);
  3088.                                                 case tk_number:
  3089.                                                 case tk_beg:
  3090.                                                         break;
  3091.                                                 default:
  3092.                                                         usereg2=0;
  3093.                                                         break;
  3094.                                         }
  3095.                                 }
  3096.                         }
  3097.                 }
  3098.         }
  3099.         if(ittok==tk_number&&htok.flag==0&&ittok2==tk_number&&htok2.flag==0){
  3100.                 invertflag=(htok.number!=htok2.number?zerocompr:voidcompr);
  3101.                 useinline=oinline;
  3102.                 return invertflag;
  3103.         }
  3104.         if((ittok==tk_number||ittok==tk_postnumber)&&(ittok2==tk_number||ittok2==tk_postnumber))usereg=0;
  3105. #ifdef OPTVARCONST
  3106.         if(comconst){
  3107.                 if(comparetok==tk_equalto||comparetok==tk_notequal){
  3108.                         if(ittok>=tk_charvar&&ittok<=tk_doublevar&&ittok2==tk_number&&
  3109.                                 (htok2.flag&f_reloc)==0&&htok.rec&&(htok.flag&f_useidx)==0){
  3110.                                 comconst->rec=htok.rec;
  3111.                                 comconst->lnumber=htok2.lnumber;
  3112.                                 comconst->contype=htok2.rm;
  3113.                         }
  3114.                         else if(ittok2>=tk_charvar&&ittok2<=tk_doublevar&&ittok==tk_number&&
  3115.                                 (htok.flag&f_reloc)==0&&htok2.rec&&(htok2.flag&f_useidx)==0){
  3116.                                 comconst->rec=htok2.rec;
  3117.                                 comconst->lnumber=htok.lnumber;
  3118.                                 comconst->contype=htok.rm;
  3119.                         }
  3120.                         comconst->typevar=comparetok;
  3121.                         if(notflag)comconst->typevar=(comparetok==tk_equalto?tk_notequal:tk_equalto);
  3122.                 }
  3123.         }
  3124. #endif
  3125.         if(outcmp(0,ittok,&htok,ibuf,&hstr,ittok2,&htok2,ibuf2,&hstr2,razr)){
  3126.                 switch(comparetok){
  3127.                         case tk_less:   comparetok=tk_greater; break;
  3128.                         case tk_lessequal: comparetok=tk_greaterequal; break;
  3129.                         case tk_greater: comparetok=tk_less; break;
  3130.                         case tk_greaterequal: comparetok=tk_lessequal; break;
  3131.                 }
  3132.         }
  3133. createopcode:
  3134.         jumptype=0;
  3135.         if(vartype==tk_char||vartype==tk_int||vartype==tk_long)jumptype=1;
  3136.         switch(comparetok){
  3137.                 case tk_equalto: ittok=0x74; break;
  3138.                 case tk_notequal: ittok=0x75; break;
  3139.                 case tk_greater:
  3140.                         ittok=(jumptype==0?0x77:0x7F);
  3141.                         break;
  3142.                 case tk_less:
  3143.                         ittok=(jumptype==0?0x72:0x7C);
  3144.                         break;
  3145.                 case tk_greaterequal:
  3146.                         ittok=(jumptype==0?0x73:0x7D);
  3147.                         break;
  3148.                 case tk_lessequal:
  3149.                         ittok=(jumptype==0?0x76:0x7E);
  3150.                         break;
  3151.                 default: unknowncompop(); break;
  3152.         }
  3153. endcomp:
  3154.         if(ofsstr){
  3155.                 if(usereg!=-1)IDZToReg(ofsstr,usereg,razr);
  3156.                 free(ofsstr);
  3157.         }
  3158.         if(ofsstr2){
  3159. //              printf("usereg2=%08X %s\n",usereg2,ofsstr2);
  3160.                 if(usereg2!=-1)IDZToReg(ofsstr2,usereg2,razr);
  3161.                 free(ofsstr2);
  3162.         }
  3163.         if(invertflag==2)invertflag=((outptr+2-startloc)>128?1:0);
  3164.         ittok^=invertflag;
  3165.         ittok^=notflag;
  3166.         op(ittok);  /* output instruction code */
  3167.         expecting(tk_closebracket);
  3168.         useinline=oinline;
  3169.         return invertflag|use_cxz;
  3170. }
  3171.  
  3172. #ifdef OPTVARCONST
  3173. ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst)
  3174. #else
  3175. ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg)
  3176. #endif
  3177. {
  3178. unsigned int i;
  3179. ICOMP *icomp;
  3180. int j=0;
  3181. int ifline=linenumber;
  3182. int ptok=tk_oror;
  3183. int rcompr;
  3184. int useor=FALSE;
  3185. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  3186.         if(am32)j=2;
  3187.         icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF);     //áëîê äëÿ èíôî î ñðàâíåíèÿõ
  3188.         i=0;
  3189.  
  3190.         do{
  3191. #ifdef OPTVARCONST
  3192.                 if((rcompr=constructcompare(0,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1;
  3193. #else
  3194.                 if((rcompr=constructcompare(0,outptr))==voidcompr||rcompr==zerocompr)i=1;
  3195. #endif
  3196.                 if(i){
  3197.                         if(rcompr==voidcompr&&ptok==tk_andand){
  3198.                                 i=0;
  3199.                                 ptok=tok;
  3200.                         }
  3201.                         continue;
  3202.                 }
  3203.                 op(0x03+j);
  3204.                 if(tok!=tk_oror){
  3205.                         JXorJMP();
  3206.                         if(am32!=FALSE)outword(0);
  3207.                         outword(0);
  3208.                 }
  3209.                 (icomp+*numcomp)->loc=outptr;
  3210.                 (icomp+*numcomp)->type=tok;
  3211. //              (icomp+*numcomp)->use_cxz=rcompr&0xFC;
  3212.                 (*numcomp)++ ;
  3213.                 if(*numcomp==MAXIF){
  3214.                         ManyLogicCompare();
  3215.                         free(icomp);
  3216.                         return NULL;
  3217.                 }
  3218.                 ptok=tok;
  3219. /*              if(tok!=tk_andand&&tok!=tk_oror&&bakregstat==NULL){
  3220.                         bakregstat=BakRegStat();
  3221.                         changeregstat=BakRegStat();
  3222.                 }*/
  3223.         }while(tok==tk_oror||tok==tk_andand);
  3224.         if(tok==tk_closebracket)nexttok();
  3225.         for(i=0;i<*numcomp;i++){
  3226.                 unsigned long temp=outptr-(icomp+i)->loc;
  3227.                 if((icomp+i)->type==tk_oror){
  3228. #ifdef OPTVARCONST
  3229.                         if(comconst)comconst->rec=NULL;
  3230. #endif
  3231.                         if(temp>127)CompareOr();
  3232.                         output[(icomp+i)->loc-1]=(unsigned char)temp;
  3233.                         clearregstat();
  3234.                         useor=TRUE;
  3235.                 }
  3236.                 else if(chip>2){
  3237.                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)temp;
  3238.                         else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)temp;
  3239.                 }
  3240.         }
  3241.  
  3242.         if(bakregstat==NULL){
  3243.                 bakregstat=BakRegStat();
  3244.                 changeregstat=BakRegStat();
  3245.         }
  3246.         if(type==tk_if&&rcompr!=zerocompr){
  3247.                 if(rcompr==voidcompr)warcompeqconst();
  3248.                 if(tok==tk_return||tok==tk_RETURN){
  3249.                         if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){
  3250.                                 if(insertmode||(!optimizespeed)){
  3251.                                         if(tok==tk_return||tok==tk_RETURN)goto merge_if;
  3252.                                 }
  3253.                         }
  3254.                         startblock();
  3255.                         doreturn(tok);
  3256.                         endblock();
  3257.                         int di;
  3258.                         if(rcompr==voidcompr)di=0;
  3259.                         else di=am32==FALSE?2:4;
  3260.                         for(unsigned int i=0;i<*numcomp;i++){
  3261.                                 if((icomp+i)->type!=tk_oror){
  3262.                                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-di]=(unsigned short)(outptr-(icomp+i)->loc);
  3263.                                         else *(unsigned long *)&output[(icomp+i)->loc-di]=(unsigned long)(outptr-(icomp+i)->loc);
  3264.                                 }
  3265.                         }
  3266.                         if((outptr-icomp->loc)<=127)warningjmp(mesIF,ifline);
  3267.                         if(tok==tk_else||tok==tk_ELSE){
  3268.                                 notunreach=TRUE;
  3269.                                 nexttok();
  3270.                                 docommand();
  3271.                         }
  3272.                         free(icomp);
  3273.                         return NULL;
  3274.                 }
  3275.                 if(tok==tk_break||tok==tk_BREAK||tok==tk_continue||tok==tk_CONTINUE||tok==tk_goto||tok==tk_GOTO){
  3276. merge_if:
  3277.                         if(rcompr==voidcompr)goto endp;
  3278.                         if(chip<3){
  3279.                                 for(i=0;i<*numcomp;i++){
  3280.                                         if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-3-j);
  3281.                                         else{
  3282.                                                 if((icomp+i)->type!=tk_andand)output[(icomp+i)->loc-5-j]=(unsigned char)(output[(icomp+i)->loc-5-j]^1);
  3283.                                                 else{
  3284.                                                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc);
  3285.                                                         else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc);
  3286.                                                 }
  3287.                                         }
  3288.                                 }
  3289.                                 outptr-=3+j;
  3290.                         }
  3291.                         else{
  3292.                                 for(i=0;i<*numcomp;i++){
  3293.                                         if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-2-j);
  3294.                                         else{
  3295.                                                 if((icomp+i)->type!=tk_andand){
  3296.                                                         output[(icomp+i)->loc-4-j]=(unsigned char)(output[(icomp+i)->loc-3-j]-0x10);
  3297.                                                         output[(icomp+i)->loc-3-j]=(unsigned char)(3+j);
  3298.                                                 }
  3299.                                                 else{
  3300.                                                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc+1);
  3301.                                                         else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc+1);
  3302.                                                 }
  3303.                                         }
  3304.                                 }
  3305.                                 outptr-=2+j;
  3306.                                 if(cpu<3)cpu=3;
  3307.                         }
  3308.                         int delta=0;    //new 07.06.06 20:27
  3309.  
  3310.                         if(tok==tk_break||tok==tk_BREAK){
  3311.                                 if(useor==FALSE){
  3312.                                         int ooutptr=outptr-2;
  3313.                                         int otok=tok;
  3314.                                         i=(unsigned char)(output[ooutptr]^1);
  3315.                                         outptr--;
  3316.                                         if(tok==tk_break)i+=0x10;
  3317.                                         else outptr--;
  3318.                                         doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32)));
  3319.                                         if(otok==tk_break){
  3320.                                                 output[ooutptr]=0x0f;
  3321.                                                 output[ooutptr+1]=i;
  3322.                                                 delta=-1;
  3323.                                         }
  3324.                                         else{
  3325.                                                 output[ooutptr]=i;
  3326.                                                 delta=(am32==TRUE?-5:-3);
  3327.                                         }
  3328.                                 }
  3329.                                 else{
  3330.                                         if(tok==tk_BREAK){
  3331.                                                 output[outptr-1]-=(am32==TRUE?3:1);
  3332.                                         }
  3333.                                         doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32)));
  3334.                                 }
  3335.                         }
  3336.                         else if(tok==tk_return||tok==tk_RETURN){
  3337. //new 07.06.06 21:12
  3338.                                 if(useor==FALSE){
  3339.                                         int ooutptr=outptr-2;
  3340.                                         int otok=tok;
  3341.                                         i=(unsigned char)(output[ooutptr]^1);
  3342.                                         outptr--;
  3343.                                         if(tok==tk_return){
  3344.                                                 i+=0x10;
  3345.                                         }
  3346.                                         else outptr--;
  3347.                                         AddRetList(outptr+1,linenumber,tok);
  3348.                                         if(tok2==tk_openbracket){
  3349.                                                 nexttok();
  3350.                                                 nexttok();
  3351.                                         }
  3352.                                         if(otok==tk_return){
  3353.                                                 output[ooutptr]=0x0f;
  3354.                                                 output[ooutptr+1]=i;
  3355.                                                 delta=-1;
  3356.                                         }
  3357.                                         else{
  3358.                                                 output[ooutptr]=i;
  3359.                                                 delta=(am32==TRUE?-5:-3);
  3360.                                         }
  3361.                                 }
  3362.                                 else{
  3363.                                         if(tok==tk_RETURN)output[outptr-1]-=(am32==TRUE?3:1);
  3364.                                         AddRetList(outptr+1,linenumber,tok);
  3365.                                         if(tok==tk_return&&tok2==tk_openbracket){
  3366.                                                 nexttok();
  3367.                                                 nexttok();
  3368.                                         }
  3369.                                 }
  3370.                                 nextseminext();
  3371.                                 clearregstat();
  3372. #ifdef OPTVARCONST
  3373.                                 ClearLVIC();
  3374. #endif
  3375.                         }
  3376.                         else if(tok==tk_goto||tok==tk_GOTO){
  3377.                                 int ooutptr=outptr;
  3378.                                 if(useor==FALSE){
  3379.                                         if(tok==tk_GOTO){
  3380.                                                 outptr-=2;
  3381.                                                 i=(unsigned char)(output[outptr]^1);
  3382.                                                 GOTOdo();
  3383.                                                 output[outptr-2]=i;
  3384.                                                 delta=(am32==0?-3:-5);
  3385.                                         }
  3386.                                         else{
  3387.                                                 int otok2=tok2;
  3388.                                                 gotodo();
  3389.                                                 if(output[ooutptr]==0xEB){      //áûë êîðîòêèé ïåðåõîä
  3390.                                                         outptr=ooutptr-2;
  3391.                                                         op(output[outptr]^1);
  3392.                                                         op(output[ooutptr+1]+2);
  3393.                                                         delta=(am32==0?-3:-5);
  3394.                                                 }
  3395.                                                 else if(am32&&otok2==tk_number){
  3396.                                                         outptr=ooutptr-2;
  3397.                                                         i=(unsigned char)((output[outptr]^1)+0x10);
  3398.                                                         op(0x0f);
  3399.                                                         op(i);
  3400.                                                         if(output[outptr]==0xE9)outdword(*(unsigned long *)&output[ooutptr+1]+1);
  3401.                                                         else outdword(*(unsigned short *)&output[ooutptr+2]);
  3402.                                                         delta=-1;
  3403.                                                 }
  3404.                                         }
  3405.                                 }
  3406.                                 else{   // useor
  3407.                                         if(tok==tk_goto)gotodo();
  3408.                                         else GOTOdo();
  3409.                                         if(output[ooutptr]==0xEB){      //áûë êîðîòêèé ïåðåõîä
  3410.                                                 output[ooutptr-1]-=(am32==TRUE?3:1);
  3411.                                         }
  3412.                                 }
  3413.                         }
  3414.                         else{
  3415.                                 if(useor==FALSE){
  3416.                                         int ooutptr=outptr-2;
  3417.                                         int otok=tok;
  3418.                                         i=(unsigned char)(output[ooutptr]^1);
  3419.                                         outptr--;
  3420.                                         if(tok==tk_continue)i+=0x10;
  3421.                                         else outptr--;
  3422.                                         doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32)));
  3423.                                         if(otok==tk_continue){
  3424.                                                 output[ooutptr]=0x0f;
  3425.                                                 output[ooutptr+1]=i;
  3426.                                                 delta=-1;
  3427.                                         }
  3428.                                         else{
  3429.                                                 output[ooutptr]=i;
  3430.                                                 delta=(am32==TRUE?-5:-3);
  3431.                                         }
  3432.                                 }
  3433.                                 else{
  3434.                                         if(tok==tk_CONTINUE){
  3435.                                                 output[outptr-1]-=(am32==TRUE?3:1);
  3436.                                         }
  3437.                                         doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32)));
  3438.                                 }
  3439.                         }
  3440.                         for(i=0;i<*numcomp;i++){
  3441. //                              if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]+=delta;
  3442. //                              else
  3443.                                 if((icomp+i)->type==tk_andand){
  3444.                                         if(am32==FALSE)*(signed short *)&output[(icomp+i)->loc-2]+=delta;
  3445.                                         else *(signed long *)&output[(icomp+i)->loc-4]+=delta;
  3446.                                 }
  3447.                         }
  3448.                         if(tok==tk_else||tok==tk_ELSE){
  3449.                                 notunreach=TRUE;
  3450.                                 nexttok();
  3451.                                 docommand();
  3452.                         }
  3453.                         free(icomp);
  3454.                         return NULL;
  3455.                 }
  3456.         }
  3457. endp:
  3458.         if(type!=tk_for){
  3459.                 startblock();
  3460.                 if(rcompr==zerocompr)warcompneqconst();
  3461.                 if(tok==tk_openbrace){
  3462.                         if(rcompr==zerocompr){
  3463.                                 cha=cha2;
  3464.                                 inptr=inptr2;
  3465.                                 SkipBlock();
  3466.                                 inptr2=inptr;
  3467.                                 cha2=cha;
  3468.                                 linenum2=linenumber;
  3469.                                 nexttok();
  3470.                         }
  3471.                         else{
  3472. #ifdef OPTVARCONST
  3473.                                 if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){
  3474.                                         Const2VarRec(comconst);
  3475.                                 }
  3476. #endif
  3477.                                 doblock();
  3478.                                 nexttok();
  3479.                         }
  3480.                 }
  3481.                 else{
  3482.                         if(rcompr==zerocompr){
  3483.                                 do{
  3484.                                         nexttok();
  3485.                                 }while(tok!=tk_semicolon&&tok!=tk_eof);
  3486.                         }
  3487.                         else{
  3488. #ifdef OPTVARCONST
  3489.                                 if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){
  3490.                                         Const2VarRec(comconst);
  3491.                                 }
  3492. #endif
  3493.                                 docommand();
  3494.                         }
  3495.                 }
  3496.                 endblock();
  3497.                 RestoreStack();
  3498.         }
  3499.         if(bakreg)*bakreg=bakregstat;
  3500.         if(changereg)*changereg=changeregstat;
  3501.         return icomp;
  3502. }
  3503.  
  3504. void opt_if_else_stop(unsigned int newptr)
  3505. {
  3506. unsigned int ooutptr,ooutptrdata;
  3507. unsigned char instr;
  3508.         dbgact++;
  3509.         ooutptr=outptr;
  3510.         ooutptrdata=outptrdata;
  3511.         outptr=newptr;
  3512.         instr=output[outptr];
  3513.         docommand();
  3514.         if(output[newptr]==0xEB){
  3515.                 signed char ofs=output[newptr+1];
  3516.                 if(output[newptr-1]==0x0F&&instr>=0x80&&instr<0x90){
  3517.                         ofs--;
  3518.                         if(am32)ofs-=(signed char)2;
  3519.                 }
  3520.                 if(am32)*(long *)&output[newptr+1]=ofs;
  3521.                 else*(short *)&output[newptr+1]=ofs;
  3522.         }
  3523.         if(am32&&output[newptr]==0x66&&output[newptr+1]==0xE9){
  3524.                 signed short ofs=(signed short)(*(short *)&output[newptr+2]-1);
  3525.                 *(long *)&output[newptr+1]=ofs;
  3526.         }
  3527.         output[newptr]=instr;
  3528.         outptr=ooutptr;
  3529.         outptrdata=ooutptrdata;
  3530.         dbgact--;
  3531. }
  3532.  
  3533. void doif()
  3534. {
  3535. unsigned int startloc,elseline,numcomp=0,ifline;
  3536. ICOMP *icomp;
  3537. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  3538. unsigned int oaddESP=addESP;
  3539.         ifline=linenumber;
  3540. #ifdef OPTVARCONST
  3541. LVIC comconst;
  3542.         comconst.rec=NULL;
  3543.         icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat,&comconst);
  3544. #else
  3545.         icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat);
  3546. #endif
  3547. //      i=CheckStopBlock();
  3548.         /*-----------------19.08.99 22:35-------------------
  3549.          Óáèðàòü else ìîæíî òîëüêî ïîñëå ïåðâîãî if
  3550.          Ïîñëå else if â ñëåäóþùèé else óáèðàòü íåëüçÿ
  3551.                 --------------------------------------------------*/
  3552.         if(icomp!=NULL){
  3553.                 elseline=linenumber;
  3554. unsigned long temp;
  3555. unsigned int j=0;
  3556. unsigned int otok=tok;
  3557. unsigned int oinptr=inptr2;
  3558. unsigned char ocha=cha2;
  3559. unsigned int oline=linenumber;
  3560.                 if(tok==tk_else||tok==tk_ELSE){
  3561.                         if(dbg)AddLine();
  3562.                         j=(am32==FALSE?3:5);
  3563.                         if(tok2==tk_goto||tok2==tk_break||tok2==tk_continue||//ïîãëîòèòü èõ
  3564.                                         tok2==tk_RETURN||tok2==tk_return||tok2==tk_GOTO||tok2==tk_BREAK||tok2==tk_CONTINUE){
  3565.                                 nexttok();
  3566.                                 switch(tok){
  3567.                                         case tk_GOTO: otok=tk_goto; break;
  3568.                                         case tk_BREAK: otok=tk_break; break;
  3569.                                         case tk_CONTINUE: otok=tk_continue; break;
  3570.                                         case tk_return:
  3571.                                         case tk_RETURN:
  3572.                                                 if(tok2==tk_semicolon||(tok2==tk_openbracket&&
  3573.                                                                 ScanTok3()==tk_closebracket)){
  3574.                                                         startblock();
  3575.                                                         otok=tk_return;
  3576.                                                         break;
  3577.                                                 }
  3578.                                                 tok=otok;       //íåâîçìîæíî îïòèìèçèðîâàòü
  3579.                                                 inptr2=oinptr;
  3580.                                                 cha2=ocha;
  3581.                                                 linenumber=oline;
  3582.                                                 goto nooptim;
  3583.                                         default:otok=tok; break;
  3584.                                 }
  3585.                                 oinptr=inptr2;
  3586.                                 ocha=cha2;
  3587.                                 oline=linenumber;
  3588.                                 for(unsigned int i=0;i<numcomp;i++){
  3589.                                         if((icomp+i)->type!=tk_oror){
  3590.                                                 notunreach=TRUE;
  3591.                                                 tok=otok;
  3592.                                                 inptr2=oinptr;
  3593.                                                 cha2=ocha;
  3594.                                                 linenumber=oline;
  3595.                                                 opt_if_else_stop((icomp+i)->loc-j);
  3596.                                         }
  3597.                                 }
  3598.                                 if(otok==tk_return)endblock();
  3599.                                 if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline);
  3600.                                 free(icomp);
  3601.                                 retproc=FALSE;
  3602.                                 lastcommand=tk_if;
  3603.                                 return;
  3604.                         }
  3605. nooptim:
  3606.                         if(tok==tk_ELSE)j=2;
  3607.                 }
  3608.                 notunreach=TRUE;
  3609.                 for(unsigned int i=0;i<numcomp;i++){
  3610.                         if((icomp+i)->type!=tk_oror){
  3611.                                 if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr+j-(icomp+i)->loc);
  3612.                                 else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr+j-(icomp+i)->loc);
  3613.                         }
  3614.                 }
  3615.                 if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline);
  3616.                 switch(lastcommand){
  3617.                         case tk_return:
  3618.                         case tk_RETURN:
  3619.                         case tk_goto:
  3620.                         case tk_GOTO:
  3621.                         case tk_break:
  3622.                         case tk_BREAK:
  3623.                         case tk_continue:
  3624.                         case tk_CONTINUE:
  3625.                                 addESP=oaddESP;
  3626.                                 break;
  3627.                 }
  3628.                 if(retproc)CopyRegStat(bakregstat);
  3629.                 else{
  3630.                         switch(lastcommand){
  3631.                                 case tk_return:
  3632.                                 case tk_RETURN:
  3633.                                 case tk_goto:
  3634.                                 case tk_GOTO:
  3635.                                 case tk_break:
  3636.                                 case tk_BREAK:
  3637.                                 case tk_continue:
  3638.                                 case tk_CONTINUE:
  3639.                                         CopyRegStat(bakregstat);
  3640.                                         break;
  3641.                                 default:
  3642.                                         CompareRegStat(changeregstat);
  3643.                                         break;
  3644.                         }
  3645.                 }
  3646. //              printf("lastcommand=%d\n",lastcommand);
  3647. //              CompareRegStat(changeregstat);
  3648.                 if(tok==tk_else/*&&i==FALSE*/){
  3649.                         addESP=oaddESP;
  3650.                         RestoreStack();
  3651.                         CopyRegStat(bakregstat);
  3652.                         jumploc0();
  3653.                         startloc=outptr;
  3654.                         getoperand();
  3655. #ifdef OPTVARCONST
  3656.                         if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){
  3657.                                 Const2VarRec(&comconst);
  3658.                         }
  3659. #endif
  3660.                         startblock();
  3661.                         if(tok==tk_return||tok==tk_RETURN){
  3662.                                 if(dbg)AddLine();
  3663.                                 doreturn(tok);
  3664.                         }
  3665.                         else docommand();
  3666.                         endblock();
  3667.                         RestoreStack();
  3668.                         temp=outptr-startloc;
  3669.                         if(temp<=127)warningjmp(mesELSE,elseline);
  3670.                         if(am32==FALSE)*(unsigned short *)&output[startloc-2]=(unsigned short)temp;
  3671.                         else *(unsigned long *)&output[startloc-4]=temp;
  3672.                         CompareRegStat(changeregstat);
  3673.                 }
  3674.                 else if(tok==tk_ELSE/*&&i==FALSE*/){
  3675.                         addESP=oaddESP;
  3676.                         RestoreStack();
  3677.                         CopyRegStat(bakregstat);
  3678.                         outword(0x00EB);
  3679.                         startloc=outptr;
  3680.                         getoperand();
  3681. #ifdef OPTVARCONST
  3682.                         if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){
  3683.                                 Const2VarRec(&comconst);
  3684.                         }
  3685. #endif
  3686.                         startblock();
  3687.                         if(tok==tk_return||tok==tk_RETURN){
  3688.                                 if(dbg)AddLine();
  3689.                                 doreturn(tok);
  3690.                         }
  3691.                         else docommand();
  3692.                         endblock();
  3693.                         RestoreStack();
  3694.                         temp=outptr-startloc;
  3695.                         if(temp>127)jumperror(elseline,mesELSE);
  3696.                         output[startloc-1]=(unsigned char)temp;
  3697.                         CompareRegStat(changeregstat);
  3698.                 }
  3699. /*              else{
  3700.                 if(i!=FALSE&&(tok==tk_else||tok==tk_ELSE))nexttok();
  3701.                 }*/
  3702.                 free(icomp);
  3703.                 CopyRegStat(changeregstat);
  3704.         }
  3705.         FreeStat(bakregstat);
  3706.         FreeStat(changeregstat);
  3707.         retproc=FALSE;
  3708.         lastcommand=tk_if;
  3709. }
  3710.  
  3711. #ifdef OPTVARCONST
  3712. ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst)
  3713. #else
  3714. ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg)
  3715. #endif
  3716. {
  3717. unsigned int ifline;
  3718. ICOMP *icomp;
  3719. unsigned int i=0;
  3720. int j=0;
  3721. int ptok=tk_oror;
  3722. int rcompr;
  3723. int useor=FALSE;
  3724. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  3725.         if(am32!=FALSE)j=2;
  3726.         icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF);     //áëîê äëÿ èíôî î ñðàâíåíèÿõ
  3727.         ifline=linenumber;
  3728.         do{
  3729. #ifdef OPTVARCONST
  3730.                 if((rcompr=constructcompare(1,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1;
  3731. #else
  3732.                 if((rcompr=constructcompare(1,outptr))==voidcompr||rcompr==zerocompr)i=1;
  3733. #endif
  3734.                 (icomp+*numcomp)->use_cxz=rcompr&0xFC;
  3735.                 if(i){
  3736.                         if(rcompr==voidcompr&&ptok==tk_andand){
  3737.                                 i=0;
  3738.                                 ptok=tok;
  3739.                         }
  3740.                         continue;
  3741.                 }
  3742.                 op(0x00);
  3743.                 (icomp+*numcomp)->loc=outptr;
  3744.                 (icomp+*numcomp)->type=tok;
  3745.                 (*numcomp)++;
  3746.                 if(*numcomp==MAXIF){
  3747.                         ManyLogicCompare();
  3748.                         free(icomp);
  3749.                         return NULL;
  3750.                 }
  3751.                 ptok=tok;
  3752. /*              if(tok==tk_andand&&bakregstat==NULL){
  3753.                         bakregstat=BakRegStat();
  3754.                         changeregstat=BakRegStat();
  3755.                 }*/
  3756.         }while(tok==tk_oror||tok==tk_andand);
  3757.         if(tok==tk_closebracket)nexttok();
  3758.         for(i=0;i<*numcomp;i++){
  3759.                 if(outptr-(icomp+i)->loc>127)CompareOr();
  3760.                 output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  3761.                 if((icomp+i)->type==tk_oror){
  3762. #ifdef OPTVARCONST
  3763.                         if(comconst)comconst->rec=NULL;
  3764. #endif
  3765.                         output[(icomp+i)->loc-2]=(unsigned char)(output[(icomp+i)->loc-2]^1);
  3766.                         clearregstat();
  3767.                         useor=TRUE;
  3768.                 }
  3769.         }
  3770.         if(bakregstat==NULL){
  3771.                 bakregstat=BakRegStat();
  3772.                 changeregstat=BakRegStat();
  3773.         }
  3774.         if(type==tk_IF&&rcompr!=zerocompr){
  3775.                 if(rcompr==voidcompr)warcompeqconst();
  3776.                 if(tok==tk_return||tok==tk_RETURN){
  3777.                         if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){
  3778.                                 if(insertmode||(!optimizespeed)){
  3779.                                         if(tok==tk_RETURN)goto merge_if;
  3780.                                         else if(chip>2&&(insertmode||(paramsize&&
  3781.                                                         (current_proc_type&f_typeproc)!=tp_cdecl)))goto merge_if2;
  3782.                                 }
  3783.                         }
  3784.                         startblock();
  3785.                         doreturn(tok);
  3786.                         endblock();
  3787.                         for(unsigned int i=0;i<*numcomp;i++){
  3788.                                 if((icomp+i)->type!=tk_oror){
  3789.                                         if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF);
  3790.                                         output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  3791.                                 }
  3792.                         }
  3793.                         if(tok==tk_else||tok==tk_ELSE){
  3794.                                 notunreach=TRUE;
  3795.                                 getoperand();
  3796.                                 docommand();
  3797.                         }
  3798.                         free(icomp);
  3799.                         return NULL;
  3800.                 }
  3801.                 if(tok==tk_BREAK||tok==tk_CONTINUE||tok==tk_GOTO){
  3802. merge_if:
  3803.                         int otok=tok;
  3804.                         for(i=0;i<*numcomp;i++){
  3805.                                 unsigned char oldcode;
  3806.                                 if(((icomp+i)->type==tk_oror)||((i+1)==*numcomp)){
  3807.                                         outptr=(icomp+i)->loc-2;
  3808.                                         oldcode=output[outptr];
  3809.                                         if(tok==tk_BREAK)MakeBreak(BREAK_SHORT);
  3810.                                         else if(tok==tk_RETURN){
  3811.                                                 AddRetList(outptr+1,ifline,tk_RETURN);
  3812.                                                 clearregstat();
  3813. #ifdef OPTVARCONST
  3814.                                                 ClearLVIC();
  3815. #endif
  3816.                                         }
  3817.                                         else if(tok==tk_GOTO){
  3818.                                                 if((i+1)!=*numcomp){
  3819.                                                         int optr,ocha,oline;
  3820.                                                         optr=inptr2;
  3821.                                                         ocha=cha2;
  3822.                                                         oline=linenum2;
  3823.                                                         GOTOdo();
  3824.                                                         if(outptr!=(icomp+i)->loc)jumperror(oline,"GOTO");
  3825.                                                         inptr2=optr;
  3826.                                                         cha2=(unsigned char)ocha;
  3827.                                                         linenum2=oline;
  3828.                                                         tok=tk_GOTO;
  3829.                                                 }
  3830.                                                 else{
  3831.                                                         getoperand();
  3832.                                                         CheckIP();
  3833.                                                         if(tok==tk_number||tok==tk_interruptproc||tok==tk_proc){
  3834.                                                                 long hnumber;
  3835.                                                                 if(tok==tk_number)hnumber=doconstdwordmath();
  3836.                                                                 else{
  3837.                                                                         hnumber=itok.number;
  3838.                                                                         nexttok();
  3839.                                                                 }
  3840.                                                                 long loc=hnumber-outptr-2;
  3841.                                                                 if(loc>-129&&loc<128){
  3842.                                                                         op((unsigned char)(oldcode^1));
  3843.                                                                         op(loc);
  3844.                                                                 }
  3845.                                                                 else{
  3846.                                                                         loc-=3;
  3847.                                                                         outptr++;
  3848.                                                                         op(am32==0?3:5);
  3849.                                                                         op(0xE9);
  3850.                                                                         if(am32==FALSE)outword(loc);
  3851.                                                                         else{
  3852.                                                                                 loc-=2;
  3853.                                                                                 outdword(loc);
  3854.                                                                         }
  3855.                                                                 }
  3856.                                                                 seminext();
  3857.                                                                 break;
  3858.                                                         }
  3859.                                                         else if(GOTO())nexttok();
  3860.                                                         seminext();
  3861.                                                 }
  3862.                                         }
  3863.                                         else MakeContinue(CONTINUE_SHORT);
  3864.                                         if((i+1)==*numcomp)oldcode^=1;
  3865.                                         output[outptr-2]=oldcode;
  3866.                                 }
  3867.                         }
  3868.                         if(tok==tk_RETURN&&tok2==tk_openbracket){
  3869.                                 nexttok();
  3870.                                 nexttok();
  3871.                         }
  3872.                         if(otok!=tk_GOTO&&rcompr!=voidcompr)nextseminext();
  3873.  
  3874.                         if(tok==tk_else||tok==tk_ELSE){
  3875.                                 notunreach=TRUE;
  3876.                                 getoperand();
  3877.                                 docommand();
  3878.                         }
  3879.                         free(icomp);
  3880.                         return NULL;
  3881.                 }
  3882.                 if((tok==tk_break||tok==tk_continue||tok==tk_goto)&&chip>2){
  3883. merge_if2:
  3884.  
  3885. //                      printf("%s (%u) %s %s tok=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,itok.name,string,tok);
  3886.  
  3887.                         if(*numcomp==1&&(!(tok==tk_goto&&(tok2==tk_reg||tok2==tk_reg32)))){
  3888.                                 outptr-=2;
  3889.                                 i=(output[outptr]^1)+0x10;
  3890.                                 op(0x0F);
  3891.                         }
  3892.                         if(tok==tk_break)doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32));
  3893.                         else if(tok==tk_return){
  3894.                                 AddRetList(outptr+1,ifline,tk_return);
  3895.                                 if(tok2==tk_openbracket){
  3896.                                         nexttok();
  3897.                                         nexttok();
  3898.                                 }
  3899.                                 nextseminext();
  3900.                                 clearregstat();
  3901. #ifdef OPTVARCONST
  3902.                                 ClearLVIC();
  3903. #endif
  3904.                         }
  3905.                         else if(tok==tk_goto){
  3906.                                 nexttok();
  3907.                                 CheckIP();
  3908.                                 if((tok==tk_number&&*numcomp==1)||tok==tk_interruptproc||tok==tk_proc){
  3909.                                         if(tok==tk_proc&&tok2==tk_openbracket)doanyproc(TRUE);
  3910.                                         else{
  3911.                                                 long hnumber;
  3912.                                                 if(tok==tk_number)hnumber=doconstdwordmath();
  3913.                                                 else{
  3914.                                                         hnumber=itok.number;
  3915.                                                         nexttok();
  3916.                                                 }
  3917.                                                 long loc=hnumber-outptr-2;
  3918.                                                 if(loc>-130&&loc<127){
  3919.                                                         outptr--;
  3920.                                                         op((unsigned char)(i-0x10));
  3921.                                                         op(loc+1);
  3922.                                                         seminext();
  3923.                                                         goto c1;
  3924.                                                 }
  3925.                                                 else{
  3926.                                                         loc--;
  3927.                                                         op(0xE9);
  3928.                                                         if(am32==FALSE)outword(loc);
  3929.                                                         else{
  3930.                                                                 loc-=2;
  3931.                                                                 outdword(loc);
  3932.                                                         }
  3933.                                                 }
  3934.                                         }
  3935.                                 }
  3936.                                 else{
  3937.                                         if(tok==tk_reg||tok==tk_reg32){
  3938.                                                 i=outptr;
  3939.                                                 if(gotol(0))nexttok();
  3940.                                                 i=outptr-i;
  3941.                                                 output[outptr-i-1]=(unsigned char)i;
  3942.                                                 goto c1;
  3943.                                         }
  3944.                                         if(gotol(0))nexttok();
  3945.                                 }
  3946.                                 seminext();
  3947.                         }
  3948.                         else doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32));
  3949.                         if(*numcomp==1)output[outptr-3-j]=(unsigned char)i;
  3950. c1:
  3951.                         if(cpu<3)cpu=3;
  3952.                         if(tok==tk_else||tok==tk_ELSE){
  3953.                                 notunreach=TRUE;
  3954.                                 getoperand();
  3955.                                 docommand();
  3956.                         }
  3957.                         if(*numcomp!=1){
  3958.                                 for(unsigned int i=0;i<*numcomp;i++){
  3959.                                         if((icomp+i)->type!=tk_oror){
  3960.                                                 if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF);
  3961.                                                 output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  3962.                                         }
  3963.                                 }
  3964.                         }
  3965.                         free(icomp);
  3966.                         return NULL;
  3967.                 }
  3968.         }
  3969.         if((icomp+(*numcomp-1))->use_cxz==cxnzcompr){
  3970.                 outptr-=4;
  3971.                 outword(0xE3);
  3972.                 (icomp+(*numcomp-1))->loc=outptr;
  3973.                 for(i=(*numcomp-1);i!=0;i--){
  3974.                         if((icomp+i-1)->type==tk_oror)output[(icomp+i-1)->loc-1]-=(unsigned char)2;
  3975.                 }
  3976.         }
  3977.         if(type!=tk_FOR){
  3978.                 startblock();
  3979.                 if(rcompr==zerocompr)warcompneqconst();
  3980.                 if(tok==tk_openbrace){
  3981.                         if(rcompr==zerocompr){
  3982.                                 cha=cha2;
  3983.                                 inptr=inptr2;
  3984.                                 SkipBlock();
  3985.                                 inptr2=inptr;
  3986.                                 cha2=cha;
  3987.                                 linenum2=linenumber;
  3988.                                 nexttok();
  3989.                         }
  3990.                         else{
  3991. #ifdef OPTVARCONST
  3992.                                 if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst);
  3993. #endif
  3994.                                 doblock();
  3995.                                 nexttok();
  3996.                         }
  3997.                 }
  3998.                 else{
  3999.                         if(rcompr==zerocompr){
  4000.                                 do{
  4001.                                         nexttok();
  4002.                                 }while(tok!=tk_semicolon&&tok!=tk_eof);
  4003.                         }
  4004.                         else{
  4005. #ifdef OPTVARCONST
  4006.                                 if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst);
  4007. #endif
  4008.                                 docommand();
  4009.                         }
  4010.                 }
  4011.                 endblock();
  4012.                 RestoreStack();
  4013.         }
  4014.         if(bakreg)*bakreg=bakregstat;
  4015.         if(changereg)*changereg=changeregstat;
  4016.         return icomp;
  4017. }
  4018.  
  4019. void dobigif()
  4020. {
  4021. unsigned int ifline,numcomp=0,j=0;
  4022. ICOMP *icomp;
  4023. int ic;
  4024. unsigned int oaddESP=addESP;
  4025. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  4026.         ifline=linenumber;
  4027. #ifdef OPTVARCONST
  4028. LVIC comconst;
  4029.         comconst.rec=NULL;
  4030.         icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat,&comconst);
  4031. #else
  4032.         icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat);
  4033. #endif
  4034.         if(icomp!=NULL){
  4035.                 unsigned int elseline;
  4036.                 elseline=linenumber;
  4037.                 if(tok==tk_else)j=(am32==FALSE?3:5);
  4038.                 else if(tok==tk_ELSE)j=2;
  4039.                 notunreach=TRUE;
  4040.                 if(dbg)AddLine();
  4041.                 for(unsigned int i=0;i<numcomp;i++){
  4042.                         if((icomp+i)->type!=tk_oror){
  4043.                                 if((outptr+j-(icomp+i)->loc)>127)jumperror(ifline,mesIF);
  4044.                                 output[(icomp+i)->loc-1]=(unsigned char)(outptr+j-(icomp+i)->loc);
  4045.                         }
  4046.                 }
  4047.                 switch(lastcommand){
  4048.                         case tk_return:
  4049.                         case tk_RETURN:
  4050.                         case tk_goto:
  4051.                         case tk_GOTO:
  4052.                         case tk_break:
  4053.                         case tk_BREAK:
  4054.                         case tk_continue:
  4055.                         case tk_CONTINUE:
  4056.                                 addESP=oaddESP;
  4057.                                 break;
  4058.                 }
  4059.                 if(retproc)CopyRegStat(bakregstat);
  4060.                 else{
  4061.                         switch(lastcommand){
  4062.                                 case tk_return:
  4063.                                 case tk_RETURN:
  4064.                                 case tk_goto:
  4065.                                 case tk_GOTO:
  4066.                                 case tk_break:
  4067.                                 case tk_BREAK:
  4068.                                 case tk_continue:
  4069.                                 case tk_CONTINUE:
  4070.                                         CopyRegStat(bakregstat);
  4071.                                         break;
  4072.                                 default:
  4073.                                         CompareRegStat(changeregstat);
  4074.                                         break;
  4075.                         }
  4076. //                      CompareRegStat(changeregstat);
  4077.                 }
  4078.                 if(tok==tk_else/*&&i==FALSE*/){
  4079.                         addESP=oaddESP;
  4080.                         RestoreStack();
  4081.                         CopyRegStat(bakregstat);
  4082.                         jumploc0();
  4083.                         ic = outptr;
  4084.                         getoperand();
  4085. #ifdef OPTVARCONST
  4086.                         if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst);
  4087. #endif
  4088.                         startblock();
  4089.                         if(tok==tk_return||tok==tk_RETURN){
  4090.                                 if(dbg)AddLine();
  4091.                                 doreturn(tok);
  4092.                         }
  4093.                         else docommand();
  4094.                         endblock();
  4095.                         RestoreStack();
  4096.                         if((outptr-ic)<=127)warningjmp(mesELSE,elseline);
  4097.                         if(am32==FALSE)*(unsigned short *)&output[ic-2]=(unsigned short)(outptr-ic);
  4098.                         else *(unsigned long *)&output[ic-4]=(unsigned long)(outptr-ic);
  4099.                         CompareRegStat(changeregstat);
  4100.                 }
  4101.                 else if(tok==tk_ELSE/*&&ic==FALSE*/){
  4102.                         addESP=oaddESP;
  4103.                         RestoreStack();
  4104.                         CopyRegStat(bakregstat);
  4105.                         outword(0x00EB);
  4106.                         ic=outptr;
  4107.                         getoperand();
  4108. #ifdef OPTVARCONST
  4109.                         if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst);
  4110. #endif
  4111.                         startblock();
  4112.                         if(tok==tk_return||tok==tk_RETURN){
  4113.                                 if(dbg)AddLine();
  4114.                                 doreturn(tok);
  4115.                         }
  4116.                         else docommand();
  4117.                         endblock();
  4118.                         RestoreStack();
  4119.                         if((outptr-ic)>127)jumperror(elseline,mesELSE);
  4120.                         output[ic-1]=(unsigned char)(outptr-ic);
  4121.                         CompareRegStat(changeregstat);
  4122.                 }
  4123.                 free(icomp);
  4124.                 CopyRegStat(changeregstat);
  4125.         }
  4126.         FreeStat(bakregstat);
  4127.         FreeStat(changeregstat);
  4128.         retproc=FALSE;
  4129.         lastcommand=tk_IF;
  4130. }
  4131.  
  4132. void JXorJMP()
  4133. {
  4134.         if(chip<3){
  4135.                 op(0xE9);
  4136.         }
  4137.         else{
  4138.                 unsigned char i;
  4139.                 outptr-=2;
  4140.                 i=(unsigned char)((output[outptr]^1)+0x10);
  4141.                 op(0x0F); op(i);
  4142.                 if(cpu<3)cpu=3;
  4143.         }
  4144. }
  4145.  
  4146. void dowhile(unsigned int typeb)
  4147. {
  4148. unsigned int ifline,conloc,numcomp=0;
  4149. ICOMP *icomp;
  4150. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  4151.         uptdbr();
  4152.         if(AlignCycle)AlignCD(CS,aligncycle);
  4153.         conloc=outptr;
  4154.         ifline=linenumber;
  4155.         if(typeb==tk_while)
  4156. #ifdef OPTVARCONST
  4157.                         icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL);
  4158. #else
  4159.                         icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat);
  4160. #endif
  4161.         else
  4162. #ifdef OPTVARCONST
  4163.                         icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL);
  4164. #else
  4165.                         icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat);
  4166. #endif
  4167.         SetContinueLabel();
  4168.         jumploc(conloc);
  4169.         if(icomp!=NULL){
  4170.                 if(typeb==tk_WHILE){
  4171.                         for(unsigned int i=0;i<numcomp;i++){
  4172.                                 if((icomp+i)->type!=tk_oror){
  4173.                                         if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesWHILE);
  4174.                                         output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  4175.                                 }
  4176.                         }
  4177.                 }
  4178.                 else{
  4179.                         for(unsigned int i=0;i<numcomp;i++){
  4180.                                 if((icomp+i)->type!=tk_oror){
  4181.                                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc);
  4182.                                         else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc);
  4183.                                 }
  4184.                         }
  4185.                         if((outptr-icomp->loc)<=127)warningjmp(mesWHILE,ifline);
  4186.                 }
  4187.                 free(icomp);
  4188.         }
  4189.         if(retproc){
  4190.                 if(bakregstat)CopyRegStat(bakregstat);
  4191.         }
  4192.         else if(changeregstat)CompareRegStat(changeregstat);
  4193.         if(changeregstat)CopyRegStat(changeregstat);
  4194.         SetBreakLabel();
  4195.         if(usebr[curbr]!=0)clearregstat();
  4196.         FreeStat(bakregstat);
  4197.         FreeStat(changeregstat);
  4198. #ifdef OPTVARCONST
  4199.         ClearLVIC();
  4200. #endif
  4201.         lastcommand=tk_do;
  4202. }
  4203.  
  4204. void dowhilefast(unsigned int typeb)
  4205. {
  4206. unsigned int numcomp=0;
  4207. unsigned int startloc,i;
  4208. ICOMP *icomp;
  4209. ITOK oitok,ostructadr;
  4210. SINFO ostr;
  4211. unsigned int oldinptr;
  4212. int otok,otok2;
  4213. char *ostring,*obufrm;
  4214. int blinenum,olinenum,oinptr;
  4215. char *ostartline,*bstartline;
  4216. char ocha,bcha;
  4217. int jmptocompr=0;
  4218. int rcompr;
  4219. unsigned char *oinput;
  4220. unsigned int oaddESP=addESP;
  4221.         ocha=cha2;
  4222.         oinptr=inptr2;
  4223.         olinenum=linenumber;
  4224.         ostartline=startline;
  4225.         clearregstat();
  4226. #ifdef OPTVARCONST
  4227.         ClearLVIC();
  4228. #endif
  4229.         do{
  4230.                 nexttok();
  4231.                 if(tok2==tk_openbracket)nexttok();
  4232.                 if(tok2==tk_closebracket){
  4233.                         nexttok();
  4234.                         jmptocompr=1;
  4235.                         break;
  4236.                 }
  4237.                 if(tok2==tk_number){
  4238.                         nexttok();
  4239.                         if(tok2==tk_closebracket){
  4240.                                 if(itok.number!=0)jmptocompr=1;
  4241.                                 else jmptocompr=2;
  4242.                                 nexttok();
  4243.                                 break;
  4244.                         }
  4245.                 }
  4246.                 nexttok();      //íåîáõîäèìî äëÿ èçáåæàíèÿ ïðåäóïðåæäåíèÿ î íåèíèöèàëèçèðîâàííîé ïåðåìåííîé
  4247.                 cha=cha2;
  4248.                 inptr=inptr2;
  4249.                 SkipParam();
  4250.                 inptr2=inptr;
  4251.                 cha2=cha;
  4252.                 linenum2=linenumber;
  4253.                 nexttok();
  4254.                 if(typeb==tk_while&&tok==tk_oror&&optimizespeed==0){
  4255.                         cha2=ocha;
  4256.                         inptr2=oinptr;
  4257.                         linenumber=linenum2=olinenum;
  4258.                         startline=ostartline;
  4259.                         dowhile(typeb);
  4260.                         if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  4261.                         return;
  4262.                 }
  4263.                 if(bufrm){
  4264.                         free(bufrm);
  4265.                         bufrm=NULL;
  4266.                 }
  4267.                 if(strinf.bufstr){
  4268.                         free(strinf.bufstr);
  4269.                         strinf.bufstr=NULL;
  4270.                 }
  4271.         }while(tok==tk_andand||tok==tk_oror);
  4272.         while(tok==tk_closebracket)nexttok();
  4273.         if(!jmptocompr){
  4274.                 if(typeb==tk_WHILE)outword(0x00EB);     // JMP SHORT
  4275.                 else jumploc0();
  4276.         }
  4277.         i=outptr;
  4278.         if(AlignCycle)AlignCD(CS,aligncycle);
  4279.         startloc=outptr;
  4280.         uptdbr();
  4281.         if(tok!=tk_openbrace){
  4282.                 if(jmptocompr==2){
  4283.                         do{
  4284.                                 nexttok();
  4285.                         }while(tok!=tk_semicolon&&tok!=tk_eof);
  4286.                 }
  4287.                 else docommand();
  4288.         }
  4289.         else{
  4290.                 if(jmptocompr==2){
  4291.                         cha=cha2;
  4292.                         inptr=inptr2;
  4293.                         SkipBlock();
  4294.                         inptr2=inptr;
  4295.                         cha2=cha;
  4296.                         linenum2=linenumber;
  4297.                         nexttok();
  4298.                 }
  4299.                 else{
  4300.                         startblock();
  4301.                         doblock();
  4302.                         nexttok();
  4303.                         endblock();
  4304.                 }
  4305.         }
  4306.         RestoreStack();
  4307.         if(!jmptocompr){
  4308.                 if(typeb==tk_WHILE){
  4309.                         if(i!=outptr){
  4310.                                 if((outptr-i)>127)jumperror(olinenum,mesWHILE);
  4311.                                 output[i-1]=(unsigned char)(outptr-i);
  4312.                         }
  4313.                         else{
  4314.                                 if(dbg&1)KillLastLine();
  4315.                                 outptr-=2;
  4316.                                 startloc-=2;
  4317.                         }
  4318.                 }
  4319.                 else{
  4320.                         if(i!=outptr){
  4321.                                 if((outptr-i)<=127)warningjmp(mesWHILE,olinenum);
  4322.                                 if(am32) *(unsigned long *)&output[i-4]=(unsigned long)(outptr-i);
  4323.                                 else *(unsigned short *)&output[i-2]=(unsigned short)(outptr-i);
  4324.                         }
  4325.                         else{
  4326.                                 i=3;
  4327.                                 if(am32)i+=2;
  4328.                                 if(dbg){
  4329.                                         KillLastLine();
  4330.                                         KillLastLine();
  4331.                                 }
  4332.                                 outptr-=i;
  4333.                                 startloc-=i;
  4334.                         }
  4335.                 }
  4336.         }
  4337.         SetContinueLabel();
  4338.         clearregstat();    //06.09.04 21:56
  4339. #ifdef OPTVARCONST
  4340.         ClearLVIC();
  4341. #endif
  4342.         icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF);     //áëîê äëÿ èíôî î ñðàâíåíèÿõ
  4343. //      oitok2=itok2;
  4344.  
  4345.         ostring=BackString((char *)string);
  4346.         oldinptr=inptr2;
  4347.         oinput=input;
  4348.         bcha=cha2;
  4349.         otok=tok;
  4350.         otok2=tok2;
  4351.         oitok=itok;
  4352.         ostructadr=structadr;
  4353.         ostr=strinf;
  4354.         strinf.bufstr=NULL;
  4355.         obufrm=bufrm;
  4356.         int oldendinptr=endinptr;
  4357. COM_MOD *tempcurmod=cur_mod;
  4358.         if(cur_mod)BackMod();
  4359.  
  4360.         bufrm=NULL;
  4361.         blinenum=linenum2;
  4362.         inptr2=oinptr;
  4363.         cha2=ocha;
  4364.         linenumber=linenum2=olinenum;
  4365.         bstartline=startline;
  4366.         startline=ostartline;
  4367.  
  4368.         if(dbg)AddLine();
  4369.         int ptok=tk_oror;
  4370.         do{
  4371.                 i=0;
  4372. #ifdef OPTVARCONST
  4373.                 if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1;
  4374. #else
  4375.                 if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1;
  4376. #endif
  4377.                 if(i){
  4378.                         if(ptok==tk_andand){
  4379. //                              i=0;
  4380.                                 ptok=tok;
  4381.                         }
  4382.                         continue;
  4383.                 }
  4384.                 if((rcompr&1)){;
  4385.                         op(0x03);
  4386.                         if(tok!=tk_andand){
  4387.                                 JXorJMP();
  4388.                                 if(am32==FALSE)outword(startloc-(outptr+2));
  4389.                                 else outdword(startloc-(outptr+4));
  4390.                         }
  4391.                 }
  4392.                 else{
  4393.                         op(startloc-(outptr+1));                 /* the small jump */
  4394.                         if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1);
  4395.                 }
  4396.                 (icomp+numcomp)->loc=outptr;
  4397.                 (icomp+numcomp)->type=tok;
  4398.                 numcomp++;
  4399.                 if(numcomp==MAXIF){
  4400.                         ManyLogicCompare();
  4401.                         break;
  4402.                 }
  4403.                 ptok=tok;
  4404.         }while(tok==tk_oror||tok==tk_andand);
  4405.         if(jmptocompr==1)jumploc(startloc);
  4406.  
  4407.         startline=bstartline;
  4408.         strinf=ostr;
  4409.         inptr2=oldinptr;
  4410.         input=oinput;
  4411.         endinptr=oldendinptr;
  4412.         cha2=bcha;
  4413.         tok=otok;
  4414.         itok=oitok;
  4415.         structadr=ostructadr;
  4416.         bufrm=obufrm;
  4417.         tok2=otok2;
  4418.         cur_mod=tempcurmod;
  4419.         strcpy((char *)string,ostring);
  4420.         free(ostring);
  4421.         linenumber=linenum2=blinenum;
  4422.         itok2=oitok;
  4423.  
  4424.         for(i=0;i<numcomp;i++){
  4425.                 if((icomp+i)->type==tk_andand){
  4426.                         if(outptr-(icomp+i)->loc>127)CompareOr();
  4427.                         output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  4428.                 }
  4429.         }
  4430.         if(rcompr==cxzcompr){
  4431.                 outptr-=4;
  4432.                 op(0xE3);
  4433.                 op(startloc-outptr-1);
  4434.                 for(i=(numcomp-1);i!=0;i--){
  4435.                         if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2;
  4436.                 }
  4437.         }
  4438.         SetBreakLabel();
  4439.         clearregstat();
  4440. #ifdef OPTVARCONST
  4441.         ClearLVIC();
  4442. #endif
  4443.         free(icomp);
  4444.         if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  4445.         lastcommand=tk_do;
  4446. }
  4447.  
  4448. void dodo()
  4449. {
  4450. unsigned int startloc,numcomp=0,i=0;
  4451. ICOMP *icomp;
  4452. int ptok=tk_oror;
  4453. int rcompr;
  4454. unsigned int oaddESP=addESP;
  4455.         nexttok();
  4456.         if(AlignCycle)AlignCD(CS,aligncycle);
  4457.         startloc=outptr;
  4458.         uptdbr();
  4459.         if(dbg&1)KillLastLine();
  4460.         clearregstat();
  4461. #ifdef OPTVARCONST
  4462.         ClearLVIC();
  4463. #endif
  4464.         docommand();
  4465.         SetContinueLabel();
  4466.         if(dbg)AddLine();
  4467.         if(tok!=tk_while)preerror("'while' expected following 'do'");
  4468.         icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF);     //áëîê äëÿ èíôî î ñðàâíåíèÿõ
  4469.         do{
  4470. #ifdef OPTVARCONST
  4471.                 if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1;
  4472. #else
  4473.                 if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1;
  4474. #endif
  4475.                 if(i){
  4476.                         if(ptok==tk_andand){
  4477.                                 i=0;
  4478.                                 ptok=tok;
  4479.                         }
  4480.                         continue;
  4481.                 }
  4482.                 if((rcompr&1)){;
  4483.                         op(0x03);
  4484.                         if(tok!=tk_andand){
  4485.                                 JXorJMP();
  4486.                                 if(am32==FALSE)outword(startloc-(outptr+2));
  4487.                                 else outdword(startloc-(outptr+4));
  4488.                         }
  4489.                 }
  4490.                 else{
  4491.                         op(startloc-(outptr+1));                 /* the small jump */
  4492.                         if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1);
  4493.                 }
  4494.                 (icomp+numcomp)->loc=outptr;
  4495.                 (icomp+numcomp)->type=tok;
  4496.                 numcomp++;
  4497.                 if(numcomp==MAXIF){
  4498.                         ManyLogicCompare();
  4499.                         goto end;
  4500.                 }
  4501.                 ptok=tok;
  4502.         }while(tok==tk_oror||tok==tk_andand);
  4503.         if(i)jumploc(startloc);
  4504.         if(tok==tk_closebracket)nexttok();
  4505.         for(i=0;i<numcomp;i++){
  4506.                 if((icomp+i)->type==tk_andand){
  4507.                         if(outptr-(icomp+i)->loc>127)CompareOr();
  4508.                         output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  4509.                 }
  4510.         }
  4511.         if(rcompr==cxzcompr){
  4512.                 outptr-=4;
  4513.                 op(0xE3);
  4514.                 op(startloc-outptr-1);
  4515.                 for(i=(numcomp-1);i!=0;i--){
  4516.                         if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2;
  4517.                 }
  4518.         }
  4519.         seminext();
  4520.         SetBreakLabel();
  4521.         if(usebr[curbr]!=0||useco[curco]!=0)clearregstat();
  4522. end:
  4523. #ifdef OPTVARCONST
  4524.         ClearLVIC();
  4525. #endif
  4526.         free(icomp);
  4527.         if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  4528.         lastcommand=tk_do;
  4529. }
  4530.  
  4531. void dofor(unsigned int typeb)
  4532. {
  4533. unsigned int ifline,conloc,blinenum,numcomp=0;
  4534. unsigned char bcha;
  4535. unsigned char COMPARE=FALSE,modif=FALSE;
  4536. int i;
  4537. unsigned char *buf;
  4538. unsigned int oaddESP=addESP;
  4539. ICOMP *icomp=NULL;
  4540. REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL;
  4541.         ifline=linenumber;
  4542. //      printf("start for, curco=%u curbr=%u\n",curco,curbr);
  4543.         uptdbr();
  4544.         nexttok();
  4545.         i=inptr2;
  4546.         bcha=cha2;
  4547.         expecting(tk_openbracket);      //ïðîâ íà îòêð ñêîáêó
  4548.         if(tok!=tk_semicolon){  //ÅÑÒÜ ÏÐÅÄÂÀÐÈÒÅËÜÍÛÅ ÓÑÒÀÍÎÂÊÈ
  4549.                 for(;;){        //çàïèñàòü èõ â áóôåð
  4550.                         AddBackBuf(i,bcha);
  4551.                         if(tok==tk_semicolon)break;
  4552.                         if(tok!=tk_camma){
  4553.                                 expecting(tk_semicolon);
  4554.                                 break;
  4555.                         }
  4556.                         i=inptr2;
  4557.                         bcha=cha2;
  4558.                         nexttok();
  4559.                 }
  4560.                 if(bufrm){
  4561.                         free(bufrm);
  4562.                         bufrm=NULL;
  4563.                 }
  4564.                 if(strinf.bufstr){
  4565.                         free(strinf.bufstr);
  4566.                         strinf.bufstr=NULL;
  4567.                 }
  4568.                 CharToBackBuf('}');
  4569.                 CharToBackBuf(0);
  4570.                 RunBackText();  //âûïîëíèòü åãî
  4571.         }
  4572.         clearregstat();
  4573. #ifdef OPTVARCONST
  4574.         ClearLVIC();
  4575. #endif
  4576.         bcha=cha2;
  4577.         i=inptr2;
  4578.         nexttok();
  4579.         if(AlignCycle)AlignCD(CS,aligncycle);
  4580.         conloc=outptr;  //çàïîìíèòü òî÷êó íà÷àëà öèêëà
  4581.  
  4582.         if(tok!=tk_semicolon){  //åñëè åñòü óñëîâèå
  4583.                 if(tok!=tk_openbracket){        //åñëè óñëîâèå íà÷èíàåòñÿ íå ñ (
  4584.                         CharToBackBuf('(');     //äîáàâèòü åå
  4585.                         COMPARE=TRUE;   //è ôëàã óñòàíîâèòü
  4586.                 }
  4587.                 AddBackBuf(i,bcha);     //çàïîìíèòü óñëîâèå
  4588.                 if(tok!=tk_semicolon)expected(';');
  4589.                 SizeBackBuf--;
  4590.                 if(COMPARE)CharToBackBuf(')');  //åñëè íàäî, çàêðûòü ñêîáêó
  4591.                 CharToBackBuf(0);
  4592.                 int oendinptr=endinptr;
  4593.                 endinptr=SizeBackBuf-1;//strlen(BackTextBlock);
  4594.                 i=inptr2;
  4595.                 buf=input;
  4596.                 bcha=cha2;
  4597.                 input=(unsigned char *)BackTextBlock;
  4598.                 SizeBackBuf=0;
  4599.                 inptr2=1;
  4600.                 cha2='(';
  4601.                 if(typeb==tk_for)
  4602. #ifdef OPTVARCONST
  4603.                                 icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL);
  4604. #else
  4605.                                 icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat);
  4606. #endif
  4607.                 else
  4608. #ifdef OPTVARCONST
  4609.                                 icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL);
  4610. #else
  4611.                                 icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat);
  4612. #endif
  4613.                 free(input);
  4614.                 input=buf;
  4615.                 inptr2=i;
  4616.                 cha2=bcha;
  4617.                 endinptr=oendinptr;
  4618.                 COMPARE=TRUE;
  4619.                 nexttok();
  4620.         }
  4621.         else{
  4622.                 i=inptr2;
  4623.                 bcha=cha2;
  4624.                 nexttok();
  4625.         }
  4626.  
  4627.         if(tok!=tk_closebracket){       //åñòü ìîäèôèêàöèÿ
  4628.                 modif=TRUE;
  4629.                 while(tok!=tk_closebracket){
  4630.                         AddBackBuf(i,bcha);
  4631.                         if(cha==')'||cha==26){
  4632.                                 CharToBackBuf(';');
  4633.                                 nextchar();
  4634.                                 cha2=cha;
  4635.                                 inptr2=inptr;
  4636.                                 break;
  4637.                         }
  4638.                         if(bufrm){
  4639.                                 free(bufrm);
  4640.                                 bufrm=NULL;
  4641.                         }
  4642.                         if(strinf.bufstr){
  4643.                                 free(strinf.bufstr);
  4644.                                 strinf.bufstr=NULL;
  4645.                         }
  4646.                         i=inptr2;
  4647.                         bcha=cha2;
  4648.                         nexttok();
  4649.                 }
  4650.                 CharToBackBuf('}');
  4651.                 CharToBackBuf(0);
  4652.                 buf=(unsigned char *)REALLOC(BackTextBlock,SizeBackBuf);
  4653.                 SizeBackBuf=0;
  4654.         }
  4655.  
  4656.         blinenum=linenumber;
  4657.         nexttok();
  4658. ///////////////////
  4659.         if(tok==tk_openbrace){
  4660.                 if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){
  4661.                         warcompneqconst();
  4662.                         cha=cha2;
  4663.                         inptr=inptr2;
  4664.                         SkipBlock();
  4665.                         inptr2=inptr;
  4666.                         cha2=cha;
  4667.                         linenum2=linenumber;
  4668.                         nexttok();
  4669.                 }
  4670.                 else{
  4671.                         startblock();
  4672.                         doblock();
  4673.                         nexttok();
  4674.                         endblock();
  4675.                 }
  4676.         }
  4677.         else{
  4678.                 if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){
  4679.                         warcompneqconst();
  4680.                         do{
  4681.                                 nexttok();
  4682.                         }while(tok!=tk_semicolon&&tok!=tk_eof);
  4683.                 }
  4684.                 else docommand();
  4685.         }
  4686.  
  4687.         RestoreStack();
  4688.         SetContinueLabel();
  4689. //      puts((char *)string2);
  4690. //      printf("end for, curco=%u curbr=%u\n",curco,curbr);
  4691.         if(modif){
  4692.                 unsigned int oldlinenum=linenum2;
  4693.                 ITOK oitok;
  4694.                 oitok=itok2;
  4695.                 BackTextBlock=(char *)buf;
  4696.                 linenum2=blinenum;
  4697.                 RunBackText();
  4698.                 linenumber=linenum2=oldlinenum;
  4699.                 itok2=oitok;
  4700.         }
  4701.  
  4702.         if(COMPARE==FALSE||(COMPARE&&(icomp+numcomp)->use_cxz!=zerocompr)){
  4703.                 if(COMPARE&&(icomp+numcomp)->use_cxz==voidcompr)warcompeqconst();
  4704.                 jumploc(conloc);//JMP íà íà÷àëî öèêëà
  4705.         }
  4706.  
  4707.         if(COMPARE){
  4708.                 for(unsigned int i=0;i<numcomp;i++){
  4709.                         if((icomp+i)->type!=tk_oror){
  4710.                                 if(typeb==tk_FOR){
  4711.                                         if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesFOR);
  4712.                                         output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc);
  4713.                                 }
  4714.                                 else{
  4715.                                         if((outptr-(icomp+i)->loc)<=127)warningjmp(mesFOR,ifline);
  4716.                                         if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc);
  4717.                                         else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc);
  4718.                                 }
  4719.                         }
  4720.                 }
  4721.                 free(icomp);
  4722.         }
  4723.         if(retproc){
  4724.                 if(bakregstat)CopyRegStat(bakregstat);
  4725.         }
  4726.         else if(changeregstat)CompareRegStat(changeregstat);
  4727.         if(changeregstat)CopyRegStat(changeregstat);
  4728.         SetBreakLabel();
  4729.         if(usebr[curbr]!=0||useco[curco]!=0)clearregstat();
  4730.         FreeStat(bakregstat);
  4731.         FreeStat(changeregstat);
  4732. #ifdef OPTVARCONST
  4733.         ClearLVIC();
  4734. #endif
  4735.         if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  4736.         lastcommand=tk_for;
  4737. }
  4738.  
  4739. void decit(int dectok,ITOK *detok,char *&decbuf,SINFO *dstr)
  4740. // outputs code to decrement the given variable one.
  4741. {
  4742. int vop=0,i=0,razr=r16;
  4743.         switch(dectok){
  4744.                 case tk_dwordvar:
  4745.                 case tk_longvar:
  4746.                         CheckAllMassiv(decbuf,4,dstr,detok);
  4747.                         op66(r32);
  4748.                         if(cpu<3)cpu=3;
  4749.                         vop=1;
  4750.                         goto l2;
  4751.                 case tk_wordvar:
  4752.                 case tk_intvar: vop=1;
  4753.                         op66(r16);
  4754.                         i=1;
  4755.                 case tk_bytevar:
  4756.                 case tk_charvar:
  4757.                         i++;
  4758.                         CheckAllMassiv(decbuf,i,dstr,detok);
  4759.                         if(vop!=0)op66(r16);
  4760. l2:
  4761.                         outseg(detok,2);
  4762.                         op(0xFE + vop);
  4763.                         op(0x08+detok->rm);
  4764.                         outaddress(detok);
  4765.                         break;
  4766.                 case tk_reg32:
  4767.                         if(cpu<3)cpu=3;
  4768.                         razr=r32;
  4769.                 case tk_reg:
  4770.                         op66(razr);
  4771.                         op(0x48+detok->number);
  4772.                         break;
  4773.                 case tk_beg:
  4774.                         op(0xFE);
  4775.                         op(0xC8+detok->number);
  4776.                         break;
  4777.                 default:
  4778.                         preerror(invaliddecrem);
  4779.                         break;
  4780.         }
  4781. }
  4782.  
  4783. void uptdbr(/*int usesw*/)
  4784. {
  4785.         listbr[curbr]=numbr;    //íîìåð ýòîãî öèêëà
  4786.         usebr[curbr]=0;
  4787.         curbr++;        //÷èñëî âëîæåíèé
  4788.         numbr++;        //âñåãî öèêëîâ
  4789. //      if(!usesw){
  4790.                 useco[curco]=0;
  4791.                 curco++;
  4792. //      }
  4793.         if(curbr==MAXIN)preerror("to many inside bloks");
  4794. }
  4795.  
  4796. void doloop(unsigned int typeb)                                                         // both short and long loops
  4797. {
  4798. unsigned int startloc,startloc2;
  4799. int looptok;
  4800. ITOK lootok;
  4801. char *loopbuf;
  4802. signed char delta;
  4803. SINFO lstr;
  4804. int j=0,sline=linenumber;
  4805. unsigned int oaddESP=addESP;
  4806.         nexttok();
  4807. //      printf("tok=%u name=%s bufrm=%s\n",tok,itok.name,bufrm);
  4808.         expecting(tk_openbracket);
  4809.         looptok=tok;
  4810.         lootok=itok;
  4811.         loopbuf=bufrm;
  4812.         bufrm=NULL;
  4813.         lstr=strinf;
  4814.         strinf.bufstr=NULL;
  4815. //      printf("bufrm=%s strinf=%s\n",loopbuf,lstr.bufstr);
  4816.         clearregstat();
  4817. #ifdef OPTVARCONST
  4818.         ClearLVIC();
  4819. #endif
  4820.         uptdbr();
  4821.         if(dbg&1)KillLastLine();
  4822.         if((tok<tk_charvar||tok>tk_dwordvar)&&tok!=tk_reg&&tok!=tk_reg32
  4823.                         &&tok!=tk_beg&&tok!=tk_closebracket)
  4824.                 preerror(invaliddecrem);
  4825.         if(tok!=tk_closebracket){
  4826.                 if(typeb!=tk_loop){
  4827.                         if(dbg)AddLine();
  4828.                         int vop=tok==tk_reg?r16:r32;
  4829.                         if(typeb==tk_LOOPNZ&&((tok==tk_reg&&itok.number==CX)||
  4830.                                         (tok==tk_reg32&&itok.number==ECX))&&(!(optimizespeed&&chip>3&&chip<7))){
  4831.                                 op67(vop);
  4832.                                 outword(0xE3);
  4833.                         }
  4834.                         else{
  4835.                                 if(tok==tk_reg||tok==tk_reg32||tok==tk_beg){
  4836.                                         if(tok==tk_beg)op(0x84);
  4837.                                         else{
  4838.                                                 op66(vop);
  4839.                                                 op(0x85);
  4840.                                         }
  4841.                                         op(0xc0+(unsigned int)itok.number*9);
  4842.                                 }
  4843.                                 else{
  4844.                                         ITOK htok2;
  4845.                                         htok2.number=0;
  4846.                                         htok2.rm=(am32==FALSE?rm_d16:rm_d32);
  4847.                                         htok2.segm=DS;
  4848.                                         htok2.post=0;
  4849.                                         htok2.sib=(am32==FALSE?CODE16:CODE32);
  4850.                                         htok2.flag=0;
  4851.                                         int razr=r_undef;
  4852.                                         switch(tok){
  4853.                                                 case tk_longvar:
  4854.                                                 case tk_dwordvar:
  4855.                                                         razr=2;
  4856.                                                 case tk_intvar:
  4857.                                                 case tk_wordvar:
  4858.                                                         razr++;
  4859.                                                 case tk_charvar:
  4860.                                                 case tk_bytevar:
  4861.                                                         razr++;
  4862.                                         }
  4863.                                         outcmp(0,tok,&itok,bufrm,&strinf,tk_number,&htok2,loopbuf,&lstr,razr);
  4864.                                 }
  4865.                                 if(typeb==tk_LOOPNZ)outword(0x74);
  4866.                                 else{
  4867.                                         if(chip<3){
  4868.                                                 outword(0x0375);        // JNZ past jump up
  4869.                                                 op(0xE9);
  4870.                                         }
  4871.                                         else{
  4872.                                                 outword(0x840F);
  4873.                                         }
  4874.                                         outword(0);
  4875.                                         if(am32!=FALSE)outword(0);
  4876.                                 }
  4877.                         }
  4878.                 }
  4879.                 nexttok();      //òî ÷òî óìåíüøàåòñÿ
  4880.         }
  4881.         expecting(tk_closebracket);
  4882.         startloc2=outptr;
  4883.         if(AlignCycle)AlignCD(CS,aligncycle);
  4884.         startloc=outptr;
  4885.         docommand();
  4886.         RestoreStack();
  4887.         SetContinueLabel();
  4888.         if(looptok!=tk_closebracket){
  4889.                 if(((outptr-startloc)<=(127-3))&&(chip<3||optimizespeed==0)&&
  4890.                    ((looptok==tk_reg&&lootok.number==CX)||(looptok==tk_reg32&&lootok.number==ECX))){
  4891.                         delta=(char)(startloc-(outptr+2));
  4892.                         if(op67(looptok==tk_reg?r16:r32)!=FALSE)delta--;
  4893.                         op(0xE2);
  4894.                         op(delta);      /* LOOP 'delta' */
  4895.                 }
  4896.                 else{
  4897.                         decit(looptok,&lootok,loopbuf,&lstr);
  4898.                         if((outptr-startloc)>(unsigned int)(127-2-j)){   /* long jump */
  4899.                                 if(chip<3){
  4900.                                         outword(0x0374);        // JZ past jump up
  4901.                                         op(0xE9);
  4902.                                 }  /* JMP top of loop */
  4903.                                 else{
  4904.                                         outword(0x850F);
  4905.                                         if(cpu<3)cpu=3;
  4906.                                 }
  4907.                                 if(am32==FALSE)outword(startloc-(outptr+2));
  4908.                                 else outdword(startloc-(outptr+4));
  4909.                         }
  4910.                         else{
  4911.                                 op(0x75);   // short jump
  4912.                                 op(startloc-(outptr+1));
  4913.                         } /* JNZ 'delta' */
  4914.                 }
  4915.         }
  4916.         else jumploc(startloc);//JMP íà íà÷àëî öèêëà
  4917.         if(typeb!=tk_loop){
  4918.                 looptok=outptr-startloc2;
  4919.                 if(typeb==tk_LOOPNZ){
  4920.                         if(looptok>127)jumperror(sline,mesLOOPNZ);
  4921.                         output[startloc2-1]=(unsigned char)looptok;
  4922.                 }
  4923.                 else{
  4924.                         if(looptok<=127)warningjmp(mesLOOPNZ,sline);
  4925.                         if(am32==FALSE)*(unsigned short *)&output[startloc2-2]=(unsigned short)looptok;
  4926.                         else *(unsigned long *)&output[startloc2-4]=(unsigned long)looptok;
  4927.                 }
  4928.         }
  4929.         SetBreakLabel();
  4930.         if(usebr[curbr]!=0||useco[curco]!=0||typeb!=tk_loop)clearregstat();
  4931. #ifdef OPTVARCONST
  4932.         ClearLVIC();
  4933. #endif
  4934.         if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  4935.         lastcommand=tk_loop;
  4936. }
  4937.  
  4938. void GetNameLabel(int type,int num)
  4939. {
  4940.         sprintf((char *)string2,type==tk_break?"BREAK%04X":"CONTINUE%04X",listbr[num]);
  4941. }
  4942.  
  4943. void SetBreakLabel()
  4944. {
  4945.         curbr--;
  4946.         if(usebr[curbr]!=0){
  4947.                 GetNameLabel(tk_break,curbr);
  4948.                 updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start);
  4949. //              clearregstat();
  4950.         }
  4951. }
  4952.  
  4953. void SetContinueLabel()
  4954. {
  4955.         curco--;
  4956.         if(useco[curco]!=0){
  4957.                 GetNameLabel(tk_continue,curco);
  4958.                 updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start);
  4959.         }
  4960. }
  4961.  
  4962. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  4963.  
  4964. void SaveDataVal(unsigned int ssize,unsigned long long val)
  4965. {
  4966.         switch(ssize){
  4967.                 case 1: opd(val);       break;
  4968.                 case 2: outwordd(val); break;
  4969.                 case 4: outdwordd(val); break;
  4970.                 case 8: outqwordd(val); break;
  4971.         }
  4972. }
  4973.  
  4974. long AddVarString()
  4975. {
  4976. long loop=0;
  4977. int term;
  4978.         do{
  4979.                 term=itok.flag;
  4980.                 for(int i=0;i<itok.number;i++){ //ââåñòè ñòðîêó
  4981.                         opd(string[i]);
  4982.                         loop++;
  4983.                 }
  4984.                 nexttok();
  4985.         }while(tok==tk_string);
  4986.         switch(term&3){
  4987.                 case zero_term:
  4988.                         if(term&s_unicod)opd(0);
  4989.                         opd(0);
  4990.                         loop++;
  4991.                         break;
  4992.                 case dos_term:
  4993.                         if(term&s_unicod)opd(0);
  4994.                         opd('$');
  4995.                         loop++;
  4996.                         break;
  4997.         }
  4998.         return loop;
  4999. }
  5000.  
  5001. long initglobalvar(int type,long elements,long ssize,char typev)
  5002. {
  5003. long loop;
  5004. long long i=0;
  5005. int htok;
  5006. char name[IDLENGTH];
  5007.         nexttok();
  5008.         loop=0;
  5009.         if(dbg&2)AddDataLine((tok==tk_string&&typev!=pointer?(char)3:(char)ssize));
  5010. loopsw:
  5011.         htok=tok;
  5012.         switch(tok){    //çàïîëíèòü âåëè÷èíàìè
  5013.                 case tk_apioffset: AddApiToPost(itok.number); nexttok(); break;
  5014.                 case tk_postnumber:
  5015.                         (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
  5016.                         itok.flag=0;
  5017.                         goto cn1;
  5018.                 case tk_undefofs:
  5019.                         strcpy(name,itok.name);
  5020. //                      AddUndefOff(1,itok.name);
  5021. cn1:
  5022.                         tok=tk_number;
  5023.                 case tk_minus:
  5024.                 case tk_number:
  5025.                   if(type==tk_byte||type==tk_word||type==tk_dword)i+=doconstdwordmath();
  5026.                         else if(type==tk_float)i=doconstfloatmath();
  5027.                         else if(type==tk_double)i=doconstdoublemath();
  5028.                         else if(type==tk_qword)i+=doconstqwordmath();
  5029.                         else i+=doconstlongmath();
  5030.                         if(tok==tk_plus&&tok2==tk_postnumber&&htok!=tk_undefofs){
  5031.                                 nexttok();
  5032.                                 goto loopsw;
  5033.                         }
  5034.                         if(elements!=0){
  5035.                                 for(;loop<elements;loop++){
  5036.                                         if(postnumflag&f_reloc)AddReloc();
  5037.                                         if(htok==tk_undefofs)AddUndefOff(3,name);
  5038.                                         SaveDataVal(ssize,i);
  5039.                                 }
  5040.                         }
  5041.                         loop=loop*ssize;
  5042.                         break;
  5043.                 case tk_string:
  5044.                         if(typev==pointer){
  5045.                                 loop=(am32==FALSE?2:4);
  5046.                                 i=addpoststring(DS);
  5047.                                 if(am32==FALSE)outwordd(i);
  5048.                                 else outdwordd(i);
  5049.                                 nexttok();
  5050.                         }
  5051.                         else{
  5052.                                 loop=AddVarString();
  5053.                                 if(elements!=0){
  5054.                                         for(;loop<ssize*elements;loop++){//äîïîëíèòü 0 åñëè êîðîòêàÿ
  5055.                                                 opd(aligner);
  5056.                                         }
  5057.                                 }
  5058.                         }
  5059.                         break;
  5060.                 case tk_from:   //ñ÷èòàòü ôàéë ñ äàííûìè
  5061.                         nexttok();
  5062.                         loop=dofrom();
  5063.                         if(elements!=0){
  5064.                                 for(;loop<ssize*elements;loop++)opd(aligner);
  5065.                         }
  5066.                         nexttok();
  5067.                         break;
  5068.                 case tk_extract:        //ñ÷èòàòü ôðàãìåíò ôàéëà ñ äàííûìè
  5069.                         nexttok();
  5070.                         loop=doextract();
  5071.                         if(elements!=0){
  5072.                                 for(;loop<ssize*elements;loop++)opd(aligner);
  5073.                         }
  5074.                         break;
  5075.                 case tk_openbrace:      //ìàññèâ äàííûõ
  5076.                         nexttok();
  5077.                         while(tok!=tk_closebrace){
  5078.                                 htok=tok;
  5079.                                 if(typev==pointer){
  5080.                                         if(tok==tk_string){
  5081.                                                 i=addpoststring(DS);
  5082.                                                 nexttok();
  5083.                                         }
  5084.                                         else if(tok==tk_number||tok==tk_minus||tok==tk_undefofs){
  5085.                                                 if(tok==tk_undefofs){
  5086.                                                         tok=tk_number;
  5087.                                                         strcpy(name,itok.name);
  5088. //                                                      AddUndefOff(1,itok.name);
  5089.                                                 }
  5090. //                                              else if((itok.flag&f_reloc)!=0)AddReloc();
  5091.                                                 i=doconstdwordmath();
  5092.                                         }
  5093.                                         else{
  5094.                                                 numexpected();
  5095.                                                 nexttok();
  5096.                                         }
  5097.                                         if(postnumflag&f_reloc)AddReloc();
  5098.                                         if(htok==tk_undefofs)AddUndefOff(3,name);
  5099.                                         if(am32==FALSE)outwordd(i);
  5100.                                         else outdwordd(i);
  5101.                                 }
  5102.             else{
  5103.                                         switch(tok){
  5104.                                                 case tk_apioffset: AddApiToPost(itok.number); nexttok(); break;
  5105.                                                 case tk_string:
  5106.                                                         loop+=AddVarString()/ssize-1;
  5107.                                                         break;
  5108.                                                 case tk_postnumber:
  5109.                                                         (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
  5110.                                                         itok.flag=0;
  5111.                                                         goto cn2;
  5112.                                                 case tk_undefofs:
  5113.                                                         strcpy(name,itok.name);
  5114. //                                                      AddUndefOff(1,itok.name);
  5115. cn2:
  5116.                                                         tok=tk_number;
  5117.                                                 case tk_number:
  5118.                                                 case tk_minus:
  5119.                                                   if(type==tk_byte||type==tk_word||type==tk_dword)i=doconstdwordmath();
  5120.                                                         else if(type==tk_float)i=doconstfloatmath();
  5121.                                                         else if(type==tk_double)i=doconstdoublemath();
  5122.                                                         else if(type==tk_qword)i=doconstqwordmath();
  5123.                                                         else i=doconstlongmath();
  5124. //                                                      if((postnumflag&f_reloc)!=0)AddReloc();
  5125.                                                         if((postnumflag&f_reloc)!=0)AddReloc();
  5126.                                                         if(htok==tk_undefofs)AddUndefOff(3,name);
  5127.                                                         SaveDataVal(ssize,i);
  5128.                                                         break;
  5129.                                                 default:
  5130.                                                         numexpected();
  5131.                                                         nexttok();
  5132.                                                         break;
  5133.                                         }
  5134.                                 }
  5135.                                 loop++;
  5136.                                 if(tok==tk_closebrace)break;
  5137.                                 expecting(tk_camma);
  5138.                         }
  5139.                         if(elements!=0){
  5140.                                 for(;loop<elements;loop++)SaveDataVal(ssize,aligner);
  5141.                         }
  5142.                         loop=loop*ssize;
  5143.                         nexttok();
  5144.                         break;
  5145.                 default:
  5146. //                      printf("tok=%d\n",tok);
  5147.                         numexpected(); nexttok(); break;
  5148.         }
  5149.         return loop;
  5150. }
  5151.  
  5152. void AddPostData(unsigned int loop)
  5153. {
  5154.         if(dynamic_flag==0){
  5155.                 unsigned int longpostsize=loop+postsize;
  5156.                 if(am32==FALSE&&longpostsize>0xFFFFL)tobigpost();
  5157.                 else postsize=longpostsize;
  5158.         }
  5159. }
  5160.  
  5161. void labelindata()
  5162. {
  5163. //idrec *varrec;
  5164.         FindOff((unsigned char *)itok.name,DS);
  5165.         tok=tk_number;
  5166.         itok.number=outptrdata;
  5167.         itok.segm=DS;
  5168.         string[0]=0;
  5169.         if(FixUp)itok.flag=f_reloc;
  5170.         /*varrec=*/addtotree(itok.name);
  5171.         /*varrec->count=*/FindOff((unsigned char *)itok.name,DS);
  5172.         nexttok();
  5173.         nexttok();
  5174. }
  5175.  
  5176. void globalvar()         /* both initialized and unitialized combined */
  5177. {
  5178. long size,loop,i,elements,ssize;
  5179. char done=0,typev;
  5180. char var_name[IDLENGTH];
  5181. int type=itok.rm,typebak;       //òèï ïåðåìåííîé
  5182. unsigned int flag,fflag=itok.flag,dynamic;
  5183. unsigned int npointr=itok.npointr;
  5184. int count;
  5185. idrec *varrec;
  5186.         size=typesize(type);    //ðàçìåð ïåðåìåííîé
  5187.         if(FixUp)fflag|=f_reloc;
  5188.         typebak=type;
  5189.         while(tok!=tk_eof&&done==0){
  5190.                 int nnpointr=0;
  5191.                 typev=variable;
  5192.                 ssize=size;
  5193.                 flag=fflag;
  5194.                 type=typebak;
  5195. //              printf("type=%d\n",type);
  5196.                 if(tok==tk_far){
  5197.                         flag|=f_far;
  5198.                         nexttok();
  5199.                 }
  5200.                 while(tok==tk_mult){    //óêàçàòåëü
  5201.                         npointr++;
  5202.                         nexttok();
  5203.                 }
  5204.                 if(tok==tk_openbracket){
  5205.                         nexttok();
  5206.                         while(tok==tk_mult){    //óêàçàòåëü íà ïðîöåäóðó
  5207.                                 nnpointr++;
  5208.                                 nexttok();
  5209.                         }
  5210.                 }
  5211.                 if(npointr){
  5212.                         if((flag&f_far)!=0||am32!=FALSE)ssize=4;
  5213.                         else ssize=2;
  5214.                         typev=pointer;
  5215.                         type=am32==FALSE?tk_word:tk_dword;
  5216.                 }
  5217. //                      printf("tok=%d %s\n",tok,itok.name);
  5218.                 switch(tok){
  5219.                         case tk_id:
  5220.                         case tk_ID:
  5221.                                 if(tok2==tk_openbracket||nnpointr){
  5222.                                         if(npointr)type=am32==FALSE?tk_word:tk_dword;
  5223.                                         declare_procedure(flag,type,nnpointr);
  5224.                                         break;
  5225.                                 }
  5226.                                 strcpy(var_name,itok.name);     //èìÿ ïåðåìåííîé
  5227.                                 elements=1;
  5228.                                 nexttok();
  5229.                                 if(tok==tk_openblock){  //[
  5230.                                         nexttok();
  5231.                                         if(tok==tk_closeblock){//íåèçâåñòíîå ÷èñëî ýëåìåíòîâ
  5232.                                                 elements=0;
  5233.                                                 nexttok();
  5234.                                         }
  5235.                                         else{
  5236.                                                 CheckMinusNum();
  5237.                                                 if(tok!=tk_number){
  5238.                                                         numexpected();
  5239.                                                         nexttok();
  5240.                                                 }
  5241.                                                 else{
  5242.                                                         elements=doconstlongmath();     //÷èñëî ýëåìåíòîâ
  5243.                                                         expecting(tk_closeblock);
  5244.                                                 }
  5245.                                         }
  5246.                                 }
  5247.                                 if(type==tk_void){
  5248.                                         preerror("type 'void' not use for declare variables");
  5249.                                         break;
  5250.                                 }
  5251.                                 dynamic=FALSE;
  5252.                                 if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){   //= èíèöèàëèçèðîâàíàÿ ïåðåìåííàÿ
  5253.                                         if((flag&f_extern))preerror("extern variable do not initialize at declare");
  5254.                                         i=tok;
  5255.                                         itok.type=tp_gvar;// 11.07.05 21:56 tp_ucnovn;
  5256.                                         SetNewTok(type,typev);
  5257.                                         if(useStartup==TRUE&&i!=tk_assign&&SaveStartUp(size*elements,var_name)!=FALSE){
  5258.                                                 if(elements==0)ZeroMassiv();    //îøèáêà
  5259.                                                 tok=i;
  5260.                                                 break;
  5261.                                         }
  5262.                                         if(alignword&&ssize&&(!dynamic_flag))alignersize+=AlignCD(DS,ssize);
  5263.                                         itok.number=dynamic_flag==0?outptrdata:0;
  5264.                                         itok.segm=(comfile==file_rom&&modelmem==TINY?CS:DS);
  5265.                                         itok.flag=flag;
  5266. //                                      itok.post=dynamic;
  5267.                                         itok.size=elements*ssize;
  5268.                                         itok.rm=(am32==FALSE?rm_d16:rm_d32);
  5269.                                         itok.npointr=(unsigned short)npointr;
  5270.  
  5271.                                         varrec=addtotree(var_name);
  5272.                                         if((count=FindOff((unsigned char *)var_name,DS))==0){
  5273.                                                 if(dynamic_flag)dynamic=DYNAMIC_VAR;
  5274.                                         }
  5275.                                         else if(dynamic_flag)dynamic=USED_DIN_VAR;
  5276.                                         if(i!=tk_assign){
  5277.                                                 if(elements==0)ZeroMassiv();
  5278.                                                 else if(notpost==TRUE){
  5279.                                                         for(loop=0;loop<elements;loop++)SaveDataVal(ssize,aligner);
  5280.                                                         loop=loop*ssize;
  5281.                                                         varrec->recsize=loop;
  5282.                                                         datasize+=loop;
  5283.                                                 }
  5284.                                                 tok=i;
  5285.                                                 break;
  5286.                                         }
  5287.                                         if(dynamic){
  5288.                                                 varrec->sbuf=dynamic_var();
  5289.                                                 varrec->recpost=dynamic;
  5290.                                         }
  5291.                                         else{
  5292.                                                 loop=initglobalvar(type,elements,ssize,typev);
  5293.                                                 varrec->recsize=loop;
  5294.                                                 datasize+=loop;
  5295.                                         }
  5296.                                         varrec->count=count;
  5297.                                 }
  5298.                                 else{
  5299.                                         if(elements==0){
  5300.                                                 ZeroMassiv();
  5301.                                                 break;
  5302.                                         }
  5303.                                         if(CheckUseAsUndef((unsigned char *)var_name)==0&&dynamic_flag)dynamic=TRUE;
  5304.                                         switch(tok){    //íåèíèöèàëèçèðîâàííûå
  5305.                                                 default: expected(';');
  5306.                                                 case tk_semicolon: done=1;//    ;
  5307.                                                 case tk_camma:   //, post global type
  5308.                                                         itok.type=tp_postvar;//11.07.05 21:57 tp_ucnovn;
  5309.                                                         SetNewTok(type,typev);
  5310.                                                         if((flag&f_extern)==0&&useStartup==TRUE&&dynamic==0){
  5311.                                                                 if(SaveStartUp(ssize*elements,var_name)!=FALSE){
  5312.                                                                         nexttok();
  5313.                                                                         break;
  5314.                                                                 }
  5315.                                                         }
  5316.                                                         if((flag&f_extern)==0&&alignword&&dynamic==0){  //âûðîâíÿòü íà ÷åòíûé àäðåñ
  5317.                                                                 if(ssize==2){
  5318.                                                                         if(postsize%2==1)postsize++;
  5319.                                                                 }
  5320.                                                                 else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4);
  5321.                                                         }
  5322.                                                         count=FindOff((unsigned char *)var_name,VARPOST);
  5323.                                                         itok.post=dynamic+1;
  5324.                                                         itok.segm=DS;
  5325.                                                         loop=elements*ssize;
  5326.                                                         itok.number=(flag&f_extern)==0?postsize:externnum++;
  5327.                                                         itok.flag=flag;
  5328.                                                         itok.size=loop;
  5329.                                                         itok.rm=(am32==FALSE?rm_d16:rm_d32);
  5330.                                                         itok.npointr=(unsigned short)npointr;
  5331.                                                         varrec=addtotree(var_name);
  5332.                                                         varrec->count=count;
  5333.                                                         if((flag&f_extern)==0)AddPostData(loop);
  5334.                                                         nexttok();
  5335.                                                         break;
  5336.                                         }
  5337.                                 }
  5338.                                 break;
  5339.                         case tk_undefproc:
  5340.                                 if(tok2==tk_openbracket||nnpointr){
  5341.                                         if(npointr)type=am32==FALSE?tk_word:tk_dword;
  5342.                                         declare_procedure(flag,type,nnpointr);
  5343.                                         break;
  5344.                                 }
  5345.                         case tk_proc:
  5346.                         case tk_floatvar:
  5347.                         case tk_dwordvar:
  5348.                         case tk_longvar:
  5349.                         case tk_charvar:
  5350.                         case tk_intvar:
  5351.                         case tk_bytevar:
  5352.                         case tk_pointer:
  5353.                         case tk_wordvar: idalreadydefined(); nexttok(); break;
  5354.                         default: expected(';');
  5355.                         case tk_semicolon: done=1;
  5356.                         case tk_camma: nexttok(); break;
  5357.                 }
  5358.                 npointr=0;
  5359.         }
  5360.         dopoststrings();
  5361. }
  5362.  
  5363. void SetNewTok(int type,int typev)
  5364. {
  5365.         switch(typev){
  5366.                 case variable:
  5367.                         if(type>=tk_char&&type<=tk_double)tok=type+(tk_charvar-tk_char);
  5368.                         break;
  5369.                 case pointer:
  5370. //                      if(type>=tk_void&&type<=tk_float){
  5371.                                 tok=tk_pointer;
  5372.                                 itok.type=(unsigned short)type;
  5373. //                      }
  5374.                         break;
  5375.         }
  5376. }
  5377.  
  5378. int SaveStartUp(int size,char *var_name)
  5379. {
  5380. int i=0;
  5381.         if((startStartup+size)<=endStartup){
  5382.                 if(alignword){  //âûðîâíÿòü íà ÷åòíûé àäðåñ
  5383.                         if(size==2){
  5384.                                 if(startStartup%2==1)i=1;
  5385.                         }
  5386.                         else if(size==4&&startStartup%4!=0)i=4-(startStartup%4);
  5387.                 }
  5388.                 if((startStartup+size+i)<=endStartup){
  5389.                         startStartup+=i;
  5390.                         itok.number=startStartup;
  5391.                         itok.segm=DS;
  5392.                         itok.flag=0;
  5393.                         itok.post=0;
  5394.                         itok.rm=(am32==FALSE?rm_d16:rm_d32);
  5395.                         itok.type=tp_ucnovn;
  5396.                         addtotree(var_name);
  5397.                         startStartup+=size;
  5398.                         return TRUE;
  5399.                 }
  5400.         }
  5401.         return FALSE;
  5402. }
  5403.  
  5404. /* ======= ñòàðò çàãîëîâêà ïðîöåäóðû ======== */
  5405.  
  5406. void setuprm()
  5407. {
  5408.         itok.rm=returntype=(itok.rm==tokens?am32==FALSE?tk_word:tk_dword:itok.rm);
  5409.         if(itok.npointr)itok.rm=returntype=(am32==FALSE?tk_word:tk_dword);
  5410. }
  5411.  
  5412. void eaxToFloat(int reg=AX)
  5413. {
  5414. int next=1;
  5415.         CheckMinusNum();
  5416.         if(itok2.type==tp_opperand){    //ñîñòàâíîå
  5417.                 doeaxfloatmath(tk_reg32,reg);
  5418.                 next=0;
  5419.         }
  5420.         else{
  5421.                 switch(tok){
  5422.                         case tk_number:
  5423.                                 if(itok.rm==tk_double)itok.fnumber=itok.dnumber;
  5424.                                 else if(itok.rm!=tk_float){
  5425.                                         float temp=itok.number;
  5426.                                         *(float *)&itok.number=temp;
  5427.                                 }
  5428.                                 op66(r32);
  5429.                                 op(0xb8+reg);   // MOV EAX,#
  5430.                                 outdword(itok.number);
  5431.                                 break;
  5432.                         case tk_floatvar:
  5433.                                 if(reg==AX&&itok.rm==rm_d16&&itok.sib==CODE16){
  5434.                                         op66(r32);
  5435.                                         outseg(&itok,1);
  5436.                                         op(0xA1);
  5437.                                         outword((unsigned int)itok.number);
  5438.                                 }
  5439.                                 else{
  5440.                                         CheckAllMassiv(bufrm,4,&strinf);
  5441.                                         op66(r32);
  5442.                                         outseg(&itok,2);
  5443.                                         op(0x8B);
  5444.                                         op(itok.rm+reg*8);
  5445.                                         outaddress(&itok);
  5446.                                 }
  5447.                                 break;
  5448.                         default:
  5449.                                 if(doeaxfloatmath(tk_reg32,reg)!=tk_reg32&&reg!=AX){
  5450.                                         if(!am32)Leave();
  5451.                                         op66(r32);
  5452.                                         op(0x89);
  5453.                                         op(0xc0+reg);
  5454.                                 }
  5455.                                 next=0;
  5456.                 }
  5457.         }
  5458.         if(next)nexttok();
  5459. }
  5460.  
  5461. void CalcRegPar(int reg,int def,char **ofsstr)
  5462. {
  5463. char signflag=0;
  5464. int razr;
  5465. unsigned char oinline=useinline;
  5466.         useinline=0;
  5467. //      if(*ofsstr)puts(*ofsstr);
  5468.         if(tok!=tk_camma){
  5469.                 if(tok==tk_openbracket){
  5470.                         nexttok();
  5471.                         if(tok>=tk_char&&tok<=tk_double)def=tok;
  5472.                         nexttok();
  5473.                         expectingoperand(tk_closebracket);
  5474.                 }
  5475.                 if(tok>=tk_char&&tok<=tk_double){
  5476.                         def=tok;
  5477.                         getoperand();
  5478.                 }
  5479.                 if(tok==tk_string){
  5480.                 op(0xB8+reg);
  5481.                         if(am32==FALSE)outword(addpoststring());
  5482.                         else outdword(addpoststring());
  5483.                         nexttok();
  5484.                         razr=(am32==FALSE?r16:r32);
  5485.                 }
  5486.                 else if(tok==tk_floatvar)eaxToFloat(reg);
  5487.                 else{
  5488.                         switch(def){
  5489.                                 case tk_int: signflag=1;
  5490.                                 case tk_word:
  5491.                                         if(reg==AX)do_e_axmath(signflag,r16,ofsstr);
  5492.                                         else getintoreg(reg,r16,signflag,ofsstr);
  5493.                                         razr=r16;
  5494.                                         break;
  5495.                                 case tk_char: signflag=1;
  5496.                                 case tk_byte:
  5497.                                         if(reg==AX)doalmath(signflag,ofsstr);
  5498.                                         else{
  5499.                                                 getintobeg(reg,ofsstr);
  5500.                                                 dobegmath(reg);
  5501.                                         }
  5502.                                         razr=r8;
  5503.                                         break;
  5504.                                 case tk_long: signflag=1;
  5505.                                 case tk_dword:
  5506.                                         if(reg==AX)do_e_axmath(signflag,r32,ofsstr);
  5507.                                         else getintoreg(reg,r32,signflag,ofsstr);
  5508.                                         razr=r32;
  5509.                                         break;
  5510.                                 case tk_float:
  5511.                                         eaxToFloat(reg);
  5512.                                         razr=r32;
  5513.                                         break;
  5514.                                 case tk_qword:
  5515.                                         getintoreg64(reg);
  5516.                                         doregmath64(reg);
  5517.                                         razr=r64;
  5518.                                         break;
  5519.                                 case tokens:
  5520.                                         razr=(am32==FALSE?r16:r32);
  5521.                                         if(reg==AX)do_e_axmath(0,razr,ofsstr);
  5522.                                         else getintoreg(reg,razr,signflag,ofsstr);
  5523.                                         break;
  5524.                         }
  5525.                 }
  5526.                 AddRegistr(razr,reg);
  5527. //                                      printf("%08X\n",reg);
  5528.         }
  5529.         useinline=oinline;
  5530. }
  5531.  
  5532. int GetTypeParam(char c)
  5533. {
  5534.         switch(c){
  5535.                 case 'B': return tk_byte;
  5536.                 case 'W': return tk_word;
  5537.                 case 'D':       return tk_dword;
  5538.                 case 'C': return tk_char;
  5539.                 case 'I': return tk_int;
  5540.                 case 'L': return tk_long;
  5541.                 case 'F': return tk_float;
  5542.                 case 'A': return tk_multipoint;
  5543.                 case 'Q': return tk_qword;
  5544.                 case 'E': return tk_double;
  5545.                 case 'S': return tk_fpust;
  5546.                 case 'T': return tk_struct;
  5547.                 case 'U': return tokens;
  5548.         default:
  5549.                         extraparam();
  5550. //                      printf("%c\n",c);
  5551.                         return 0;
  5552.         }
  5553. }
  5554.  
  5555. void doregparams()
  5556. {
  5557. int i=0;
  5558. char *ofsstr=NULL;
  5559. int razr;
  5560. int retreg;
  5561.         ClearRegister();
  5562.         if(tok!=tk_openbracket)expected('(');
  5563.         while(tok2==tk_camma){
  5564.                 nexttok();
  5565.                 i++;
  5566.         }
  5567.         ofsstr=GetLecsem(tk_camma,tk_closebracket);
  5568.         getoperand();
  5569.         if(tok!=tk_closebracket){
  5570.                 if(strlen(param)!=0){
  5571.                 int def;
  5572.                         char *oparam=BackString(param);
  5573.                         for(;;){
  5574.                                 while(tok==tk_camma){
  5575.                                         if(ofsstr)free(ofsstr);
  5576.                                         ofsstr=GetLecsem(tk_camma,tk_closebracket);
  5577.                                         getoperand();
  5578.                                 }
  5579.                                 if((def=GetTypeParam(oparam[i++]))==0){
  5580.                                         nexttok();
  5581.                                         break;
  5582.                                 }
  5583.                                 if(def==tk_qword){
  5584.                                         int c1,c2;
  5585.                                         c1=oparam[i++]-0x30;
  5586.                                         c2=oparam[i++]-0x30;
  5587.                                         retreg=c1|(c2*256);
  5588. //                                      printf("%08X\n",retreg);
  5589.                                 }
  5590.                                 else retreg=oparam[i++]-0x30;
  5591.                                 if(ofsstr){
  5592.                                         if((razr=getrazr(def))!=r64){
  5593.                                                 int retr;
  5594.                                                 if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){
  5595.                                                         GetEndLex(tk_camma,tk_closebracket);
  5596.                                                         if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr);
  5597.                                                         nexttok();
  5598.                                                         goto endparam;
  5599.                                                 }
  5600.                                         }
  5601.                                 }
  5602.                                 if(def==tk_fpust)float2stack(retreg);
  5603.                                 else CalcRegPar(retreg,def,&ofsstr);
  5604. endparam:
  5605.                                 if(ofsstr&&razr!=r64){
  5606.                                         IDZToReg(ofsstr,retreg,razr);
  5607.                                         free(ofsstr);
  5608.                                         ofsstr=NULL;
  5609.                                 }
  5610.                                 if(tok!=tk_camma){
  5611.                                         if(tok!=tk_closebracket)expected(')');
  5612.                                         if(oparam[i]!=0)missingpar();
  5613.                                         break;
  5614.                                 }
  5615.                         }
  5616.                         free(oparam);
  5617.                 }
  5618.                 else{
  5619. char regpar[6]={AX,BX,CX,DX,DI,SI};
  5620.                         for(;i<6;i++){
  5621.                                 if(tok==tk_camma){
  5622.                                         if(ofsstr)free(ofsstr);
  5623.                                         ofsstr=GetLecsem(tk_camma,tk_closebracket);
  5624.                                         getoperand();
  5625.                                         if(tok==tk_camma)continue;
  5626.                                 }
  5627.                                 retreg=regpar[i];
  5628.                                 if(ofsstr&&tok!=tk_camma){
  5629.                                         razr=(am32==FALSE?r16:r32);
  5630.                                         int retr;
  5631.                                         if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){
  5632.                                                 GetEndLex(tk_camma,tk_closebracket);
  5633.                                                 if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr);
  5634.                                                 nexttok();
  5635.                                                 goto endparam1;
  5636.                                         }
  5637.                                 }
  5638.                                 CalcRegPar(retreg,tokens,&ofsstr);
  5639. endparam1:
  5640.                                 if(ofsstr){
  5641.                                         IDZToReg(ofsstr,retreg,razr);
  5642.                                         free(ofsstr);
  5643.                                         ofsstr=NULL;
  5644.                                 }
  5645.                                 if(tok!=tk_camma){
  5646.                                         if(tok!=tk_closebracket)expected(')');
  5647.                                         break;
  5648.                                 }
  5649.                         }
  5650.                 }
  5651.                 setzeroflag=FALSE;
  5652.         }
  5653.         if(ofsstr)free(ofsstr);
  5654. }
  5655.  
  5656. int CheckUses()
  5657. {
  5658. int i;
  5659. int regs=0;
  5660. int bracket=FALSE;
  5661.         memset((SAVEREG *)psavereg,0,sizeof(SAVEREG));
  5662.         if(tok==tk_openbracket){
  5663.                 if(stricmp(itok2.name,"uses")==0){
  5664.                         bracket=TRUE;
  5665.                         nexttok();
  5666.                 }
  5667.                 else return 0;
  5668.         }
  5669.         if(stricmp(itok.name,"uses")==0){
  5670.                 nexttok();
  5671.                 while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){
  5672.                         i=r32;
  5673.                         switch(tok){
  5674.                                 case tk_beg:
  5675.                                         if(itok.number>3)itok.number-=4;
  5676.                                         i=(am32+1)*2;
  5677.                                         break;
  5678.                                 case tk_reg:
  5679.                                         if(!am32)i=r16;
  5680.                                         break;
  5681.                         }
  5682.                         regs=regs|(1<<itok.number);
  5683.                         psavereg->reg[itok.number]=i;
  5684.                         i=1;
  5685.                         if((am32&&i==r16)||(am32==0&&i==r32))i=2;
  5686.                         psavereg->size+=i;
  5687.                         nexttok();
  5688.                         if(tok==tk_camma)nexttok();
  5689.                 }
  5690.                 if(strcmp(itok.name,"allregs")==0){
  5691.                         psavereg->size=1;
  5692.                         psavereg->all=1;
  5693.                         regs=dEAX|dEBX|dECX|dEDX|dEBP|dEDI|dESI;
  5694.                         nexttok();
  5695.                 }
  5696.         }
  5697.         if(bracket)expecting(tk_closebracket);
  5698.         return regs;
  5699. }
  5700.  
  5701. void Enter()
  5702. {
  5703.         if(ESPloc==FALSE||am32==FALSE){
  5704.                 op(0x55);       //push bp
  5705.                 outword(0xe589);//mov bp,sp
  5706.         }
  5707. }
  5708.  
  5709. void setproc(int defflag)
  5710. {
  5711. char *bstring;
  5712. unsigned char oinline,ooptimizespeed;
  5713. ITOK otok;
  5714. unsigned int i;
  5715. int regs=0;
  5716. unsigned char oESPloc=ESPloc;
  5717. int startline=linenumber;
  5718. unsigned int oregidx;
  5719.  
  5720.         clearregstat();
  5721.         addESP=inlineflag=0;
  5722.         oinline=useinline;
  5723.         ooptimizespeed=optimizespeed;
  5724.         oregidx=*(unsigned int *)&idxregs;
  5725.         current_proc_type=itok.flag;
  5726.  
  5727.         if(itok.flag&f_extern)notexternfun();   //new 18.04.07 12:20
  5728. //      printf("%s tok=%d flag=%08X\n",itok.name,tok,itok.flag);
  5729.  
  5730.         tok=lastcommand=tk_proc;
  5731.         itok.number=outptr;
  5732.         if(itok.segm<NOT_DYNAMIC)itok.segm=DYNAMIC_SET;
  5733.         setuprm();
  5734. //      printf("rm=%d %s\n",itok.rm,itok.name);
  5735.         if(defflag){    //ðàíåå óæå áûëè âûçîâû
  5736. //              updatecall(updatetree(),(unsigned int)itok.number,0);
  5737.                 regs=itok.post;
  5738.                 if(updatecall(updatetree(),(unsigned int)itok.number,0)==-1&&
  5739.                                         strcmp(itok.name,mesmain)==0/*&&jumptomain!=CALL_NONE*/){
  5740.                         itok.number=outptr=outptr-(jumptomain==CALL_SHORT?2:am32==FALSE?3:5);
  5741.                         if(dbg){
  5742.                                 KillLastLine();
  5743.                                 KillLastLine();
  5744.                                 AddLine();
  5745.                         }
  5746.                         updatetree();
  5747.                 }
  5748.         }
  5749.         else{   //èíà÷å äîáàâèòü â äåðåâî
  5750.                 string[0]=0;
  5751.                 itok.type=tp_ucnovn;
  5752.                 addtotree(itok.name);
  5753.         }
  5754. //      puts(itok.name);
  5755.         if((i=FindOff((unsigned char *)itok.name,CS))!=0){
  5756.                 itok.rec->count=i;
  5757.         }
  5758.         bstring=BackString((char *)string);
  5759.         otok=itok;
  5760.         if(strcmp(mesmain,otok.name)==0){
  5761.                 if(startuptomain==TRUE&&comfile==file_com)doprestuff();
  5762.                 if(numdomain!=0){
  5763.                         for(i=0;i<numdomain;i++){
  5764.                                 strcpy(itok.name,domain+i*IDLENGTH);
  5765.                                 tok=tk_ID;
  5766.                                 searchvar(itok.name,0);
  5767.                                 switch(tok){
  5768.                                         case tk_ID:
  5769.                                         case tk_id:
  5770.                                                 tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void);
  5771.                                                 (postbuf+posts-1)->loc=outptr+1;
  5772.                                                 callloc0();                     /* produce CALL [#] */
  5773.                                                 break;
  5774.                                         case tk_declare:
  5775.                                                 tok=tk_undefproc;
  5776.                                                 updatetree();
  5777.                                         case tk_undefproc:
  5778.                                                 addacall(itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR)));
  5779.                                                 callloc0();             /* produce CALL [#] */
  5780.                                                 break;
  5781.                                         case tk_proc:
  5782.                                                 if(itok.flag&f_far)op(0x0e);    //push cs
  5783.                                                 if(itok.segm<NOT_DYNAMIC){
  5784.                                                         addacall(itok.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));
  5785.                                                         itok.number=0;
  5786.                                                 }
  5787.                                                 callloc(itok.number);
  5788.                                                 break;
  5789.                                         default:
  5790.                                                 preerror("impossible type for startup function");
  5791.                                                 break;
  5792.                                 }
  5793.                         }
  5794.                         numdomain=0;
  5795.                         free(domain);
  5796.                 }
  5797.         }
  5798.         nextexpecting2(tk_openbracket);
  5799.         startblock();
  5800.         if(searchteg&&(!(current_proc_type&f_static))&&(current_proc_type&f_typeproc)!=tp_pascal)AddThis();
  5801.         if(tok!=tk_closebracket){
  5802.                 if((current_proc_type&f_typeproc)!=tp_fastcall){
  5803.                         declareparams();
  5804.                         if(otok.type==tp_declare&&defflag&&strcmp(bstring,param)!=0){
  5805. //                                      printf("old=%s new=%s\n",bstring,param);
  5806.                                         redeclare(otok.name);
  5807.                         }
  5808. //                      if(bstring[0]!=0&&bstring[0]!='A'&&strcmp(bstring,param)!=0)redeclare();
  5809.                 }
  5810.                 else{
  5811.                         declareparamreg();
  5812.                 }
  5813.                 if(bstring)free(bstring);
  5814.                 bstring=BackString((char *)param);
  5815.         }
  5816.         else if((current_proc_type&f_typeproc)!=tp_fastcall&&bstring[0]!=0){
  5817.                 if(bstring[0]!='V'&&bstring[0]!='A'){
  5818.                         redeclare(otok.name);
  5819. //                      puts(bstring);
  5820.                 }
  5821.         }
  5822.  
  5823.         strcpy((char *)string,bstring);
  5824.         itok=otok;
  5825.         tok=tk_proc;
  5826.         updatetree();
  5827.  
  5828.         if(searchteg&&(!(current_proc_type&f_static))&&(current_proc_type&f_typeproc)==tp_pascal)AddThis();
  5829.         nexttok();
  5830.         blockproc=TRUE;
  5831. //      printf("tok=%d\n",tok);
  5832.         if(tok==tk_inline){
  5833.                 inlineflag=1;
  5834.                 nexttok();
  5835.         }
  5836.         else if(paramsize)Enter();      // PUSH BP  MOV BP,SP
  5837.         if(tok==tk_colon&&(current_proc_type&fs_constructor)!=0){
  5838.                 do{
  5839.                         AddBackBuf(inptr2,cha2);
  5840.                 }while(tok==tk_camma);
  5841.                 nexttok();
  5842.         }
  5843.         regs|=CheckUses();
  5844.         CorrectParamVar();
  5845.         if(tok!=tk_openbrace)declarelocals(0,inlineflag);
  5846. #ifdef OPTVARCONST
  5847.         ClearLVIC();
  5848. #endif
  5849. //      numblocks++;    //íà ýòîì ìåñòå äëÿ ðàíåãî îïðåäåëåíèÿ ::var
  5850.         expecting(tk_openbrace);
  5851.         declarelocals(1,inlineflag);
  5852.         retproc=FALSE;
  5853.         if(paramsize||localsize/*||(lstructlist!=NULL)*/){
  5854.                 initBP=1;
  5855.                 if(inlineflag)warninline();
  5856.         }
  5857.  
  5858. #ifdef __NEWLEX__
  5859.         doblockstart(otok.name);
  5860. #endif
  5861.         doblock2();                                                     // do proc
  5862.         if(current_proc_type&fs_destructor){
  5863. elementteg *bazael=searchteg->baza;
  5864.                 for(i=0;i<searchteg->numoper;i++){
  5865.                         if((bazael+i)->tok==tk_baseclass)CallDestructor((structteg *)(bazael+i)->rec);
  5866.                 }
  5867.         }
  5868.         i=numreturn;
  5869.         setreturn();
  5870.         if(inlineflag==0&&retproc==FALSE&&(i||(lastcommand!=tk_goto&&lastcommand!=tk_GOTO)))leaveproc();
  5871.         endblock();
  5872.         initBP=0;
  5873.         strcpy((char *)string,bstring);
  5874.         itok=otok;
  5875.         tok=tk_proc;
  5876.         itok.size=outptr-procedure_start;
  5877.         itok.rec->recpost=regs;
  5878. //      printf("reg=%08X set=%s\n",regs,itok.name);
  5879. #ifdef OPTVARCONST
  5880.         if(inlineflag)itok.flag|=f_useidx;
  5881. #endif
  5882.         updatetree();
  5883.         if(mapfile)mapfun(startline);
  5884.         i=linenumber;
  5885.         linenumber=startline;
  5886.         killlocals();
  5887.         linenumber=i;
  5888.         free(bstring);
  5889.         optimizespeed=ooptimizespeed;
  5890.         useinline=oinline;
  5891.         *(unsigned int *)&idxregs=oregidx;
  5892.         if(searchteg)searchteg=NULL;
  5893.         blockproc=FALSE;
  5894.         ESPloc=oESPloc;
  5895.         nexttok();
  5896. }
  5897.  
  5898. void insertproc(/*int sizepar*/)
  5899. {
  5900. unsigned char oinline,ooptimizespeed;
  5901. struct treelocalrec  *otlr;
  5902. struct structteg *olteglist;
  5903. //struct idrec     *olstructlist;
  5904. struct idrec *rec;
  5905. unsigned int oparamsize;
  5906. unsigned int olocalsize;
  5907. unsigned char oinsertmode;
  5908. unsigned int onumblocks;        //íîìåð âëîæåííîãî áëîêà
  5909. unsigned int osizestack;
  5910. RETLIST *olistreturn;
  5911. unsigned int onumreturn;
  5912. int oinlineflag;
  5913. SAVEREG *osavr;
  5914. unsigned int oaddESP=addESP;
  5915.         addESP=0;
  5916.         clearregstat();
  5917.         osavr=psavereg;
  5918.         psavereg=(SAVEREG*)MALLOC(sizeof(SAVEREG));
  5919.         oinsertmode=insertmode;
  5920.         insertmode=TRUE;        //ôëàã ðåæèìà âñòàâêè
  5921.         oinline=useinline;
  5922.         ooptimizespeed=optimizespeed;
  5923.         current_proc_type=itok.flag;
  5924.         rec=itok.rec;
  5925.         otlr=tlr;
  5926.         olteglist=ltegtree;
  5927. //      olstructlist=lstructlist;
  5928.         oinlineflag=inlineflag;
  5929.         osizestack=sizestack;
  5930.         sizestack=0;
  5931.         tlr=NULL;
  5932.         ltegtree=NULL;
  5933. //      lstructlist=0;
  5934.         oparamsize=paramsize;
  5935.         olocalsize=localsize;
  5936.         onumblocks=numblocks;
  5937.         olistreturn=listreturn;
  5938.         onumreturn=numreturn;
  5939.         paramsize=0;
  5940.         localsize=0;
  5941.         numblocks=0;    //íîìåð âëîæåííîãî áëîêà
  5942.         listreturn=NULL;
  5943.         numreturn=0;
  5944.         inlineflag=0;
  5945.         nextexpecting2(tk_openbracket);
  5946.         if(tok!=tk_closebracket){
  5947.                 if((current_proc_type&f_typeproc)!=tp_fastcall)declareparams();
  5948.                 else declareparamreg();
  5949.         }
  5950.         CorrectParamVar();
  5951.         nexttok();
  5952.         if(tok==tk_inline){
  5953.                 nexttok();
  5954.                 inlineflag=1;
  5955.                 expecting(tk_openbrace);
  5956.         }
  5957.         else{
  5958.                 if((current_proc_type&f_typeproc)!=tp_fastcall&&paramsize>0)Enter();    // PUSH BP  MOV BP,SP
  5959.                 rec->recpost|=CheckUses();
  5960.                 if(tok!=tk_openbrace)declarelocals(0);
  5961.                 expecting(tk_openbrace);
  5962.                 declarelocals(1);
  5963.         }
  5964.         retproc=FALSE;
  5965. #ifdef OPTVARCONST
  5966.         ClearLVIC();
  5967. #endif
  5968.         startblock();
  5969.         doblock2();
  5970.         sizestack=osizestack;                                           // do proc
  5971.         setreturn();
  5972.         endblock();
  5973.         RestoreSaveReg();
  5974.         if(inlineflag==0&&(localsize||paramsize)&&(ESPloc==FALSE||am32==FALSE))Leave();
  5975.         killlocals(/*0*/);
  5976.         optimizespeed=ooptimizespeed;
  5977.         useinline=oinline;
  5978.         paramsize=oparamsize;
  5979.         localsize=olocalsize;
  5980.         tlr=otlr;
  5981.         ltegtree=olteglist;
  5982. //      lstructlist=olstructlist;
  5983.         insertmode=oinsertmode;
  5984.         numblocks=onumblocks;
  5985.         listreturn=olistreturn;
  5986.         numreturn=onumreturn;
  5987.         inlineflag=oinlineflag;
  5988.         free(psavereg);
  5989.         psavereg=osavr;
  5990.         addESP=oaddESP;
  5991. //      nexttok();
  5992. //      printf("tok=%d\n",tok);
  5993. }
  5994.  
  5995. void AddTypeVar(int type,int pos)
  5996. {
  5997.         switch(type){
  5998.                 case tk_char:
  5999.                         param[pos]='C';
  6000.                         break;
  6001.                 case tk_byte:
  6002.                         param[pos]='B';
  6003.                         break;
  6004.                 case tk_int:
  6005.                         param[pos]='I';
  6006.                         break;
  6007.                 case tk_word:
  6008.                         param[pos]='W';
  6009.                         break;
  6010.                 case tk_long:
  6011.                         param[pos]='L';
  6012.                         break;
  6013.                 case tk_dword:
  6014.                         param[pos]='D';
  6015.                         break;
  6016.                 case tk_float:
  6017.                         param[pos]='F';
  6018.                         break;
  6019.                 case tk_qword:
  6020.                         param[pos]='Q';
  6021.                         break;
  6022.                 case tk_double:
  6023.                         param[pos]='E';
  6024.                         break;
  6025.  
  6026.         }
  6027. }
  6028.  
  6029. void declareparamreg() /* declare procedure parameters */
  6030. {
  6031. int i=0,num=1;
  6032. unsigned char j=0;
  6033.         do{
  6034.                 if(tok>=tk_char&&tok<=tk_double){
  6035.                         AddTypeVar(tok,i++);
  6036.                         nexttok();
  6037.                         j=1;
  6038.                 }
  6039.                 else{
  6040.                         switch(tok){
  6041.                                 case tk_beg:
  6042.                                         if(j==0)param[i++]='B';
  6043.                                         param[i++]=(char)(itok.number+0x30);
  6044.                                         j=0;
  6045.                                         break;
  6046.                                 case tk_reg:
  6047.                                         if(j==0)param[i++]='W';
  6048.                                         param[i++]=(char)(itok.number+0x30);
  6049.                                         j=0;
  6050.                                         break;
  6051.                                 case tk_reg32:
  6052.                                         if(j==0)param[i++]='D';
  6053.                                         param[i++]=(char)(itok.number+0x30);
  6054.                                         j=0;
  6055.                                         break;
  6056.                                 case tk_reg64:
  6057.                                         param[i++]='Q';
  6058.                                         param[i++]=(char)((itok.number&255)+0x30);
  6059.                                         param[i++]=(char)((itok.number/256)+0x30);
  6060.                                         j=0;
  6061.                                         break;
  6062.                                 case tk_fpust:
  6063.                                         param[i++]='S';
  6064.                                         param[i++]=(char)(itok.number+0x30);
  6065.                                         j=0;
  6066.                                         break;
  6067.                                 case tk_closebracket:
  6068.                                         if(j==0)goto endproc;
  6069.                                 default: edpip(num);
  6070.                         }
  6071.                         nexttok();
  6072.                         if(tok==tk_camma){
  6073.                                 if(j!=0){
  6074.                                         edpip(num);
  6075.                                         param[i++]='0';
  6076.                                         j=0;
  6077.                                 }
  6078.                                 nexttok();
  6079.                         }
  6080.                 }
  6081.                 num++;
  6082.         }while(tok!=tk_closebracket);
  6083. endproc:
  6084.         if(j!=0){
  6085.                 edpip(num-1);
  6086.                 param[i++]='0';
  6087.         }
  6088.         param[i]=0;
  6089. }
  6090.  
  6091. void AddMultiPoint(int pos)
  6092. {
  6093.         param[pos]='A';
  6094.         nexttok();
  6095.         if(tok!=tk_closebracket)SwTok(tk_closebracket);
  6096. }
  6097.  
  6098. void declareparamstack() /* declare procedure parameters */
  6099. {
  6100. int i=0,num=1;
  6101. unsigned char j=0;
  6102. /*
  6103.  1 - îáúÿâëåí òèï
  6104.  2 - áûëà çàïÿòàÿ
  6105.  3 - áûëà òî÷êà ñ çàïÿòîé
  6106.  4 -
  6107.  5 - áûë èäåíòèôèêàòîð
  6108.  6 - òèï void
  6109.  */
  6110. int typevar=tk_multipoint;
  6111. structteg *tteg=NULL;
  6112. int size;
  6113.         do{
  6114.                 if(tok==tk_struct)nexttok();
  6115.                 if(tok>=tk_char&&tok<=tk_double){
  6116.                         if(j>3||j==1)edpip(num);
  6117.                         j=1;
  6118.                         typevar=tok;
  6119.                         nexttok();
  6120.                 }
  6121.                 else if((tteg=FindTeg(TRUE))!=NULL){
  6122.                         size=Align(tteg->size,(am32+1)*2);
  6123. //                      printf("%s size=%u\n",itok.name,size);
  6124.                         j=1;
  6125.                         typevar=tk_struct;
  6126.                         nexttok();
  6127.                 }
  6128.                 while(tok==tk_mult){
  6129.                         param[i++]='*';
  6130.                         nexttok();
  6131.                 }
  6132.                 if(tok==tk_camma){
  6133.                         if(j==1){
  6134.                                 if(typevar==tk_struct)i+=sprintf(&param[i],"T%u",size);
  6135.                                 else AddTypeVar(typevar,i++);
  6136.                         }
  6137.                         else if(j!=5)edpip(num);
  6138.                         j=2;
  6139.                         num++;
  6140.                 }
  6141.                 else if(tok==tk_semicolon){
  6142.                         if(j==1){
  6143.                                 if(typevar==tk_struct)i+=sprintf(&param[i],"T%u",size);
  6144.                                 else AddTypeVar(typevar,i++);
  6145.                         }
  6146.                         else if(j!=5)edpip(num);
  6147.                         j=3;
  6148.                         num++;
  6149.                 }
  6150.                 else if(tok==tk_multipoint){
  6151.                         AddMultiPoint(i++);
  6152.                         break;
  6153.                 }
  6154.                 else if(tok==tk_closebracket){
  6155.                         if(j==0)param[i++]='A';
  6156.                         else if(j==1){
  6157.                                 if(typevar==tk_struct)i+=sprintf(&param[i],"T%u",size);
  6158.                                 else AddTypeVar(typevar,i++);
  6159.                         }
  6160.                         else if(j<4)edpip(num);
  6161.                         break;
  6162.                 }
  6163.                 else if(tok==tk_void){
  6164.                         if(j!=0)edpip(num);
  6165.                         param[i++]='V';
  6166.                         j=6;
  6167.                 }
  6168.                 else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){
  6169.                         if(j==1){
  6170.                                 if(typevar==tk_struct)i+=sprintf(&param[i],"T%u",size);
  6171.                                 else AddTypeVar(typevar,i++);
  6172.                         }
  6173.                         else if(j<4){
  6174.                                 switch(tok){
  6175.                                         case tk_beg: param[i++]='B'; break;
  6176.                                         case tk_reg: param[i++]='W'; break;
  6177.                                         case tk_reg32: param[i++]='D'; break;
  6178.                                         case tk_fpust: param[i++]='S'; break;
  6179.                                         case tk_reg64:
  6180.                                                 param[i++]='Q';
  6181.                                                 param[i++]=(char)((itok.number&255)+0x30);
  6182.                                                 itok.number/=256;
  6183.                                                 break;
  6184.                                 }
  6185.                         }
  6186.                         else edpip(num);
  6187.                         param[i++]=(char)(itok.number+0x30);
  6188.                         j=5;
  6189.                 }
  6190.                 else{
  6191.                         if(j==1||j==2){
  6192.                                 if(typevar==tk_struct)i+=sprintf(&param[i],"T%u",size);
  6193.                                 else AddTypeVar(typevar,i++);
  6194.                         }
  6195.                         else edpip(num);
  6196.                         j=5;
  6197.                 }
  6198.                 nexttok();
  6199.         }while(tok!=tk_eof);
  6200.         param[i]=0;
  6201. //      puts(param);
  6202. }
  6203.  
  6204. void CorrectParamVar()
  6205. {
  6206. unsigned int addnum;
  6207. int fspin;
  6208. struct localrec *ptr;
  6209.         if(paramsize==0)return;
  6210.         if(insertmode)addnum=0; //ret-address
  6211.         else addnum=2;
  6212.         if(ESPloc==FALSE||am32==FALSE)addnum+=2;        //EBP
  6213.         if((current_proc_type&f_far))addnum+=2;// move over seg on stack
  6214.         if(am32)addnum*=2;
  6215.         if((current_proc_type&f_typeproc)==tp_cdecl||(current_proc_type&f_typeproc)==tp_stdcall)fspin=FALSE;
  6216.         else fspin=TRUE;
  6217. treelocalrec *ntlr=tlr;
  6218.         while(ntlr&&ntlr->level>1)ntlr=ntlr->next;
  6219.         for(ptr=ntlr->lrec;;ptr=ptr->rec.next){
  6220.                 if(ptr->rec.type==tp_paramvar){
  6221.                         if(fspin)ptr->rec.recnumber=paramsize-ptr->rec.recnumber-Align(ptr->rec.recsize,am32==FALSE?2:4);
  6222.                         ptr->rec.recnumber+=addnum;
  6223.                 }
  6224.                 if(ptr->rec.next==NULL)break;
  6225.         }
  6226. }
  6227.  
  6228. void declareparams()                                                                     /* declare procedure parameters */
  6229. {
  6230. int paramtok,sparamtok,i=0,type;
  6231. char flag=33;
  6232. int numpointr;
  6233. localrec *lrec;
  6234. structteg *tteg=NULL,*nteg;
  6235.         do{
  6236.                 if(flag!=33)nexttok();
  6237.                 flag=1;
  6238.                 if(tok==tk_multipoint){
  6239.                         AddMultiPoint(i++);
  6240.                         break;
  6241.                 }
  6242.                 if(tok==tk_void){
  6243.                         param[i++]='V';
  6244.                         nexttok();
  6245.                         if(tok!=tk_closebracket)SwTok(tk_closebracket);
  6246.                         break;
  6247.                 }
  6248.                 if(tok>=tk_char&&tok<=tk_double){
  6249.                         type=tok;
  6250.                         SetNewTok(tok,variable);
  6251.                         paramtok=tok;
  6252.                 }
  6253.                 else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust)flag=3;
  6254.                 else{
  6255.                         if(tok==tk_struct)nexttok();
  6256.                         if((tteg=FindTeg(TRUE))!=NULL)paramtok=tk_struct;
  6257.                         else{
  6258.                                 datatype_expected();
  6259.                                 flag=0;
  6260.                                 nexttok();
  6261.                         }
  6262.                 }
  6263.                 if(flag){
  6264.                         do{
  6265.                                 numpointr=0;
  6266.                                 skipfind=TRUE;
  6267.                                 if(flag!=3)nexttok();
  6268.                                 while(tok==tk_mult){
  6269.                                         nexttok();
  6270.                                         numpointr++;
  6271.                                         param[i++]='*';
  6272.                                 }
  6273.                                 if(tok==tk_id||tok==tk_ID){     //ïðîâåðèòü íà òèïû îïðåäåëåííûå ÷åðåç define
  6274.                                         skipfind=FALSE;
  6275.                                         int otok=tok;
  6276.                                         searchtree(&ptok,&otok,string);
  6277.                                         if(otok>=tk_char&&otok<=tk_double){
  6278.                                                 tok=otok;
  6279.                                                 itok=ptok;
  6280.                                         }
  6281.                                         skipfind=TRUE;
  6282.                                 }
  6283.                                 if(tok==tk_struct){
  6284.                                         nexttok();
  6285.                                         if((tteg=FindTeg(TRUE))!=NULL){
  6286.                                                 paramtok=tk_struct;
  6287.                                                 nexttok();
  6288.                                         }
  6289.                                         else{
  6290.                                                 edpip();
  6291.                                                 nexttok();
  6292.                                                 goto endparam1;
  6293.                                         }
  6294.                                 }
  6295.                                 else {
  6296.                                         if((nteg=FindTeg(TRUE))!=NULL){
  6297.                                                 tteg=nteg;
  6298.                                                 paramtok=tk_struct;
  6299.                                                 nexttok();
  6300.                                         }
  6301.                                         else{
  6302.                                                 if(tok>=tk_char&&tok<=tk_double){
  6303.                                                         type=tok;
  6304.                                                         SetNewTok(tok,variable);
  6305.                                                         paramtok=tok;
  6306.                                                         nexttok();
  6307.                                                         while(tok==tk_mult){
  6308.                                                                 nexttok();
  6309.                                                                 numpointr++;
  6310.                                                                 param[i++]='*';
  6311.                                                         }
  6312.                                                         flag=2;
  6313.                                                 }
  6314.                                                 skipfind=FALSE;
  6315.                                                 if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){
  6316.                                                         if(flag==2)AddTypeVar(type,i++);
  6317.                                                         else{
  6318.                                                                 switch(tok){
  6319.                                                                         case tk_beg: param[i++]='B'; break;
  6320.                                                                         case tk_reg: param[i++]='W'; break;
  6321.                                                                         case tk_reg32: param[i++]='D'; break;
  6322.                                                                         case tk_fpust: param[i++]='S'; break;
  6323.                                                                         case tk_reg64:
  6324.                                                                                 param[i++]='Q';
  6325.                                                                                 param[i++]=(char)((itok.number&255)+0x30);
  6326.                                                                                 itok.number/=256;
  6327.                                                                                 break;
  6328.                                                                 }
  6329.                                                         }
  6330.                                                         param[i++]=(unsigned char)(itok.number+0x30);
  6331.                                                         flag=1;
  6332.                                                         goto endparam1;
  6333.                                                 }
  6334.                                         }
  6335.                                 }
  6336.                                 sparamtok=paramtok;
  6337.                                 if(tok==tk_multipoint){
  6338.                                         AddMultiPoint(i++);
  6339.                                         break;
  6340.                                 }
  6341.                                 if(tok!=tk_ID&&tok!=tk_id){
  6342.                                         idalreadydefined();
  6343.                                         break;
  6344.                                 }
  6345.                                 int lsize;
  6346.                                 if(am32)lsize=4;
  6347.                                 else{
  6348.                                         lsize=2;
  6349.                                         if(sparamtok>=tk_longvar&&sparamtok<=tk_floatvar&&numpointr==0)
  6350.                                                  lsize+=2;//add 2 more bytes
  6351.                                 }
  6352.                                 if((sparamtok==tk_qwordvar||sparamtok==tk_doublevar)&&numpointr==0)lsize=8;
  6353.                                 AddTypeVar(type,i++);
  6354.                                 if(sparamtok==tk_struct){
  6355. //idrec *newrec,*trec;
  6356.                                         lsize=Align(tteg->size,(am32+1)*2);
  6357.                                         i+=sprintf(&param[i],"T%u",lsize);
  6358. //                                      newrec=(struct idrec *)MALLOC(sizeof(struct idrec));
  6359. //                                      if(lstructlist==NULL)lstructlist=newrec;
  6360. //                                      else{
  6361. //                                              trec=lstructlist;
  6362. //                                              while(trec->left!=NULL)trec=trec->left;
  6363. //                                              trec->left=newrec;
  6364. //                                      }
  6365. //                                      newrec->right=newrec->left=NULL;
  6366.                                         lrec=addlocalvar(itok.name,tk_structvar,paramsize);
  6367.                                         lrec->rec.newid=(char *)tteg;
  6368.                                         lrec->rec.flag=tteg->flag;
  6369.                                         lrec->rec.recrm=1;
  6370.                                         lrec->rec.recpost=LOCAL;
  6371.                                         goto endparam;
  6372.                                 }
  6373.                                 lrec=addlocalvar(itok.name,sparamtok,paramsize);
  6374.                                 lrec->rec.npointr=(unsigned short)numpointr;
  6375. endparam:
  6376.                                 lrec->rec.type=tp_paramvar;
  6377.                                 lrec->rec.recsize=lsize;
  6378.                                 paramsize+=lsize;
  6379. endparam1:
  6380.                                 nexttok();
  6381.                         }while(tok==tk_camma);
  6382.                 }
  6383.         }while(tok==tk_semicolon);
  6384.         param[i]=0;
  6385. //      puts(param);
  6386. }
  6387.  
  6388. void CharToBackBuf(char c)
  6389. {
  6390.         if(SizeBackBuf==0){
  6391.                 MaxSizeBackBuf=STRLEN;
  6392.                 BackTextBlock=(char *)MALLOC(STRLEN);
  6393.         }
  6394.         else if(SizeBackBuf==MaxSizeBackBuf){
  6395.                 MaxSizeBackBuf+=STRLEN;
  6396.                 BackTextBlock=(char *)REALLOC(BackTextBlock,MaxSizeBackBuf);
  6397.         }
  6398.         BackTextBlock[SizeBackBuf++]=c;
  6399. }
  6400.  
  6401. void  AddBackBuf(int oinptr,char ocha)
  6402. //ñîçäàòü ëèñòèíã íà÷àëüíîé èíèöèàëèçàöèè ëîñàëüíûõ ïåðåìåííûõ
  6403. {
  6404. int numblock=0;
  6405. unsigned char save;
  6406. char bcha;
  6407.         inptr=oinptr;
  6408.         cha=ocha;
  6409.         for(;;){
  6410.                 save=TRUE;
  6411.                 switch(cha){
  6412.                         case '(':
  6413.                         case '{':
  6414.                         case '[':
  6415.                                 numblock++;
  6416.                                 break;
  6417.                         case ')':
  6418.                         case '}':
  6419.                         case ']':
  6420.                                 numblock--;
  6421.                                 if(numblock<0)return;
  6422.                                 break;
  6423.                         case ',':
  6424.                                 if(numblock>0)break;
  6425.                                 tok=tk_camma;
  6426.                                 goto endp;
  6427.                         case ';':
  6428.                         case 26:
  6429.                                 tok=tk_semicolon;
  6430. endp:
  6431.                                 CharToBackBuf(';');
  6432.                                 nextchar();
  6433.                                 inptr2=inptr;
  6434.                                 cha2=cha;
  6435.                                 return;
  6436.                         case '/':       //îòñëåäèòü êîììåíòàðèè
  6437.                                 nextchar();
  6438.                                 if(cha=='*'){
  6439.                                         do{
  6440.                                                 nextchar();
  6441.                                                 if(cha=='*'){
  6442.                                                         nextchar();
  6443.                                                         if(cha=='/'){
  6444.                                                                 save=FALSE;
  6445.                                                                 break;
  6446.                                                         }
  6447.                                                 }
  6448.                                         }while(cha!=26);
  6449.                                 }
  6450.                                 else if(cha=='/'){
  6451.                                         do{
  6452.                                                 nextchar();
  6453.                                         }while(cha!=13&&cha!=26);
  6454.                                 }
  6455.                                 else CharToBackBuf('/');
  6456.                                 break;
  6457.                         case '"':
  6458.                         case '\'':
  6459.                                 bcha=cha;
  6460.                                 do{
  6461.                                         CharToBackBuf(cha);
  6462.                                         nextchar();
  6463.                                         if(cha=='\\'){
  6464.                                                 CharToBackBuf(cha);
  6465.                                                 nextchar();
  6466.                                                 CharToBackBuf(cha);
  6467.                                                 nextchar();
  6468.                                         }
  6469.                                 }while(cha!=bcha);
  6470.                                 break;
  6471.                 }
  6472.                 if(save)CharToBackBuf(cha);
  6473.                 nextchar();
  6474.         }
  6475. }
  6476.  
  6477. void RunBackText()
  6478. {
  6479. ITOK oitok,ostructadr;
  6480. SINFO ostr;
  6481. unsigned char *oldinput;
  6482. unsigned int oldinptr,oldendinptr;
  6483. unsigned char bcha;
  6484. int otok,otok2;
  6485. char *ostartline;
  6486. char *ostring,*obufrm;
  6487. COM_MOD *ocurmod;
  6488.         ostring=BackString((char *)string);
  6489.         oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå
  6490.         oldinptr=inptr2;
  6491.         ostructadr=structadr;
  6492.         bcha=cha2;
  6493.         oldendinptr=endinptr;
  6494.         otok=tok;
  6495.         otok2=tok2;
  6496.         oitok=itok;
  6497.         ostr=strinf;
  6498.         strinf.bufstr=NULL;
  6499.         obufrm=bufrm;
  6500.         bufrm=NULL;
  6501.  
  6502.         ocurmod=cur_mod;
  6503.         cur_mod=NULL;
  6504.  
  6505.         input=(unsigned char *)BackTextBlock;
  6506.         inptr2=1;
  6507.         cha2=input[0];
  6508.         tok=tk_openbrace;
  6509.         SizeBackBuf=0;
  6510.         ostartline=startline;
  6511.         startline=(char*)input;
  6512.         endinptr=strlen((char *)input);
  6513.         endinput=startline+endinptr;
  6514.  
  6515.         doblock();
  6516.  
  6517.         endoffile=0;
  6518.         startline=ostartline;
  6519.         strinf=ostr;
  6520.         free(input);
  6521.         input=oldinput;
  6522.         inptr2=oldinptr;
  6523.         cha2=bcha;
  6524.         endinptr=oldendinptr;
  6525.         tok=otok;
  6526.         itok=oitok;
  6527.         if(bufrm)free(bufrm);
  6528.         bufrm=obufrm;
  6529.         tok2=otok2;
  6530.         strcpy((char *)string,ostring);
  6531.         if(strinf.bufstr)free(strinf.bufstr);
  6532.         structadr=ostructadr;
  6533.         free(ostring);
  6534.  
  6535.         cur_mod=ocurmod;
  6536. }
  6537.  
  6538. int PushLocInit(int ofs)
  6539. {
  6540. ITOK oitok,ostructadr,wtok;
  6541. SINFO ostr;
  6542. unsigned char *oldinput;
  6543. unsigned int oldinptr,oldendinptr;
  6544. unsigned char bcha;
  6545. int otok,otok2;
  6546. char *ostartline;
  6547. char *ostring,*obufrm;
  6548. int retcode=FALSE;
  6549. //      if(bufrm)puts(bufrm);
  6550.         ostring=BackString((char *)string);
  6551.         oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå
  6552.         oldinptr=inptr2;
  6553.         ostructadr=structadr;
  6554.         bcha=cha2;
  6555.         oldendinptr=endinptr;
  6556.         otok=tok;
  6557.         otok2=tok2;
  6558.         oitok=itok;
  6559.         ostr=strinf;
  6560.         strinf.bufstr=NULL;
  6561.         obufrm=bufrm;
  6562.         bufrm=NULL;
  6563.         input=(unsigned char *)BackTextBlock;
  6564.         inptr2=ofs;
  6565.         ostartline=startline;
  6566.         cha2=input[inptr2++];
  6567.         endinptr=strlen((char *)input);
  6568.         startline=(char *)input+ofs;
  6569.         endinput=startline+endinptr;
  6570.         nexttok();
  6571.         wtok=itok;
  6572.         nexttok();
  6573.         nexttok();
  6574.         if((retcode=Push(&wtok))!=FALSE){
  6575.                 retcode=TRUE;
  6576.                 for(inptr2=ofs;;inptr2++){
  6577.                         cha2=input[inptr2];
  6578.                         input[inptr2]=' ';
  6579.                         if(cha2==';'||cha2==0)break;
  6580.                 }
  6581.         }
  6582.         endoffile=0;
  6583.         startline=ostartline;
  6584.         strinf=ostr;
  6585.         input=oldinput;
  6586.         inptr2=oldinptr;
  6587.         cha2=bcha;
  6588.         endinptr=oldendinptr;
  6589.         tok=otok;
  6590.         itok=oitok;
  6591.         if(bufrm)free(bufrm);
  6592.         bufrm=obufrm;
  6593.         tok2=otok2;
  6594.         strcpy((char *)string,ostring);
  6595.         if(strinf.bufstr)free(strinf.bufstr);
  6596.         structadr=ostructadr;
  6597.         free(ostring);
  6598.         return retcode;
  6599. }
  6600.  
  6601. int pushinit(int localline,unsigned int ofs)
  6602. {
  6603. int oline=linenumber;
  6604. COM_MOD *bcur_mod;
  6605. int retcode;
  6606.         linenum2=localline;
  6607.         bcur_mod=cur_mod;
  6608.         cur_mod=NULL;
  6609.         retcode=PushLocInit(ofs);
  6610.         cur_mod=bcur_mod;
  6611.         linenumber=linenum2=oline;
  6612.         return retcode;
  6613. }
  6614.  
  6615. int PossiblePush()
  6616. {
  6617. int retcode=FALSE;
  6618.         nexttok();
  6619.         switch(tok){
  6620.                 case tk_dwordvar:
  6621.                 case tk_longvar:
  6622.                 case tk_reg32:
  6623.                         if(am32==FALSE)break;
  6624.                 case tk_postnumber:
  6625.                 case tk_string:
  6626.                 case tk_intvar:
  6627.                 case tk_wordvar:
  6628.                 case tk_reg:
  6629.                         if(tok2==tk_semicolon||tok2==tk_camma)retcode=TRUE;
  6630.                         break;
  6631.                 case tk_undefofs:
  6632.                         tok=tk_number;
  6633.                         goto chnum;
  6634.                 case tk_minus:
  6635.                         if(tok2!=tk_number)break;
  6636.                         nexttok();
  6637.                 case tk_number:
  6638. chnum:
  6639.                         doconstlongmath();
  6640.                         if(tok==tk_semicolon||tok==tk_camma)retcode=TRUE;
  6641.                         break;
  6642.         }
  6643.  
  6644. ////   New 20.07.07 22:01
  6645.         if(bufrm){
  6646.                 free(bufrm);
  6647.                 bufrm=NULL;
  6648.         }
  6649.         if(strinf.bufstr){
  6650.                 free(strinf.bufstr);
  6651.                 strinf.bufstr=NULL;
  6652.         }
  6653. ////////////////////////////
  6654.  
  6655.         return retcode;
  6656. }
  6657.  
  6658. #define MAXLOCVAR 128
  6659.  
  6660. void declarelocals(int mode,int finline) /* declare locals */
  6661. /*-----------------01.06.02 15:12-------------------
  6662. mode = 0 if local vars prior {
  6663. mode = 1 if local vars after {
  6664. --------------------------------------------------*/
  6665. {
  6666. unsigned int size,ssize,localtok;
  6667. int binptr;
  6668. int flag=0;
  6669. char bcha;
  6670. int slocaltok;
  6671. int numpointr,type;
  6672. unsigned int loop;
  6673. static int localline;
  6674. static int numinit;
  6675. static int maxlocvar;
  6676. static LILV *lilv=NULL;
  6677. static int headerinit;
  6678.         if(localsize==0)localline=0;
  6679.         if(lilv==NULL){
  6680.                 numinit=0;
  6681.                 lilv=(LILV *)MALLOC(sizeof(LILV)*MAXLOCVAR);
  6682.                 maxlocvar=MAXLOCVAR;
  6683.                 if(paramsize&&(!finline))headerinit=TRUE;
  6684.                 else headerinit=FALSE;
  6685.         }
  6686.         dynamic_flag=0;
  6687.         do{
  6688.                 while(tok==tk_semicolon)nexttok();
  6689.                 if(tok==tk_static){
  6690.                         flag|=f_static;
  6691.                         nexttok();
  6692.                 }
  6693.                 size=0;
  6694.                 switch(tok){
  6695.                         case tk_union:
  6696.                                 loop=dounion(0,flag);
  6697.                                 goto locstruct;
  6698.                         case tk_struct:
  6699.                                 loop=LocalStruct(flag,&localline);
  6700. locstruct:
  6701.                                 (lilv+numinit)->size=-loop;
  6702.                                 break;
  6703.                         case tk_int: localtok=tk_intvar; size=2; break;
  6704.                         case tk_word: localtok=tk_wordvar; size=2; break;
  6705.                         case tk_char: localtok=tk_charvar; size=1; break;
  6706.                         case tk_byte: localtok=tk_bytevar; size=1; break;
  6707.                         case tk_long: localtok=tk_longvar; size=4; break;
  6708.                         case tk_dword: localtok=tk_dwordvar; size=4; break;
  6709.                         case tk_float: localtok=tk_floatvar; size=4; break;
  6710.                         case tk_qword: localtok=tk_qwordvar; size=8; break;
  6711.                         case tk_double: localtok=tk_doublevar; size=8; break;
  6712.                         default:
  6713.                                 if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_pointer||tok==tk_proc
  6714.                                                 ||tok==tk_declare||tok==tk_undefproc||tok==tk_structvar||
  6715.                                                 (FindTeg(FALSE)==NULL&&FindTeg(TRUE)==NULL)){
  6716.                                         if(mode==0){
  6717.                                                 (lilv+numinit)->size=0;
  6718.                                                 datatype_expected();
  6719.                                                 nexttok();
  6720.                                         }
  6721.                                         else{
  6722.                                                 if(localsize){
  6723.                                                         if(!finline){
  6724.                                                                 numpointr=0;
  6725.                                                                 if(SizeBackBuf){
  6726.                                                                         BackTextBlock[SizeBackBuf]=0;
  6727.                                                                         for(type=numinit-1,numpointr=0;type>=0;type--){//îïð ÷èñëî èíèö. ïåðåìåííûõ â êîíöå
  6728.                                                                                 if((lilv+type)->size<=0)break;
  6729.                                                                                 numpointr+=(lilv+type)->size;
  6730.                                                                         }
  6731.                                                                         type++; //÷èñëî îñòàâøèõñÿ ïåðåìåííûõ
  6732.                                                                         ssize=type;
  6733.                                                                 }
  6734.                                                                 size=localsize;
  6735.                                                                 if(lilv->size<=0&&optimizespeed==0&&chip>1){
  6736.                                                                         size-=numpointr;
  6737.                                                                         if(headerinit)outptr-=3;                                        /* remove PUSH BP and MOV BP,SP */
  6738.                                                                         op(0xC8);                                               /* ENTER */
  6739.                                                                         outword(size);  /* # of locals */
  6740.                                                                         op(0x00);                                               /* level = 0 */
  6741.                                                                         flag=0;
  6742.                                                                         type=0;
  6743.                                                                         headerinit=TRUE;
  6744.                                                                         size=numpointr;
  6745.                                                                 }
  6746.                                                                 else{
  6747.                                                                         if(headerinit==FALSE){
  6748.                                                                                 Enter();
  6749.                                                                                 headerinit=TRUE;
  6750.                                                                         }
  6751.                                                                         flag=1;
  6752.                                                                 }
  6753.                                                                 if(SizeBackBuf){
  6754.                                                                         if(lilv->size>0){       //åñòü èíèö ïåðåìåííûå â íà÷àëå
  6755.                                                                                 for(loop=0;loop<numinit;loop++){
  6756. //                                                                              printf("size%d=%d %s\n",loop,(lilv+loop)->size,BackTextBlock);
  6757.                                                                                         if((lilv+loop)->size<=0)break;
  6758.                                                                                         if(pushinit(localline,(lilv+loop)->ofs)==FALSE)break;
  6759.                                                                                         (lilv+loop)->rec->fuse|=INITVAR;
  6760.                                                                                         size-=Align((lilv+loop)->size,(am32==FALSE?2:4));
  6761.                                                                                         type--;
  6762.                                                                                 }
  6763.                                                                         }
  6764.                                                                         if(size){
  6765.                                                                                 binptr=size-numpointr;
  6766.                                                                                 if(binptr){
  6767.                                                                                         if(!optimizespeed&&type<3&&(type*(am32+1)*2)>=binptr)for(;type!=0;type--)op(0x50+ECX);
  6768.                                                                                         else{
  6769.                                                                                                 if(binptr<128){
  6770.                                                                                                         outword(0xEC83);
  6771.                                                                                                         op(binptr);
  6772.                                                                                                 }
  6773.                                                                                                 else{
  6774.                                                                                                         outword(0xEC81);
  6775.                                                                                                         if(am32==FALSE)outword(binptr);
  6776.                                                                                                         else outdword((unsigned long)binptr);
  6777.                                                                                                 }
  6778.                                                                                         }
  6779.                                                                                 }
  6780.                                                                                 if(numpointr){
  6781.                                                                                         for(;ssize<numinit;ssize++){
  6782. //                                                                              printf("size%d=%d %s\n",loop,(lilv+loop)->size,BackTextBlock);
  6783.                                                                                                 if(pushinit(localline,(lilv+ssize)->ofs)==FALSE)break;
  6784.                                                                                                 (lilv+ssize)->rec->fuse|=INITVAR;
  6785.                                                                                         }
  6786.                                                                                 }
  6787.                                                                         }
  6788.                                                                 }
  6789.                                                                 else if(flag){
  6790.                                                                         if(localsize<128){
  6791.                                                                                 outword(0xEC83);
  6792.                                                                                 op(localsize);
  6793.                                                                         }
  6794.                                                                         else{
  6795.                                                                                 outword(0xEC81);
  6796.                                                                                 if(am32==FALSE)outword(localsize);
  6797.                                                                                 else outdword((unsigned long)localsize);
  6798.                                                                         }
  6799.                                                                 }
  6800.                                                         }
  6801.                                                         else{   //finline
  6802.                                                                 if(SizeBackBuf!=0){
  6803.                                                                         free(BackTextBlock);
  6804.                                                                         SizeBackBuf=0;
  6805.                                                                 }
  6806.                                                         }
  6807.                                                 }
  6808.                                                 if(psavereg->size){
  6809.                                                         if(psavereg->all){
  6810.                                                                 op(0x60);
  6811.                                                                 addESP+=am32==FALSE?16:32;
  6812.                                                         }
  6813.                                                         else{
  6814.                                                                 for(int i=0;i<8;i++){
  6815.                                                                         if(psavereg->reg[i]){
  6816.                                                                                 op66(psavereg->reg[i]);
  6817.                                                                                 op(0x50+i);
  6818.                                                                                 addESP+=am32==FALSE?2:4;
  6819.  
  6820.                                                                         }
  6821.                                                                 }
  6822.                                                         }
  6823.                                                         if(ESPloc&&am32&&(itok.type==tp_localvar||itok.type==tp_paramvar))itok.number+=addESP;
  6824.                                                 }
  6825. //                                                                              printf("numinit=%d firstinit=%d\n%s\n",numinit,firstinit,BackTextBlock);
  6826.                                                 if(SizeBackBuf!=0){
  6827.                                                         CharToBackBuf('}');
  6828.                                                         CharToBackBuf(0);
  6829.                                                         int oline=linenumber;
  6830.                                                         linenum2=localline;
  6831.                                                         COM_MOD *bcur_mod;
  6832.                                                         bcur_mod=cur_mod;
  6833.                                                         cur_mod=NULL;
  6834.                                                         RunBackText();
  6835.                                                         cur_mod=bcur_mod;
  6836.                                                         linenumber=linenum2=oline;
  6837.                                                 }
  6838.                                                 if(lilv){
  6839.                                                         free(lilv);
  6840.                                                         lilv=NULL;
  6841.                                                 }
  6842.                                                 return;
  6843.                                         }
  6844.                                 }
  6845.                                 else{
  6846.                                         loop=LocalStruct(flag,&localline);
  6847.                                         (lilv+numinit)->size=-loop;
  6848.                                 }
  6849.                                 break;
  6850.                 }
  6851.                 if(size!=0){
  6852.                         do{
  6853.                                 binptr=inptr2;
  6854.                                 bcha=cha2;
  6855.                                 skipfind=TRUE;  //çàïðåòèòü èñêàòü â ãëîáàëüíîì äåðåâå
  6856.                                 nexttok();
  6857.                                 if(tok==tk_static){
  6858.                                         flag|=f_static;
  6859.                                         binptr=inptr2;
  6860.                                         bcha=cha2;
  6861.                                         nexttok();
  6862.                                 }
  6863.                                 slocaltok=localtok;
  6864.                                 ssize=size;
  6865.                                 numpointr=0;
  6866.                                 type=tp_localvar;
  6867.                                 while(tok==tk_mult){
  6868.                                         binptr=inptr2;
  6869.                                         bcha=cha2;
  6870.                                         nexttok();
  6871.                                         numpointr++;
  6872.                                 }
  6873.                                 if(tok!=tk_ID&&tok!=tk_id)idalreadydefined();
  6874.                                 else{
  6875.                                         long numcopyvar;
  6876.                                         numcopyvar=1;
  6877.                                         localrec *lrec=addlocalvar(itok.name,slocaltok,(flag&f_static)==0?localsize:postsize);
  6878.                                         loop=ssize;
  6879.                                         if(numpointr)loop=am32==TRUE?4:2;
  6880.                                         skipfind=FALSE; //ðàçðåøèòü ïîèñê â ãëîáàëüíîì äåðåâå
  6881.                                         if(tok2==tk_openblock){//[
  6882.                                                 nexttok();
  6883.                                                 nexttok();
  6884.                                                 CheckMinusNum();
  6885.                                                 if(tok!=tk_number){
  6886.                                                         numexpected();
  6887.                                                         nexttok();
  6888.                                                 }
  6889.                                                 else numcopyvar=doconstlongmath();
  6890.                                                 loop=numcopyvar*ssize;
  6891.                                                 if(tok!=tk_closeblock)expected(']');
  6892.                                         }
  6893.                                         lrec->rec.recsize=loop;
  6894.                                         if(!mode){
  6895.                                                 nexttok();
  6896.                                         }
  6897.                                         if(flag&f_static){
  6898.                                                 if(tok==tk_assign||(mode&&tok2==tk_assign)){
  6899.                                                         if(mode)nexttok();
  6900.                                                         if(numpointr){
  6901.                                                                 type=tk_char+slocaltok-tk_charvar;
  6902.                                                                 slocaltok=tk_pointer;
  6903.                                                         }
  6904.                                                         lrec->rec.rectok=slocaltok;
  6905.                                                         lrec->rec.recnumber=0;
  6906.                                                         lrec->rec.recpost=DYNAMIC_VAR;
  6907.                                                         lrec->rec.line=linenumber;
  6908.                                                         lrec->rec.file=currentfileinfo;
  6909.                                                         lrec->rec.count=0;
  6910. //                                                      lptr->rec.type=(unsigned short)type;
  6911.                                                         lrec->rec.npointr=(unsigned short)numpointr;
  6912.                                                         lrec->rec.sbuf=dynamic_var();
  6913.                                                         lrec->rec.recsib=type;
  6914.                                                         lrec->rec.type=tp_gvar;
  6915.  
  6916. //                                                      if(strcmp(lrec->rec.recid,"nnil")==0)crec=&lrec->rec;
  6917.  
  6918.                                                 }
  6919.                                                 else{
  6920.                                                         lrec->rec.type=tp_postvar;
  6921.                                                         AddPostData(loop);
  6922.                                                         if(mode)nexttok();
  6923.                                                 }
  6924.                                         }
  6925.                                         else{
  6926.                                                 lrec->rec.type=tp_localvar;
  6927.                                                 lrec->rec.npointr=(unsigned short)numpointr;
  6928.                                                 localsize+=loop;
  6929.                                                 if(mode)nexttok();
  6930.                                                 (lilv+numinit)->size=-loop;
  6931.                                                 if(tok==tk_assign){
  6932.                                                         if(localline==0)localline=linenumber;
  6933.                                                         if(numcopyvar!=1){
  6934.                                                                 int i=binptr;
  6935.                                                                 while(input[i]!='[')i++;
  6936.                                                                 i++;
  6937.                                                                 input[i]='0';
  6938.                                                                 i++;
  6939.                                                                 for ( int j=1;j!=0;i++){
  6940.                                                                         switch(input[i]){
  6941.                                                                                 case '[':
  6942.                                                                                         j++;
  6943.                                                                                         break;
  6944.                                                                                 case ']':
  6945.                                                                                         j--;
  6946.                                                                                         break;
  6947.                                                                         }
  6948.                                                                         if(j!=0)input[i]= ' ';
  6949.                                                                 }
  6950.                                                         }
  6951.                                                         else{
  6952.                                                                 switch(slocaltok){
  6953.                                                                         case tk_floatvar:
  6954.                                                                         case tk_doublevar:
  6955.                                                                         case tk_qwordvar:
  6956. //                                                                              (lilv+numinit)->ofs=-1;
  6957.                                                                                 break;
  6958.                                                                         default:
  6959.                                                                                 if(PossiblePush()){
  6960.                                                                                         (lilv+numinit)->size=loop;
  6961.                                                                                         (lilv+numinit)->rec=lrec;
  6962.                                                                                 }
  6963.                                                                                 break;
  6964.                                                                 }
  6965.                                                         }
  6966.                                                         (lilv+numinit)->ofs=SizeBackBuf;
  6967.                                                         AddBackBuf(binptr,bcha);
  6968. //                                                      if(bufrm)puts(bufrm);
  6969.                                                 }
  6970.                                                 numinit++;
  6971.                                                 if(numinit==maxlocvar){
  6972.                                                         maxlocvar+=MAXLOCVAR;
  6973.                                                         lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV));
  6974.                                                 }
  6975.                                                 lrec->rec.recnumber=-lrec->rec.recnumber-Align(loop,(am32==FALSE?2:4));
  6976.                                         }
  6977.                                 }
  6978.                                 if(localsize)localsize=Align(localsize,(am32==FALSE?2:4));
  6979.                         }while(tok==tk_camma);
  6980.                         seminext();
  6981.                 }
  6982.                 else{
  6983.                         numinit++;
  6984.                         if(numinit==maxlocvar){
  6985.                                 maxlocvar+=MAXLOCVAR;
  6986.                                 lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV));
  6987.                         }
  6988.                 }
  6989.                 flag=0;
  6990. //              printf("tok=%d %s\n",tok,BackTextBlock);
  6991.         }while(tok!=tk_openbrace&&tok!=tk_eof);
  6992. }
  6993.  
  6994. int CheckDeclareProc()
  6995. {
  6996. unsigned int i=inptr2-1;
  6997.         while(input[i]!='('){
  6998.                 i++;
  6999.                 if(i>=endinptr){
  7000.                         unexpectedeof();
  7001.                         break;
  7002.                 }
  7003.         }
  7004. lab1:
  7005.         i++;
  7006.         for(int j=1;j!=0;i++){
  7007.                 char c=input[i];
  7008.                 if(c=='(')j++;
  7009.                 else if(c==')')j--;
  7010.                 if(i>=endinptr){
  7011.                         unexpectedeof();
  7012.                         break;
  7013.                 }
  7014.         }
  7015.         for(;;i++){
  7016.                 if(input[i]=='(')goto lab1;
  7017.                 if(input[i]>' ')break;
  7018.                 if(i>=endinptr){
  7019.                         unexpectedeof();
  7020.                         break;
  7021.                 }
  7022.         }
  7023.  
  7024.         for(;;i++){
  7025.                 if(input[i]==';'||input[i]==',')return TRUE;    //îáúÿâëåíèå ïðîöåäóðû
  7026.                 if(input[i]>' ')break;
  7027.                 if(i>=endinptr){
  7028.                         unexpectedeof();
  7029.                         break;
  7030.                 }
  7031.         }
  7032.         return FALSE;
  7033. }
  7034.  
  7035. void IsUses(idrec *rec)
  7036. {
  7037. int i;
  7038.         if(tok==tk_openbracket&&stricmp(itok2.name,"uses")==0){
  7039.                 nexttok();
  7040.                 i=0;
  7041.                 nexttok();
  7042.                 while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){
  7043.                         if(tok==tk_beg&&itok.number>3)itok.number-=4;
  7044.                         i=i|(1<<itok.number);
  7045.                         nexttok();
  7046.                         if(tok==tk_camma)nexttok();
  7047.                 }
  7048.                 if(strcmp(itok.name,"allregs")==0){
  7049.                         i=256;
  7050.                         nexttok();
  7051.                 }
  7052.                 rec->recpost=0xFF^i;
  7053.                 expecting(tk_closebracket);
  7054.         }
  7055. }
  7056.  
  7057. void declare_procedure(int oflag,int orm,int npointr)
  7058. {
  7059. int i,next=TRUE,j;
  7060. char pname[IDLENGTH];
  7061. idrec *rec;
  7062.         strcpy(pname,itok.name);
  7063.         param[0]=0;
  7064.         nexttok();
  7065.         if(npointr)expecting(tk_closebracket);
  7066.         expecting(tk_openbracket);
  7067.         if((oflag&f_typeproc)==tp_fastcall)declareparamreg();
  7068.         else declareparamstack();
  7069.         if(tok2==tk_assign)nexttok();
  7070.         itok.post=1;
  7071.         if(npointr){
  7072.                 itok.segm=DS;
  7073.                 itok.type=tk_proc;
  7074.                 itok.sib=am32==FALSE?rm_d16:rm_d32;
  7075.                 i=2;
  7076.                 if(am32||(oflag&f_far))i=4;
  7077.                 if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){   //= èíèöèàëèçèðîâàíàÿ ïåðåìåííàÿ
  7078.                         if((oflag&f_extern))preerror("extern variable do not initialize at declare");
  7079.                         if(alignword&&(!dynamic_flag))alignersize+=AlignCD(DS,i);
  7080.                         FindOff((unsigned char *)pname,DS);
  7081.                         itok.number=outptrdata;
  7082.                         if(tok!=tk_assign){
  7083.                                 if(dbg&2)AddDataLine(i);
  7084.                                 outword(0);
  7085.                                 if(i==4)outword(0);
  7086.                         }
  7087.                         else{
  7088.                                 ITOK oitok;
  7089.                                 oitok=itok;
  7090.                                 initglobalvar(tk_word,1,i,variable);
  7091.                                 itok=oitok;
  7092.                                 next=FALSE;
  7093.                         }
  7094.                         itok.post=0;
  7095.                         datasize+=i;
  7096.                 }
  7097.                 else{
  7098.                         if((oflag&f_extern)==0){
  7099.                                 itok.number=postsize;
  7100.                                 AddPostData(i);
  7101.                         }
  7102.                         else itok.number=externnum++;
  7103.                 }
  7104.                 j=tok;
  7105.                 tok=tk_pointer;
  7106.         }
  7107.         else{
  7108.                 tok=tk_declare;
  7109.                 itok.type=tp_declare;
  7110.                 itok.number=(oflag&f_extern)!=0?externnum++:secondcallnum++;
  7111.                 itok.segm=NOT_DYNAMIC;
  7112.                 itok.post=0;
  7113.         }
  7114.         itok.npointr=(unsigned short)npointr;
  7115.         itok.rm=orm;
  7116.         itok.flag=oflag;
  7117.         if(itok.rm==tokens)itok.rm=(am32==0?tk_word:tk_dword);
  7118. //      printf("rm=%d %s\n",itok.rm,itok.name);
  7119.         strcpy((char *)string,param);
  7120.         rec=addtotree(pname);
  7121.         if(next)nexttok();
  7122.         else tok=j;
  7123.         IsUses(rec);
  7124. }
  7125.  
  7126. void define_procedure()
  7127. {
  7128.         if(dynamic_flag)dynamic_proc();
  7129.         else{
  7130.                 itok.segm=NOT_DYNAMIC;
  7131.                 if(AlignProc!=FALSE)AlignCD(CS,alignproc);
  7132.                 procedure_start=outptr;
  7133.                 if(dbg)AddLine();
  7134. //              itok.flag&=~f_static; 26.08.05 00:09
  7135.                 setproc((tok==tk_id||tok==tk_ID)?0:1);
  7136.                 dopoststrings();
  7137.         }
  7138. }
  7139.  
  7140. void interruptproc()
  7141. {
  7142. char *bstring;
  7143. ITOK otok;
  7144.         inlineflag=0;
  7145.         procedure_start=outptr;
  7146.         returntype=tk_void;
  7147.         current_proc_type=f_interrupt;
  7148.         localsize=paramsize=0;
  7149.         nexttok();
  7150. //      FindOff((unsigned char *)itok.name,CS);
  7151.         itok.number=outptr;
  7152.         itok.segm=NOT_DYNAMIC;
  7153.         itok.post=0;
  7154.         itok.rm=tk_void;
  7155.         itok.flag=0;
  7156.         if(tok==tk_ID||tok==tk_id){
  7157.                 tok=tk_interruptproc;
  7158.                 itok.type=tp_ucnovn;
  7159.                 addtotree((char *)string);
  7160.         }
  7161.         else if(tok==tk_undefproc){
  7162.                 tok=tk_interruptproc;
  7163.                 long hold=updatetree();
  7164.                 updatecall((unsigned int)hold,(unsigned int)outptr,0);
  7165.         }
  7166.         else idalreadydefined();
  7167.         itok.rec->count=FindOff((unsigned char *)itok.name,CS);
  7168.         bstring=BackString((char *)string);
  7169.         otok=itok;
  7170.         nextexpecting2(tk_openbracket);
  7171.         expecting(tk_closebracket);
  7172.         if(tok==tk_inline){
  7173.                 inlineflag=1;
  7174.                 nexttok();
  7175.         }
  7176.         else if(tok!=tk_openbrace)declarelocals(0);
  7177.         expecting(tk_openbrace);
  7178.         declarelocals(1);
  7179.         startblock();
  7180.         doblock2();                                                     /* do proc */
  7181.         endblock();
  7182.         if(retproc==FALSE){
  7183.                 if(inlineflag==0)leaveproc();
  7184.                 else if(localsize>0)Leave();
  7185.         }
  7186.         initBP=0;
  7187.         strcpy((char *)string,bstring);
  7188.         itok=otok;
  7189.         tok=tk_interruptproc;
  7190.         itok.size=outptr-procedure_start;
  7191.         updatetree();
  7192.         free(bstring);
  7193.         killlocals();
  7194.         nexttok();
  7195.         dopoststrings();
  7196. }
  7197.  
  7198. int skipstring(int pos,unsigned char term)
  7199. {
  7200. unsigned char c;
  7201.         do{
  7202.                 pos++;
  7203.                 c=input[pos];
  7204.                 if(c==0x5C){
  7205.                         pos++;
  7206.                         continue;
  7207. //                      c=input[pos+1];
  7208.                 }
  7209.         }while(c!=term);
  7210.         return pos;
  7211. }
  7212.  
  7213. int skipcomment(int pos)
  7214. {
  7215.         if(input[pos+1]=='*'){
  7216.                 pos+=2;
  7217.                 for(;;pos++){
  7218.                         if(input[pos]==13){
  7219.                                 linenumber++;
  7220.                         }
  7221.                         else if(input[pos]=='*'){
  7222.                                 pos++;
  7223.                                 if(input[pos]=='/')break;
  7224.                         }
  7225.                         if((unsigned int)pos>=endinptr){
  7226.                                 unexpectedeof();
  7227.                                 break;
  7228.                         }
  7229.                 }
  7230.         }
  7231.         else if(input[pos+1]=='/'){
  7232.                 pos+=2;
  7233.                 for(;;pos++){
  7234.                         if(input[pos]==13){
  7235.                                 linenumber++;
  7236.                                 break;
  7237.                         }
  7238.                         if(input[pos]==10)break;
  7239.                 }
  7240.         }
  7241.         return pos;
  7242. }
  7243.  
  7244. int swapparam()
  7245. {
  7246. int i,ns,j,lastofs;
  7247. int linep,linebak;
  7248. char c,ochar;
  7249. unsigned char *bufpar;
  7250. int numpar=0;
  7251. unsigned char *oldinput;
  7252. paraminfo *pi;
  7253.         if(tok!=tk_openbracket){
  7254.                 expected('(');
  7255.                 do{
  7256.                         nexttok();
  7257.                 }while(tok2!=tk_semicolon&&tok!=tk_eof);
  7258.                 return 0;
  7259.         }
  7260.         pi=(paraminfo *)MALLOC(128*sizeof(paraminfo));
  7261.         do{
  7262.                 inptr2--;
  7263.         }while(input[inptr2]!='(');
  7264.         inptr2++;
  7265.         pi->ofspar=inptr2;
  7266.         pi->type[0]=0;
  7267.         linep=linenumber;
  7268.         for(i=inptr2,ns=1;ns>0;i++){    //ïîèñê êîíöà ïàðàìåòðîâ
  7269.                 switch(input[i]){
  7270.                         case '(': ns++; break;
  7271.                         case ')': ns--; break;
  7272.                         case ',':
  7273.                                 if(ns==1){
  7274.                                         if(numpar==127)preerror("To many parametrs in function");
  7275.                                         numpar++;
  7276.                                         (pi+numpar)->ofspar=i+1;
  7277.                                         (pi+numpar)->type[0]=0;
  7278.                                 }
  7279.                                 break;
  7280.                         case '/':
  7281.                                 i=skipcomment(i);
  7282.                                 break;
  7283.                         case '"':
  7284.                         case 0x27:
  7285.                                 i=skipstring(i,input[i]);
  7286.                                 break;
  7287.                         case 13:
  7288.                                 linenumber++;
  7289.                                 break;
  7290.                 }
  7291.                 if((unsigned int)i>=endinptr){
  7292.                         unexpectedeof();
  7293.                         break;
  7294.                 }
  7295.         }
  7296.         for(j=0,ns=0;param[j]!=0;j++,ns++){//ïåðåâåðíóòü çàäåêëàðèðóåìûå ïàðàìåòðû
  7297.                 lastofs=0;
  7298.                 ochar=c=param[j];
  7299.                 (pi+ns)->type[0]=c;
  7300.                 while(c=='*'){
  7301.                         j++;
  7302.                         ochar=c=param[j];
  7303.                         (pi+ns)->type[++lastofs]=c;
  7304.                 }
  7305.                 if(c=='A'){
  7306.                         if(ns){
  7307.                                 while(ns<=numpar){
  7308.                                         (pi+ns)->type[0]='U';
  7309.                                         (pi+ns)->type[1]=0;
  7310.                                         ns++;
  7311.                                 }
  7312.                                 break;
  7313.                         }
  7314.                 }
  7315.                 if(ochar=='T'){
  7316.                         do{
  7317.                                 j++;
  7318.                                 lastofs++;
  7319.                                 c=param[j];
  7320.                                 (pi+ns)->type[lastofs]=c;
  7321.                         }while(isdigit(c));
  7322.                         (pi+ns)->type[lastofs]=0;
  7323.                         j--;
  7324.                         continue;
  7325.                 }
  7326.                 c=param[j+1];
  7327.                 if(c>='0'&&c<='7'){
  7328.                         (pi+ns)->type[1]=c;
  7329.                         j++;
  7330.                         lastofs++;
  7331.                         if(ochar=='Q'){
  7332.                                 (pi+ns)->type[2]=param[j+1];
  7333.                                 j++;
  7334.                                 lastofs++;
  7335.                         }
  7336.                 }
  7337.                 (pi+ns)->type[++lastofs]=0;
  7338.         }
  7339.         ns--;
  7340.         for(j=0;ns>=0;ns--){
  7341.                 lastofs=0;
  7342.                 c=(pi+ns)->type[lastofs++];
  7343.                 while(c!=0){
  7344.                         param[j++]=c;
  7345.                         c=(pi+ns)->type[lastofs++];
  7346.                 }
  7347.         }
  7348.         param[j]=0;
  7349. //      puts(param);
  7350. //      if(crec)printf("start0 swapparams num=%08X\n",crec->recnumber);
  7351.         bufpar=(unsigned char *)MALLOC(i-inptr2+2);
  7352. //      printf("crec=%08X size=%d bufpar=%08X size=%d\n",crec,sizeof(idrec),bufpar,i-inptr2+2);
  7353.         inptr2=i;
  7354.         ochar=input[inptr2];
  7355.         inptr2++;
  7356.         i--;
  7357.         lastofs=0;
  7358.         for(;;){
  7359.                 j=(pi+numpar)->ofspar;//[numpar];
  7360.                 for(ns=0;(j+ns)!=i;ns++){
  7361.                         bufpar[lastofs++]=input[j+ns];
  7362.                 }
  7363.                 i=j-1;
  7364.                 numpar--;
  7365.                 if(numpar<0)break;
  7366.                 bufpar[lastofs++]=',';
  7367.         }
  7368.         bufpar[lastofs++]=')';
  7369.         *(short *)&bufpar[lastofs++]=';';
  7370.         free(pi);
  7371.         oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå
  7372. //      puts((char *)(input+inptr));
  7373. //      printf("cur_mod=%08X input=%08X\n",cur_mod,input);
  7374.         ns=inptr2;
  7375.         j=endinptr;
  7376.         input=bufpar;
  7377. //      puts((char *)bufpar);
  7378.         inptr2=1;
  7379.         cha2=input[0];
  7380.         endinptr=lastofs;
  7381.         tok=tk_openbracket;
  7382.         if(bufrm!=NULL){
  7383.                 free(bufrm);
  7384.                 bufrm=NULL;
  7385.         }
  7386.         if(strinf.bufstr!=NULL){
  7387.                 free(strinf.bufstr);
  7388.                 strinf.bufstr=NULL;
  7389.         }
  7390.         linebak=linenumber;
  7391.         linenumber=linep;
  7392.         i=doparams();
  7393.         endoffile=0;
  7394.         input=oldinput;
  7395.         inptr2=ns;
  7396.         cha2=ochar;
  7397.         endinptr=j;
  7398.         linenumber=linebak;
  7399. //      printf("cur_mod=%08X input=%08X\n",cur_mod,input);
  7400.         free(bufpar);
  7401. //      puts((char *)input);
  7402.         return i;
  7403. }
  7404.  
  7405. int getrazr(int type)
  7406. {
  7407.         switch(type){
  7408.                 case tk_char:
  7409.                 case tk_byte:
  7410.                         return r8;
  7411.                 case tk_word:
  7412.                 case tk_int:
  7413.                         return r16;
  7414.                 case tk_long:
  7415.                 case tk_dword:
  7416.                 case tk_float:
  7417.                         return r32;
  7418.                 case tk_qword:
  7419.                 case tk_double:
  7420.                         return r64;
  7421.         }
  7422.         if(am32)return r32;
  7423.         return r16;
  7424. }
  7425.  
  7426. int doparams()           /* do stack procedure parameter pushing */
  7427. {
  7428. char done=0,next;
  7429. int vartype;
  7430. int stackpar=0;
  7431. int i;
  7432. int jj=0;
  7433. char *bparam;   //áóôåð äëÿ äåêëàðèðóåìûõ ïàðàìåòðîâ
  7434. int ip=-1;      //íîìåð ïàðàìåòðà
  7435. char *ofsstr=NULL;
  7436. int useAX=FALSE;
  7437. int retreg=AX;
  7438. unsigned char oaddstack=addstack;
  7439. unsigned char oinline=useinline;
  7440.         useinline=0;
  7441. int structsize;
  7442. struct idrec *ptrs;
  7443.         addstack=FALSE;
  7444.         if(am32!=FALSE)jj=2;
  7445.         bparam=BackString(param);
  7446.         if(param[0]!=0)ip=0;
  7447.         ofsstr=GetLecsem(tk_camma,tk_closebracket);
  7448.         expectingoperand(tk_openbracket);
  7449.         ClearRegister();
  7450.         if(tok!=tk_closebracket){
  7451.                 while(tok!=tk_eof&&done==0){
  7452.                         useAX=FALSE;
  7453.                         retreg=AX;
  7454.                         i=0;
  7455.                         next=1;
  7456.                         if(ip!=-1){
  7457.                                 if(bparam[ip]=='*'){
  7458.                                         while(bparam[ip]=='*')ip++;
  7459.                                         ip++;
  7460.                                         vartype=(am32==FALSE?tk_word:tk_dword);
  7461.                                 }
  7462.                                 else{
  7463.                                         if((vartype=GetTypeParam(bparam[ip++]))==0)ip=-1;
  7464.                                         else{
  7465.                                                 int c=bparam[ip];
  7466.                                                 if(vartype==tk_struct){
  7467.                                                         structsize=0;
  7468.                                                         while(isdigit(c)){
  7469.                                                                 c-='0';
  7470.                                                                 structsize=structsize*10+c;
  7471.                                                                 ip++;
  7472.                                                                 c=param[ip];
  7473.                                                         }
  7474.                                                 }
  7475.                                                 else if(c>='0'&&c<='7'){
  7476.                                                         ip++;
  7477.                                                         c-=0x30;
  7478.                                                         if(vartype==tk_fpust)float2stack(c);
  7479.                                                         else{
  7480.                                                                 if(vartype==tk_qword){
  7481.                                                                         c|=(bparam[ip]-0x30)*256;
  7482.                                                                         ip++;
  7483.                                                                 }
  7484.                                                                 CalcRegPar(c,vartype,&ofsstr);
  7485.                                                         }
  7486.                                                         goto endparam;
  7487.                                                 }
  7488.                                         }
  7489.                                 }
  7490.                                 if(vartype==tk_multipoint){
  7491.                                         vartype=tokens;
  7492.                                         ip--;
  7493.                                 }
  7494.                         }
  7495.                         if(tok==tk_string){
  7496.                                 if(chip<2||(optimizespeed&&(chip==5||chip==6))){
  7497.                                         op(0xB8);
  7498.                                         if(am32!=FALSE)outdword(addpoststring());
  7499.                                         else outword(addpoststring());  // MOV AX,imm16
  7500.                                         op(0x50);
  7501.                                         useAX=TRUE;
  7502.                                         ClearReg(EAX);  //íàäî äîáàâèòü îïòèìèçàöèþ ðåãèñòðîâ à ïîêà òàê
  7503.                                 }                       /* PUSH AX */
  7504.                                 else{
  7505.                                         op(0x68);  /* PUSH imm16 */
  7506.                                         if(am32!=FALSE)outdword(addpoststring());
  7507.                                         else outword(addpoststring());
  7508.                                         if(cpu<2)cpu=2;
  7509.                                 }
  7510.                                 stackpar+=2+jj;
  7511.                                 addESP+=2+jj;
  7512.                                 nexttok();
  7513.                         }
  7514.                         else{
  7515.                                 if(tok>=tk_char&&tok<=tk_double){
  7516.                                         vartype=tok;
  7517.                                         getoperand();
  7518.                                 }
  7519.                                 else if(tok==tk_openbracket){
  7520.                                         nexttok();
  7521.                                         if(tok>=tk_char&&tok<=tk_double)vartype=tok;
  7522.                                         nexttok();
  7523.                                         expectingoperand(tk_closebracket);
  7524.                                 }
  7525.                                 else{
  7526.                                         if(ip==-1||vartype==tokens){
  7527.                                                 switch(tok){
  7528.                                                         case tk_longvar: vartype=tk_long; break;
  7529.                                                 case tk_floatvar: vartype=tk_float; break;
  7530.                                                         case tk_dwordvar: vartype=tk_dword; break;
  7531.                                                         case tk_doublevar: vartype=tk_double; break;
  7532.                                                         case tk_qwordvar: vartype=tk_qword; break;
  7533.                                                         case tk_number:
  7534.                                                                 vartype=(itok.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword));
  7535.                                                                 break;
  7536.                                                         case tk_reg32: vartype=tk_dword; break;
  7537.                                                         case tk_reg64: vartype=tk_qword; break;
  7538.                                                         case tk_minus:
  7539.                                                                 if(tok2==tk_number){
  7540.                                                                         vartype=itok2.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword);
  7541.                                                                         break;
  7542.                                                                 }
  7543.                                                         default: vartype=(am32==FALSE?tk_word:tk_dword); break;
  7544.                                                 }
  7545.                                         }
  7546.                                 }
  7547.                                 if(tok==tk_minus&&tok2==tk_number&&vartype!=tk_float){  //ïðîâåðêà îòðèöàòåëüíîãî ÷èñëà
  7548.                                         nexttok();
  7549.                                         itok.lnumber=-itok.lnumber;
  7550.                                 }
  7551.                                 int razr;
  7552.                                 if(ofsstr){
  7553.                                         razr=getrazr(vartype);
  7554.                                         int retr;
  7555.                                         if((retr=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){
  7556. //                                              printf("reg=%d\n",retr);
  7557.                                                 GetEndLex(tk_camma,tk_closebracket);
  7558.                                                 if(razr==r8)razr=am32==0?r16:r32;
  7559.                                                 if(retr==SKIPREG)retreg=AX;
  7560.                                                 else retreg=retr;
  7561.                                                 op66(razr);
  7562.                                                 op(0x50+retreg);
  7563.                                                 useAX=TRUE;
  7564.                                                 stackpar+=razr;
  7565.                                                 addESP+=razr;
  7566.                                                 goto endparam1;
  7567.                                         }
  7568. //                                              printf("reg=%d\n",retr);
  7569.                                 }
  7570.                                 razr=r32;
  7571.                                 if(itok2.type==tp_opperand||tok==tk_minus){     //ñîñòàâíîå
  7572.                                         switch(vartype){
  7573.                                                 case tk_struct:
  7574.                                                         i=structsize/((am32+1)*2);
  7575.                                                         do_e_axmath(0,r32,&ofsstr);
  7576.                                                         ClearReg(AX);
  7577.                                                         if(am32){
  7578.                                                                 i--;
  7579.                                                                 itok.number=structsize;
  7580.                                                                 for(;i>0;i--){
  7581.                                                                         itok.number-=4;
  7582.                                                                         outword(0x70FF);
  7583.                                                                         op(itok.number);
  7584.                                                                 }
  7585.                                                                 outword(0x30FF);
  7586.                                                         }
  7587.                                                         else{
  7588.                                                                 ClearReg(BX);
  7589.                                                                 warningreg(regs[1][BX]);
  7590.                                                                 outword(0xC389);
  7591.                                                                 i--;
  7592.                                                                 itok.number=structsize;
  7593.                                                                 for(;i>0;i--){
  7594.                                                                         itok.number-=2;
  7595.                                                                         outword(0x77FF);
  7596.                                                                         op(itok.number);
  7597.                                                                 }
  7598.                                                                 outword(0x37FF);
  7599.                                                         }
  7600.                                                         stackpar+=structsize;
  7601.                                                         addESP+=structsize;
  7602.                                                         break;
  7603.                                                 case tk_char: i=1;
  7604.                                                 case tk_byte:
  7605.                                                         stackpar+=jj;
  7606.                                                         doalmath((char)i,&ofsstr);
  7607.                                                         addESP+=2+jj;
  7608.                                                         break;
  7609.                                                 case tk_int: i=1;
  7610.                                                 case tk_word:
  7611.                                                         if(am32==FALSE)razr=r16;
  7612.                                                         stackpar+=jj;
  7613.                                                         goto blokl;
  7614.                                                 case tk_long: i=1;
  7615.                                                 case tk_dword:
  7616.                                                         if(cpu<3)cpu=3;
  7617.                                                         stackpar+=2;
  7618. blokl:
  7619.                                                         if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))&&(tok==tk_number
  7620.                                                                         ||tok==tk_undefofs||tok==tk_postnumber)){
  7621.                                                                 int otok=tok;
  7622.                                                                 ITOK oitok=itok;
  7623.                                                                 tok=tk_number;
  7624.                                                                 if(OnlyNumber(i)){
  7625.                                                                         op66(razr);
  7626.                                                                         if(otok==tk_number&&(postnumflag&f_reloc)==0&&short_ok(itok.number,razr==r16?FALSE:TRUE)!=0){
  7627.                                                                                 op(0x6A);       // PUSH 8 extend to 32 bit
  7628.                                                                                 op((unsigned int)itok.number);
  7629.                                                                         }
  7630.                                                                         else{
  7631.                                                                                 op(0x68);       // PUSH const
  7632.                                                                                 if(otok==tk_undefofs)AddUndefOff(0,oitok.name);
  7633.                                                                                 else if(otok==tk_postnumber)(oitok.flag&f_extern)==0?setwordpost(&oitok):setwordext(&oitok.number);
  7634.                                                                                 else if((postnumflag&f_reloc)!=0)AddReloc();
  7635.                                                                                 if(razr==r16)outword(itok.number);
  7636.                                                                                 else outdword(itok.number);
  7637.                                                                         }
  7638.                                                                         addESP+=razr==r16?2:4;
  7639.                                                                         goto nopush;
  7640.                                                                 }
  7641.                                                                 tok=otok;
  7642.                                                         }
  7643.                                                         do_e_axmath(i,razr,&ofsstr);
  7644.                                                         addESP+=razr==r16?2:4;
  7645.                                                         op66(razr);
  7646.                                                         break;
  7647.                                                 case tk_double:
  7648.                                                         if(doeaxfloatmath(tk_stackstart,0,4)!=tk_stackstart){
  7649.                                                                 op66(r32);
  7650.                                                                 op(0x50+EDX);   // PUSH EDX
  7651.                                                                 op66(r32);
  7652.                                                                 op(0x50);       //push eax
  7653.                                                                 useAX=TRUE;
  7654.                                                         }
  7655.                                                         if(cpu<3)cpu=3;
  7656.                                                         stackpar+=6;
  7657.                                                         addESP+=8;
  7658.                                                         goto nopush;
  7659.                                                 case tk_float:
  7660.                                                         if(doeaxfloatmath(tk_stackstart)!=tk_stackstart){
  7661.                                                                 op66(r32);
  7662.                                                                 if(!am32){
  7663.                                                                         op(0x89);       //      mov ssdword[bp+2]=eax
  7664.                                                                         op(0x46);
  7665.                                                                         op(2);
  7666.                                                                         Leave();
  7667.                                                                 }
  7668.                                                                 else{
  7669.                                                                         op(0x50);       //push eax
  7670.                                                                         useAX=TRUE;
  7671.                                                                 }
  7672.                                                         }
  7673.                                                         if(cpu<3)cpu=3;
  7674.                                                         stackpar+=2;
  7675.                                                         addESP+=4;
  7676.                                                         goto nopush;
  7677.                                                 case tk_qwordvar:
  7678.                                                         i=EAX|(EDX*256);
  7679.                                                         getintoreg64(i);
  7680.                                                         doregmath64(i);
  7681.                                                         op66(r32);
  7682.                                                         op(0x50+EDX);   // PUSH EDX
  7683.                                                         op66(r32);
  7684.                                                         next=0;
  7685.                                                         if(cpu<3)cpu=3;
  7686.                                                         stackpar+=6;
  7687.                                                         addESP+=8;
  7688.                                                         break;
  7689.                                                 default: goto deflt;
  7690.                                         }
  7691.                                         op(0x50);/* PUSH AX or EAX */
  7692.                                         useAX=TRUE;
  7693. nopush:
  7694.                                         stackpar+=2;
  7695.                                 }
  7696.                                 else{   //îäèíî÷íîå
  7697. //                                      next=1;
  7698. //                                      printf("vartype=%d\n",vartype);
  7699.                                         if(vartype==tk_struct){
  7700. //                                              printf("tok=%d %s\n",tok,itok.name);
  7701.                                                 i=structsize/((am32+1)*2);
  7702.                                                 switch(tok){
  7703.                                                         case tk_structvar:
  7704.                                                                 ptrs=itok.rec;
  7705.                                                                 if(ptrs->recpost==LOCAL){
  7706.                                                                         if(ESPloc&&am32){
  7707.                                                                                 itok.rm=rm_mod10|rm_sib;
  7708.                                                                                 itok.sib=0x24;
  7709.                                                                                 itok.number+=addESP;
  7710.                                                                         }
  7711.                                                                         else{
  7712.                                                                                 itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
  7713.                                                                         }
  7714.                                                                         itok.segm=SS;
  7715.                                                                         itok.post=0;
  7716.                                                                         compressoffset(&itok);
  7717.                                                                 }
  7718.                                                                 else{
  7719.                                                                         itok.segm=DS;
  7720.                                                                         itok.rm=(am32==FALSE?rm_d16:rm_d32);    //óñòàíîâêè ïî óìîë÷àíèþ
  7721.                                                                         itok.post=ptrs->recpost;
  7722.                                                                         if(i>1&&am32){
  7723.                                                                                 outseg(&itok,1);
  7724.                                                                                 op(0xB8);
  7725.                                                                                 outaddress(&itok);
  7726.                                                                                 ClearReg(AX);
  7727.                                                                                 i--;
  7728.                                                                                 itok.number=structsize;
  7729.                                                                                 for(;i>0;i--){
  7730.                                                                                         itok.number-=4;
  7731.                                                                                         outword(0x70FF);
  7732.                                                                                         op(itok.number);
  7733.                                                                                 }
  7734.                                                                                 outword(0x30FF);
  7735.                                                                                 break;
  7736.                                                                         }
  7737.                                                                 }
  7738.                                                                 itok.sib=(am32==FALSE?CODE16:CODE32);
  7739.                                                                 itok.flag=ptrs->flag;
  7740.                                                                 itok.number+=structsize;
  7741.                                                                 for(;i>0;i--){
  7742.                                                                         itok.number-=(am32+1)*2;
  7743.                                                                         outseg(&itok,2);
  7744.                                                                         op(0xFF);       // PUSH [dword]
  7745.                                                                         op(0x30+itok.rm);
  7746.                                                                         outaddress(&itok);
  7747.                                                                 }
  7748.                                                                 break;
  7749.                                                         case tk_rmnumber:
  7750.                                                                 itok.number+=structsize;
  7751.                                                                 for(;i>0;i--){
  7752.                                                                         itok.number-=(am32+1)*2;
  7753.                                                                         outseg(&itok,2);
  7754.                                                                         op(0xFF);       // PUSH [dword]
  7755.                                                                         op(0x30+itok.rm);
  7756.                                                                         outaddress(&itok);
  7757.                                                                 }
  7758.                                                                 break;
  7759.                                                         case tk_undefofs:
  7760.                                                                 itok.rm=(am32==FALSE?rm_d16:rm_d32);    //óñòàíîâêè ïî óìîë÷àíèþ
  7761.                                                         case tk_postnumber:
  7762.                                                                 if(i>1&&am32){
  7763.                                                                         if(tok!=tk_undefofs)outseg(&itok,1);
  7764.                                                                         op(0xB8);
  7765.                                                                         if(tok==tk_undefofs){
  7766.                                                                                 AddUndefOff(0,(char *)string);
  7767.                                                                                 outdword(itok.number);
  7768.                                                                         }
  7769.                                                                         else outaddress(&itok);
  7770.                                                                         ClearReg(AX);
  7771.                                                                         i--;
  7772.                                                                         itok.number=structsize;
  7773.                                                                         for(;i>0;i--){
  7774.                                                                                 itok.number-=4;
  7775.                                                                                 outword(0x70FF);
  7776.                                                                                 op(itok.number);
  7777.                                                                         }
  7778.                                                                         outword(0x30FF);
  7779.                                                                         break;
  7780.                                                                 }
  7781.                                                                 itok.number+=structsize;
  7782.                                                                 for(;i>0;i--){
  7783.                                                                         itok.number-=(am32+1)*2;
  7784.                                                                         if(tok!=tk_undefofs)outseg(&itok,2);
  7785.                                                                         op(0xFF);       // PUSH [dword]
  7786.                                                                         op(0x30+itok.rm);
  7787.                                                                         if(tok==tk_undefofs){
  7788.                                                                                 AddUndefOff(0,(char *)string);
  7789.                                                                                 outdword(itok.number);
  7790.                                                                         }
  7791.                                                                         else outaddress(&itok);
  7792.                                                                 }
  7793.                                                                 break;
  7794.                                                         case tk_reg32:
  7795.                                                                 i--;
  7796.                                                                 itok.rm=structsize;
  7797.                                                                 for(;i>0;i--){
  7798.                                                                         itok.rm-=4;
  7799.                                                                         op(0xFF);
  7800.                                                                         op(0x70+itok.number);
  7801.                                                                         op(itok.rm);
  7802.                                                                 }
  7803.                                                                 op(0xFF);
  7804.                                                                 op(0x30+itok.number);
  7805.                                                                 break;
  7806.                                                         default:
  7807. //                                                              preerror("for parametr function required structure");
  7808.                                                                 do_e_axmath(0,r32,&ofsstr);
  7809.                                                                 ClearReg(AX);
  7810.                                                                 if(am32){
  7811.                                                                         i--;
  7812.                                                                         itok.number=structsize;
  7813.                                                                         for(;i>0;i--){
  7814.                                                                                 itok.number-=4;
  7815.                                                                                 outword(0x70FF);
  7816.                                                                                 op(itok.number);
  7817.                                                                         }
  7818.                                                                         outword(0x30FF);
  7819.                                                                 }
  7820.                                                                 else{
  7821.                                                                         ClearReg(BX);
  7822.                                                                         warningreg(regs[1][BX]);
  7823.                                                                         outword(0xC389);
  7824.                                                                         i--;
  7825.                                                                         itok.number=structsize;
  7826.                                                                         for(;i>0;i--){
  7827.                                                                                 itok.number-=2;
  7828.                                                                                 outword(0x77FF);
  7829.                                                                                 op(itok.number);
  7830.                                                                         }
  7831.                                                                         outword(0x37FF);
  7832.                                                                 }
  7833.                                                                 break;
  7834.                                                 }
  7835.                                                 stackpar+=structsize;
  7836.                                                 addESP+=structsize;
  7837.                                         }
  7838.                                         else if(vartype<tk_long){
  7839. #ifdef OPTVARCONST
  7840.                                                 CheckConstVar3(&tok,&itok,razr);
  7841. #endif
  7842.                                                 switch(tok){
  7843.                                                         case tk_reg:
  7844.                                                                 op(0x50+(unsigned int)itok.number);
  7845.                                                                 break;
  7846.                                                         case tk_beg:
  7847.                                                                 if(vartype==tk_int||vartype==tk_word)goto deflt;
  7848.                                                                 if(itok.number<AH){
  7849.                                                                         op(0x50+(unsigned int)itok.number);
  7850.                                                                         break;
  7851.                                                                 }
  7852.                                                                 op(0x88);
  7853.                                                                 op(0xC0+(unsigned int)itok.number*8);
  7854.                                                                 op(0x50);
  7855.                                                                 useAX=TRUE;
  7856.                                                                 break;
  7857.                                                         case tk_seg:
  7858.                                                                 if(am32)goto deflt;
  7859.                                                                 if((unsigned int)itok.number<FS)op(0x06+(unsigned int)itok.number*8);
  7860.                                                                 else{
  7861.                                                                         op(0xF); op(0x80+(unsigned int)itok.number*8);
  7862.                                                                         if((unsigned int)itok.number<=GS)if(cpu<3)cpu=3;
  7863.                                                                 }
  7864.                                                                 break;
  7865.                                                         case tk_longvar:
  7866.                                                         case tk_dwordvar:
  7867. //                                                              if(am32==FALSE)goto deflt;
  7868.                                                                 i=2;
  7869.                                                         case tk_intvar:
  7870.                                                         case tk_wordvar:
  7871.                                                                 i+=2;
  7872.                                                                 CheckAllMassiv(bufrm,i,&strinf);
  7873.                                                                 outseg(&itok,2);
  7874.                                                                 op(0xFF);                       /* PUSH [word] */
  7875.                                                                 op(0x30+itok.rm);
  7876.                                                                 outaddress(&itok);
  7877.                                                                 break;
  7878.                                                         case tk_number:
  7879.                                                                 if(chip>=2/*&&(!(optimizespeed&&(chip==5||chip==6)))*/){        //28.03.07 19:04
  7880.                                                                         if((itok.flag&f_reloc)==0&&short_ok(itok.number)){
  7881.                                                                                 op(0x6A);       /* PUSH const */
  7882.                                                                                 op((unsigned int)itok.number);
  7883.                                                                         }
  7884.                                                                         else{
  7885.                                                                                 op(0x68);        /* PUSH const */
  7886.                                                                                 if((itok.flag&f_reloc)!=0)AddReloc();
  7887.                                                                                 if(am32==FALSE)outword((unsigned int)itok.number);
  7888.                                                                                 else outdword(itok.number);
  7889.                                                                         }
  7890.                                                                         if(cpu<2)cpu=2;
  7891.                                                                 }
  7892.                                                                 else{
  7893.                                                                         MovRegNum(r16,itok.flag&f_reloc,itok.number,EAX);
  7894.                                                                         op(0x50);
  7895.                                                                 }
  7896.                                                                 break;
  7897.                                                         case tk_apioffset:
  7898.                                                                 op(0x68);       // PUSH const
  7899.                                                                 AddApiToPost(itok.number);
  7900.                                                                 break;
  7901.                                                         case tk_postnumber:
  7902.                                                         case tk_undefofs:
  7903.                                                                 if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))){
  7904.                                                                         op(0x68);       // PUSH const
  7905.                                                                         if(tok==tk_undefofs)AddUndefOff(0,(char *)string);
  7906.                                                                         else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
  7907.                                                                         if(am32==FALSE)outword((unsigned int)itok.number);
  7908.                                                                         else outdword(itok.number);
  7909.                                                                         break;
  7910.                                                                 }
  7911.                                                         default:
  7912. deflt:
  7913. //if(tok==tk_new)puts("monovar default");
  7914.                                                                 switch(vartype){
  7915.                                                                         case tk_int: i=1;
  7916.                                                                         case tk_word: do_e_axmath(i,r16,&ofsstr); break;
  7917.                                                                         case tk_char: i=1;
  7918.                                                                         case tk_byte: doalmath((char)i,&ofsstr); break;
  7919.                                                                         default: beep(); break;
  7920.                                                                 }
  7921.                                                                 op(0x50);       /* PUSH AX */
  7922.                                                                 useAX=TRUE;
  7923.                                                                 next=0;
  7924.                                                                 break;
  7925.                                                 }
  7926.                                                 stackpar+=2+jj;
  7927.                                                 addESP+=2+jj;
  7928.                                         }
  7929.                                         else if(vartype<tk_qword){
  7930. #ifdef OPTVARCONST
  7931.                                                 CheckConstVar3(&tok,&itok,razr);
  7932. #endif
  7933. //                                              printf("tok=%d %s\n",tok,itok.name);
  7934.                                                 switch(tok){                            // long or dword or float
  7935.                                                         case tk_reg32:
  7936.                                                                 op66(r32);
  7937.                                                                 op(0x50+(unsigned int)itok.number);
  7938.                                                                 break;
  7939.                                                         case tk_floatvar:
  7940.                                                                 if(vartype==tk_float)goto pushmem;
  7941.                                                         case tk_qwordvar:
  7942.                                                         case tk_dwordvar:
  7943.                                                         case tk_longvar:
  7944.                                                                 if(optimizespeed&&(chip==5||chip==6))goto def;
  7945. pushmem:
  7946.                                                                 CheckAllMassiv(bufrm,4,&strinf);
  7947.                                                                 op66(r32);
  7948.                                                                 outseg(&itok,2);
  7949.                                                                 op(0xFF);       // PUSH [dword]
  7950.                                                                 op(0x30+itok.rm);
  7951. //                                                              printf("push rm=%08X sib=%08X post=%u num=%08X rec=%08X flag=%08X %s\n",itok.rm,itok.sib,itok.post,itok.number,itok.rec,itok.flag,itok.name);
  7952.                                                                 outaddress(&itok);
  7953.                                                                 break;
  7954.                                                         case tk_number:
  7955.                                                                 if(optimizespeed&&(chip==5||chip==6))goto def;
  7956.                                                                 if(vartype==tk_float){
  7957.                                                                         itok.number=doconstfloatmath();
  7958.                                                                         next=0;
  7959.                                                                 }
  7960.                                                                 else if(itok.rm==tk_double)itok.fnumber=itok.dnumber;
  7961.                                                                 op66(r32);
  7962.                                                                 if((itok.flag&f_reloc)==0&&short_ok(itok.number,TRUE)!=0){
  7963.                                                                         op(0x6A);       // PUSH 8 extend to 32 bit
  7964.                                                                         op((unsigned int)itok.number);
  7965.                                                                 }
  7966.                                                                 else{
  7967.                                                                         op(0x68);       // PUSH const
  7968.                                                                         if((itok.flag&f_reloc)!=0)AddReloc();
  7969.                                                                         outdword(itok.number);
  7970.                                                                 }
  7971.                                                                 break;
  7972.                                                         case tk_apioffset:
  7973.                                                                 op66(r32);
  7974.                                                                 op(0x68);       // PUSH const
  7975.                                                                 AddApiToPost(itok.number);
  7976.                                                                 break;
  7977.                                                         case tk_postnumber:
  7978.                                                         case tk_undefofs:
  7979.                                                                 if(optimizespeed&&(chip==5||chip==6))goto def;
  7980.                                                                 op66(r32);
  7981.                                                                 op(0x68);       // PUSH const
  7982.                                                                 if(tok==tk_undefofs)AddUndefOff(0,(char *)string);
  7983.                                                                 else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
  7984.                                                                 outdword(itok.number);
  7985.                                                                 break;
  7986.                                                         default:
  7987. def:
  7988.                                                                 if(vartype==tk_float)doeaxfloatmath(tk_stackstart);
  7989.                                                                 else{
  7990.                                                                         if(vartype==tk_long)i=1;
  7991. //                                                                      printf("tok=%d rm=%08X %s\n",tok,itok.rm,itok.name);
  7992.                                                                         if(tok==tk_rmnumber&&am32&&bufrm==NULL&&strinf.bufstr==NULL&&
  7993.                                                                                         ((itok.rm&7)!=4)&&((itok.rm&7)!=5)&&
  7994.                                                                                         ((itok.rm&rm_mod11)==rm_mod00)&&itok.number==0){
  7995.                                                                                 op66(r32);
  7996.                                                                                 op(0x50+(itok.rm&7));   // PUSH rm reg
  7997.                                                                                 break;
  7998.  
  7999.                                                                         }
  8000.                                                                         do_e_axmath(i,r32,&ofsstr);
  8001.                                                                         op66(r32);
  8002.                                                                         op(0x50);       // PUSH EAX
  8003.                                                                         useAX=TRUE;
  8004.                                                                 }
  8005.                                                                 next=0;
  8006.                                                                 break;
  8007.                                                 }
  8008.                                                 stackpar+=4;
  8009.                                                 addESP+=4;
  8010.                                                 if(cpu<3)cpu=3;
  8011.                                         }
  8012.                                         else{   //qword or double
  8013. #ifdef OPTVARCONST
  8014.                                                 CheckConstVar3(&tok,&itok,razr);
  8015. #endif
  8016.                                                 switch(tok){
  8017.                                                         case tk_reg64:
  8018.                                                                 op66(r32);
  8019.                                                                 op(0x50+(unsigned int)itok.number/256);
  8020.                                                                 op66(r32);
  8021.                                                                 op(0x50+(unsigned int)itok.number&255);
  8022.                                                                 break;
  8023.                                                         case tk_doublevar:
  8024.                                                         case tk_qwordvar:
  8025.                                                                 itok.number+=4;
  8026.                                                                 compressoffset(&itok);
  8027.                                                                 CheckAllMassiv(bufrm,8,&strinf);
  8028.                                                                 for(i=0;i<2;i++){
  8029.                                                                         op66(r32);
  8030.                                                                         outseg(&itok,2);
  8031.                                                                         op(0xFF);       // PUSH [dword]
  8032.                                                                         op(0x30+itok.rm);
  8033.                                                                         outaddress(&itok);
  8034.                                                                         if(i==1)break;
  8035.                                                                         itok.number-=4;
  8036.                                                                         compressoffset(&itok);
  8037.                                                                 }
  8038.                                                                 break;
  8039.                                                         case tk_reg32:
  8040.                                                                 op66(r32);
  8041.                                                                 outword(0x6A);  // PUSH 8 extend to 32 bit
  8042.                                                                 op66(r32);
  8043.                                                                 op(0x50+(unsigned int)itok.number);
  8044.                                                                 break;
  8045.                                                         case tk_number:
  8046.                                                                 long long lnumber;
  8047.                                                                 lnumber=itok.lnumber;
  8048.                                                                 itok.lnumber=lnumber>>32;
  8049.                                                                 for(i=0;i<2;i++){
  8050.                                                                         op66(r32);
  8051.                                                                         if((i==0||(itok.flag&f_reloc)==0)&&short_ok(itok.number,TRUE)!=0){
  8052.                                                                                 op(0x6A);       // PUSH 8 extend to 32 bit
  8053.                                                                                 op((unsigned int)itok.number);
  8054.                                                                         }
  8055.                                                                         else{
  8056.                                                                                 op(0x68);       // PUSH const
  8057.                                                                                 if(i==1&&(itok.flag&f_reloc)!=0)AddReloc();
  8058.                                                                                 outdword(itok.number);
  8059.                                                                         }
  8060.                                                                         if(i==1)break;
  8061.                                                                         itok.number=lnumber;
  8062.                                                                 }
  8063.                                                                 break;
  8064.                                                         case tk_postnumber:
  8065.                                                         case tk_undefofs:
  8066.                                                                 op66(r32);
  8067.                                                                 outword(0x6A);  // PUSH 8 extend to 32 bit
  8068.                                                                 op66(r32);
  8069.                                                                 op(0x68);       // PUSH const
  8070.                                                                 if(tok==tk_undefofs)AddUndefOff(0,(char *)string);
  8071.                                                                 else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
  8072.                                                                 outdword(itok.number);
  8073.                                                                 break;
  8074.                                                         default:
  8075.                                                                 if(vartype==tk_double)doeaxfloatmath(tk_stackstart,0,4);
  8076.                                                                 else{
  8077.                                                                         op66(r32);
  8078.                                                                         outword(0x6A);
  8079.                                                                         do_e_axmath(0,r32,&ofsstr);
  8080.                                                                         op66(r32);
  8081.                                                                         op(0x50);       // PUSH EAX
  8082.                                                                         useAX=TRUE;
  8083.                                                                 }
  8084.                                                                 next=0;
  8085.                                                                 break;
  8086.                                                 }
  8087.                                                 stackpar+=8;
  8088.                                                 addESP+=8;
  8089.                                                 if(cpu<3)cpu=3;
  8090.                                         }
  8091. endparam1:
  8092.                                         if(next)nexttok();
  8093.  
  8094.                                 }
  8095.                         }
  8096. endparam:
  8097.                         if(ofsstr){
  8098.                                 if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype));
  8099.                                 free(ofsstr);
  8100.                                 ofsstr=NULL;
  8101.                         }
  8102.                         if(tok==tk_camma){
  8103.                                 ofsstr=GetLecsem(tk_camma,tk_closebracket);
  8104.                                 getoperand();
  8105.                         }
  8106.                         else if(tok==tk_closebracket)done=1;
  8107.                         else{
  8108.                                 expected(')');
  8109.                                 done=1;
  8110.                         }
  8111.                 }
  8112.         }
  8113.         if(ofsstr){
  8114.                 if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype));
  8115.                 free(ofsstr);
  8116.         }
  8117.         if(ip!=-1&&bparam[ip]!=0&&bparam[ip]!='A'&&bparam[ip]!='V')missingpar();
  8118.         free(bparam);
  8119.         setzeroflag=FALSE;
  8120.         addstack=oaddstack;
  8121.         useinline=oinline;
  8122.         return stackpar;
  8123. }
  8124.  
  8125. void CheckDir()
  8126. {
  8127.         do{
  8128.                 switch(itok.number){
  8129.                         case d_ifdef:
  8130.                         case d_ifndef:
  8131.                         case d_endif:
  8132.                         case d_else:
  8133.                         case d_if:
  8134.                         case d_elif:
  8135.                                 inptr2=inptr;
  8136.                                 cha2=cha;
  8137.                                 linenum2=linenumber;
  8138.                                 directive();
  8139.                                 inptr=inptr2;
  8140.                                 cha=cha2;
  8141.                                 break;
  8142.                         default:
  8143.                                 FastTok(0);
  8144.                                 break;
  8145.                 }
  8146.                 if(tok==tk_eof)break;
  8147.         }while(tok==tk_question);
  8148. }
  8149.  
  8150. char *dynamic_var()
  8151. {
  8152. int start,size;
  8153. char *bstring;
  8154. int use_extract=FALSE;
  8155.  
  8156. #define TBUFSIZE 2048
  8157. #define MTBUFSIZE TBUFSIZE-IDLENGTH
  8158. int curbsize;
  8159. COM_MOD *ocur_mod;
  8160.         bstring=(char *)MALLOC(TBUFSIZE);
  8161.         curbsize=TBUFSIZE;
  8162.         size=0;
  8163.         if(tok2==tk_extract)use_extract=TRUE;
  8164.         do{
  8165.                 start=inptr2-1;
  8166.                 ocur_mod=cur_mod;
  8167.                 if(size>(curbsize-IDLENGTH)){
  8168.                         curbsize+=TBUFSIZE;
  8169.                         bstring=(char *)REALLOC(bstring,curbsize);
  8170.                 }
  8171.                 nexttok();
  8172.                 if(tok==tk_openbrace){
  8173.                         bstring[size]='{';
  8174.                         size++;
  8175.                         do{
  8176.                                 start=inptr2-1;
  8177.                                 ocur_mod=cur_mod;
  8178.                                 if(size>(curbsize-IDLENGTH)){
  8179.                                         curbsize+=TBUFSIZE;
  8180.                                         bstring=(char *)REALLOC(bstring,curbsize);
  8181.                                 }
  8182.                                 nexttok();
  8183.                                 if(tok==tk_number){
  8184.                                         switch(itok.rm){
  8185.                                                 case tk_double:
  8186.                                                 case tk_float:
  8187.                                                         sprintf(itok.name,"%e",itok.dnumber);
  8188.                                                         break;
  8189.                                                 case tk_qword:
  8190.                                                         sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number);
  8191.                                                         break;
  8192.                                                 default:
  8193.                                                         sprintf(itok.name,"0x%X",itok.number);
  8194.                                                         break;
  8195.                                         }
  8196.                                 }
  8197.                                 if(itok.name[0]!=0){
  8198.                                         strcpy(bstring+size,itok.name);
  8199.                                         size+=strlen(itok.name);
  8200.                                 }
  8201.                                 else{
  8202.                                         if(cur_mod!=ocur_mod){
  8203.                                                 start=inptr2-2;
  8204.                                                 if(start<0)start=0;
  8205.                                         }
  8206.                                         strncpy(bstring+size,(char *)(input+start),inptr2-1-start);
  8207.                                         size+=inptr2-1-start;
  8208.                                 }
  8209.                         }while(tok!=tk_closebrace&&tok!=tk_eof);
  8210.                         if(tok!=tk_eof)continue;
  8211.                 }
  8212.                 if(tok==tk_number){
  8213.                         switch(itok.rm){
  8214.                                 case tk_double:
  8215.                                 case tk_float:
  8216.                                         sprintf(itok.name,"%e",itok.dnumber);
  8217.                                         break;
  8218.                                 case tk_qword:
  8219.                                         sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number);
  8220.                                         break;
  8221.                                 default:
  8222.                                         sprintf(itok.name,"0x%X",itok.number);
  8223.                                         break;
  8224.                         }
  8225.                 }
  8226.                 if(itok.name[0]!=0){
  8227.                         strcpy(bstring+size,itok.name);
  8228.                         size+=strlen(itok.name);
  8229.                 }
  8230.                 else{
  8231.                         if(cur_mod!=ocur_mod){
  8232.                                 start=inptr2-2;
  8233.                                 if(start<0)start=0;
  8234.                         }
  8235.                         strncpy(bstring+size,(char *)(input+start),inptr2-1-start);
  8236.                         size+=inptr2-1-start;
  8237.                 }
  8238.                 if(tok==tk_eof){
  8239.                         unexpectedeof();
  8240.                         return NULL;
  8241.                 }
  8242.                 if(tok==tk_camma&&use_extract==FALSE)break;
  8243.         }while(tok!=tk_semicolon);
  8244. //      size++;
  8245.         bstring[size]=0;
  8246.         return bstring;
  8247. }
  8248.  
  8249. int SkipBlock()
  8250. {
  8251.         for(int i=1;i!=0;){
  8252.                 FastTok(0);
  8253.                 if(tok==tk_question)CheckDir();
  8254.                 switch(tok){
  8255.                         case tk_eof: unexpectedeof(); return FALSE;
  8256.                         case tk_openbrace: i++; break;
  8257.                         case tk_closebrace: i--; break;
  8258.                 }
  8259.         }
  8260.         return TRUE;
  8261. }
  8262.  
  8263. int SkipParam()
  8264. {
  8265.         for(int i=1;i!=0;){
  8266.                 FastTok(0);
  8267.                 if(tok==tk_question)CheckDir();
  8268.                 switch(tok){
  8269.                         case tk_openbracket: i++; break;
  8270.                         case tk_closebracket: i--; break;
  8271.                         case tk_eof: unexpectedeof(); return FALSE;
  8272.                 }
  8273.         }
  8274.         return TRUE;
  8275. }
  8276.  
  8277. int SkipLocalVar()
  8278. {
  8279.         while(tok!=tk_openbrace&&tok!=tk_eof){
  8280.                 if(tok==tk_question){
  8281.                         CheckDir();
  8282.                         continue;
  8283.                 }
  8284.                 if(tok==tk_id&&(strcmp(itok.name,"struct")==0||strcmp(itok.name,"union")==0)){
  8285.                         do{
  8286.                                 FastTok(0);
  8287.                                 if(tok==tk_eof){
  8288.                                         unexpectedeof();
  8289.                                         return FALSE;
  8290.                                 }
  8291.                         }while(tok!=tk_semicolon&&tok!=tk_openbrace);
  8292.                         if(tok==tk_openbrace){
  8293.                                 FastTok(0);
  8294.                                 if(!SkipBlock())return FALSE;
  8295.                         }
  8296.                 }
  8297.                 FastTok(1);
  8298.         }
  8299.         return TRUE;
  8300. }
  8301.  
  8302. SAVEPAR *SRparam(int save,SAVEPAR *par) //save or restore global param compiler
  8303. {
  8304.         if(save){
  8305.                 par=(SAVEPAR *)MALLOC(sizeof(SAVEPAR));
  8306.                 par->ooptimizespeed=optimizespeed;
  8307.                 par->owarning=      warning;
  8308.                 par->odbg=          dbg;
  8309.                 par->odosstring=    dosstring;
  8310.                 par->ouseinline=    useinline;
  8311.                 par->oam32=                  am32;
  8312.                 par->oalignword=    alignword;
  8313.                 par->oAlignCycle=   AlignCycle;
  8314.                 par->oidasm=        idasm;      //àññ
  8315.                 par->ooptnumber=    optnumber;
  8316.                 par->odivexpand=    divexpand;
  8317.                 par->ooptstr=        optstr;    //îï
  8318.                 par->ochip=         chip;
  8319.                 par->oaligncycle=   aligncycle;
  8320.                 par->ouselea=       uselea;
  8321.                 par->oregoverstack= regoverstack;
  8322.                 return par;
  8323.         }
  8324.         if(par){
  8325.                 optimizespeed=par->ooptimizespeed;
  8326.                 warning=      par->owarning;
  8327.                 dbg=          par->odbg;
  8328.                 dosstring=    par->odosstring;
  8329.                 useinline=    par->ouseinline;
  8330.                 am32=               par->oam32;
  8331.                 alignword=    par->oalignword;
  8332.                 AlignCycle=   par->oAlignCycle;
  8333.                 idasm=        par->oidasm;      //àññ
  8334.                 optnumber=    par->ooptnumber;
  8335.                 divexpand=    par->odivexpand;
  8336.                 optstr=      par->ooptstr;      //îï
  8337.                 chip=         par->ochip;
  8338.                 aligncycle=   par->oaligncycle;
  8339.                 uselea    =   par->ouselea;
  8340.                 regoverstack= par->oregoverstack;
  8341.                 free(par);
  8342.         }
  8343.         return NULL;
  8344. }
  8345.  
  8346. void dynamic_proc()
  8347. {
  8348. int dtok,start,size,line;
  8349. ITOK otok;
  8350. char *bstring;
  8351. idrec *ptr;
  8352. _PROCINFO_ *pinfo;
  8353.         if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word);
  8354.         dtok=tok;
  8355.         otok=itok;
  8356.         line=linenum2;
  8357.         switch(tok){
  8358.                 case tk_id:
  8359.                 case tk_ID:
  8360.                         string[0]=0;
  8361.                 case tk_undefproc:
  8362.                 case tk_declare:
  8363.                         break;
  8364.                 default: idalreadydefined(); break;
  8365.         }
  8366.         if(itok.flag&f_export)preerror("'_export' not use in dynamic functions");
  8367.         bstring=BackString((char *)string);
  8368.         start=inptr2-1;
  8369.         pinfo=(_PROCINFO_ *)MALLOC(sizeof(_PROCINFO_));
  8370.         if(itok.flag&f_classproc)pinfo->classteg=searchteg;
  8371.         else pinfo->classteg=NULL;
  8372.         pinfo->warn=warning;
  8373.         pinfo->speed=optimizespeed;
  8374.         pinfo->lst=(dbg&2)>>1;
  8375.         pinfo->typestring=dosstring;
  8376.         pinfo->inlinest=useinline;
  8377.         pinfo->code32=am32;
  8378.         pinfo->align=alignword;
  8379.         pinfo->acycle=AlignCycle;
  8380.         pinfo->idasm=idasm;
  8381.         pinfo->opnum=optnumber;
  8382.         pinfo->de=divexpand;
  8383.         pinfo->ostring=optstr;
  8384.         pinfo->chip=chip;
  8385.         pinfo->sizeacycle=aligncycle;
  8386.         pinfo->uselea=uselea;
  8387.         pinfo->regoverstack=regoverstack;
  8388.         nexttok();
  8389.         if(dtok==tk_id||dtok==tk_ID){
  8390.                 param[0]=0;
  8391.                 if(tok2!=tk_closebracket&&(otok.flag&f_typeproc)==tp_fastcall){
  8392.                         nexttok();      //ïàðàìåòðû ðåãèñòðîâîé ïðîöåäóðû
  8393.                         declareparamreg();
  8394.                         free(bstring);
  8395.                         bstring=BackString((char *)param);
  8396.                         nexttok();
  8397.                         inptr=inptr2;
  8398.                         cha=cha2;
  8399.                         linenumber=linenum2;
  8400.                 }
  8401.         }
  8402.         else{
  8403.                 inptr=inptr2;
  8404.                 cha=cha2;
  8405.                 if(!SkipParam()){
  8406.                         free(bstring);
  8407.                         return;
  8408.                 }
  8409.                 FastTok(1);
  8410.         }
  8411.         if(tok==tk_semicolon)preerror("error declare dynamic function");
  8412.         if((!SkipLocalVar())||(!SkipBlock())){
  8413.                 free(bstring);
  8414.                 return;
  8415.         }
  8416.         size=inptr-start+1;
  8417.         inptr2=inptr;
  8418.         cha2=cha;
  8419.         linenum2=linenumber;
  8420.         linenumber=line;
  8421.         itok=otok;
  8422.         strcpy((char *)string,bstring);
  8423.         free(bstring);
  8424.         bstring=(char *)MALLOC(size+1);
  8425.         strncpy(bstring,(char *)(input+start),size);
  8426.         bstring[size-1]=';';
  8427.         bstring[size]=0;
  8428.  
  8429. //      printf("tok=%d %s\n%s\n",dtok,itok.name,bstring);
  8430.         itok.size=0;
  8431.         tok=tk_proc;
  8432.         itok.segm=DYNAMIC;
  8433.         if(dtok==tk_id||dtok==tk_ID){
  8434.                 int i;
  8435.                 itok.number=secondcallnum++;
  8436.                 itok.type=tp_ucnovn;
  8437.                 if((i=FindUseName(itok.name))!=0)itok.segm=DYNAMIC_USED;
  8438.                 ptr=addtotree(itok.name);
  8439.                 if(i){
  8440.                         ptr->count=i;
  8441.                         ptr=itok.rec;
  8442.                         AddDynamicList(ptr);
  8443.                 }
  8444.         }
  8445.         else{
  8446.                 if(dtok==tk_undefproc)itok.segm=DYNAMIC_USED;
  8447.                 updatetree();
  8448.                 ptr=itok.rec;
  8449.                 //11.08.04 23:38
  8450.                 strcpy(ptr->recid,itok.name);
  8451.  
  8452.                 if(dtok==tk_undefproc&&(itok.flag&f_classproc))AddDynamicList(ptr);
  8453.         }
  8454.         ptr->line=linenumber;
  8455.         ptr->file=currentfileinfo;
  8456.         pinfo->buf=bstring;
  8457.         ptr->pinfo=pinfo;
  8458. //      ptr->sbuf=bstring;
  8459. //      linenumber=linenum2;
  8460.         if(searchteg)searchteg=NULL;
  8461.         nexttok();
  8462. }
  8463.  
  8464. /* ======= procedure handling ends here ======== */
  8465.  
  8466. int  macros(int expectedreturn)
  8467. {
  8468. int dynamicindex,actualreturn;
  8469. ITOK otok;
  8470. int orettype;
  8471. unsigned int oproctype;
  8472. int otok2;
  8473. unsigned int typep;
  8474. int snum=0;
  8475.         actualreturn=(am32==FALSE?tk_word:tk_dword);
  8476.         switch(tok){
  8477.                 case tk_ID:
  8478.                 case tk_id:
  8479.                         dynamicindex=NOT_DYNAMIC;
  8480.                         break;
  8481.                 case tk_proc:
  8482.                 case tk_undefproc:
  8483.                 case tk_declare:
  8484.                         dynamicindex=itok.segm;
  8485.                         actualreturn=itok.rm;
  8486.                         break;
  8487.                 default:
  8488.                         idalreadydefined();
  8489.                         return expectedreturn;
  8490.         }
  8491.         typep=itok.flag;
  8492.         otok=itok;
  8493.         if(tok==tk_ID)param[0]=0;
  8494.         else strcpy(param,(char *)string);
  8495.         nexttok();
  8496.         orettype=returntype;
  8497.         returntype=actualreturn;        //01.08.04 14:45
  8498.         oproctype=current_proc_type;
  8499.         if(dynamicindex==NOT_DYNAMIC)doregparams();
  8500.         else{
  8501.                 switch(typep&f_typeproc){
  8502.                         case tp_cdecl:
  8503.                         case tp_stdcall:
  8504.                                 snum=swapparam();
  8505.                                 break;
  8506.                         case tp_pascal:
  8507.                                 snum=doparams();
  8508.                                 break;
  8509.                         case tp_fastcall:
  8510.                                 doregparams();
  8511.                                 break;
  8512.                 }
  8513.         }
  8514.         itok=otok;
  8515.         otok2=tok2;
  8516.         if(dynamicindex==NOT_DYNAMIC){
  8517.                 if((actualreturn=includeit(0))==-1){
  8518.                         char holdstr[IDLENGTH+16];
  8519.                         sprintf(holdstr,"unknown macro '%s'",itok.name);
  8520.                         preerror(holdstr);
  8521.                 }
  8522.         }
  8523.         else insert_dynamic(TRUE);
  8524.         if(actualreturn!=tk_void&&expectedreturn!=tk_ID)convert_returnvalue(expectedreturn,actualreturn);
  8525.         returntype=orettype;
  8526.         current_proc_type=oproctype;
  8527.         if(snum!=0){
  8528.                 if(typep&f_retproc)warningdestroyflags();
  8529.                 CorrectStack(snum);
  8530.         }
  8531.         tok2=otok2;
  8532.         return actualreturn;
  8533. }
  8534.  
  8535. int updatecall(unsigned int which,unsigned int where,unsigned int top)
  8536. /* update output with newly defined location, but only for addresses after
  8537.          and including top. return the number of addresses updated.
  8538.   which - àäðåñ ïðîöåäóðû
  8539.   where - òåêóùèé àäðåñ*/
  8540. {
  8541. unsigned int count=0;
  8542. long hold;
  8543. int updates=0;
  8544.         while(count<posts){
  8545.                 if(((postbuf+count)->type>=CALL_SHORT&&(postbuf+count)->type<=CONTINUE_32)&&
  8546.                                 (postbuf+count)->num==which&&(postbuf+count)->loc>=top){
  8547.                         hold=(long)where-(long)(postbuf+count)->loc;
  8548.                         if((postbuf+count)->type>=CALL_NEAR&&(postbuf+count)->type<=CONTINUE_NEAR){     //NEAR
  8549.                                 hold-=2;
  8550.                                 *(unsigned short *)&output[(postbuf+count)->loc]=(unsigned short)hold;
  8551.                         }
  8552.                         else if((postbuf+count)->type>=CALL_32&&(postbuf+count)->type<=CONTINUE_32){//32-BIT
  8553.                                 hold-=4;
  8554.                                 *(unsigned long *)&output[(postbuf+count)->loc]=(unsigned long)hold;
  8555.                         }
  8556.                         else{   //SHORT
  8557.                                 hold--;  // CALL_SHORT
  8558.                                 if(short_ok(hold))output[(postbuf+count)->loc]=(unsigned char)hold;
  8559.                                 else{
  8560.                                         if((postbuf+count)->type==BREAK_SHORT)preerror3("BREAK distance too large, use break",(postbuf+count)->line);
  8561.                                         else if((postbuf+count)->type==CONTINUE_SHORT)preerror3("CONTINUE distance too large, use continue",(postbuf+count)->line);
  8562.                                         else preerror3(shorterr,(postbuf+count)->line,(postbuf+count)->file);
  8563.                                 }
  8564.                         }
  8565.                         if(hold<127){
  8566.                                 if((postbuf+count)->type==JMP_NEAR||(postbuf+count)->type==JMP_32)warningjmp("GOTO",(postbuf+count)->line,(postbuf+count)->file);
  8567.                                 if((postbuf+count)->type==BREAK_NEAR||(postbuf+count)->type==BREAK_32)warningjmp("BREAK",(postbuf+count)->line);
  8568.                                 if((postbuf+count)->type==CONTINUE_NEAR||(postbuf+count)->type==CONTINUE_32)warningjmp("CONTINUE",(postbuf+count)->line);
  8569.                         }
  8570.                         killpost(count);
  8571.                         updates++;
  8572.                 }
  8573.                 else count++;
  8574.         }
  8575.         if(updates==1&&hold==0)return -1;
  8576.         return(updates);
  8577. }
  8578.  
  8579. void define_locallabel()
  8580. {
  8581.         FindOff(string,CS);
  8582.         updatecall((unsigned int)updatelocalvar((char *)string,tk_number,outptr),outptr,procedure_start);
  8583.         nextexpecting2(tk_colon);
  8584.         RestoreStack();
  8585.         clearregstat();
  8586. #ifdef OPTVARCONST
  8587.         ClearLVIC();
  8588. #endif
  8589. }
  8590.  
  8591. void  addacall(unsigned int idnum,unsigned char callkind)
  8592. {
  8593.         CheckPosts();
  8594.         (postbuf+posts)->num=idnum;
  8595.         (postbuf+posts)->loc=outptr+1;
  8596.         (postbuf+posts)->type=callkind;
  8597.         (postbuf+posts)->line=(unsigned short)linenumber;
  8598.         (postbuf+posts)->file=(unsigned short)currentfileinfo;
  8599.         posts++;
  8600. }
  8601.  
  8602. unsigned int dofrom() // returns number of bytes read from FROM file
  8603. {
  8604. int filehandle;
  8605. long filesize;
  8606.         if(tok!=tk_string){
  8607.                 stringexpected();
  8608.                 return(0);
  8609.         }
  8610. #ifndef _WIN32_
  8611.         for(char* p=(char *)string3; *p; ++p) if(*p=='\\') *p='/';
  8612. #endif
  8613.         filehandle=open((char *)string3,O_BINARY|O_RDONLY);
  8614.         if(filehandle==-1){
  8615.                 unableopenfile((char *)string3);
  8616.                 return(0);
  8617.         }
  8618.         if((filesize=getfilelen(filehandle))==-1L){
  8619.                 preerror("Unable to determine FROM file size");
  8620.                 close(filehandle);
  8621.                 return(0);
  8622.         }
  8623.         if(am32==FALSE&&filesize>=0xFFFFL){
  8624.                 preerror("FROM file too large");
  8625.                 close(filehandle);
  8626.                 return(0);
  8627.         }
  8628.         LoadData(filesize,filehandle);
  8629.         return filesize;
  8630. }
  8631.  
  8632. unsigned int doextract() // returns number of bytes EXTRACTed
  8633. {
  8634. unsigned int sizetoread;
  8635. int filehandle;
  8636. long filesize,startpos;
  8637.         if(tok!=tk_string){
  8638.                 stringexpected();
  8639.                 return(0);
  8640.         }
  8641.         filehandle=open((char *)string3,O_BINARY|O_RDONLY);
  8642.         if(filehandle==-1){
  8643.                 unableopenfile((char *)string3);
  8644.                 return(0);
  8645.         }
  8646.         nexttok();
  8647.         expecting(tk_camma);
  8648.         if(tok!=tk_number){
  8649.                 numexpected();
  8650.                 return(0);
  8651.         }
  8652.         startpos=doconstlongmath();
  8653.         expecting(tk_camma);
  8654.         if(tok!=tk_number){
  8655.                 numexpected();
  8656.                 return(0);
  8657.         }
  8658.         sizetoread=doconstlongmath();
  8659.         if((filesize=getfilelen(filehandle))==-1L){
  8660.                 preerror("Unable to determine EXTRACT file size");
  8661.                 close(filehandle);
  8662.                 return(0);
  8663.         }
  8664.         if(filesize<=startpos){
  8665.                 preerror("EXTRACT offset exceeds the length of the file");
  8666.                 close(filehandle);
  8667.                 return(0);
  8668.         }
  8669.         if(sizetoread==0)sizetoread=filesize-startpos;
  8670.         if(am32==FALSE&&sizetoread>=0xFFFFL){
  8671.                 preerror("Block to EXTRACT exceeds 64K");
  8672.                 close(filehandle);
  8673.                 return(0);
  8674.         }
  8675.         lseek(filehandle,startpos,0);   // error checking required on this
  8676.         LoadData(sizetoread,filehandle);
  8677.         return sizetoread;
  8678. }
  8679.  
  8680. void LoadData(unsigned int size,int filehandle)
  8681. {
  8682.         if(splitdata){
  8683.                 while(((unsigned long)size+(unsigned long)outptrdata)>=outdatasize){
  8684.                         if(CheckDataSize()==0)break;
  8685.                 }
  8686.                 if((unsigned int)read(filehandle,outputdata+outptrdata,size)!=size)errorreadingfile((char *)string3);
  8687.                 outptrdata+=size;
  8688.         }
  8689.         else{
  8690.                 while(((unsigned long)size+(unsigned long)outptr)>=outptrsize){
  8691.                         if(CheckCodeSize()==0)break;
  8692.                 }
  8693.                 if((unsigned int)read(filehandle,output+outptr,size)!=size)errorreadingfile((char *)string3);
  8694.                 outptr+=size;
  8695.                 outptrdata=outptr;
  8696.         }
  8697.         close(filehandle);
  8698. }
  8699.  
  8700. void  op66(int ctok)
  8701. {
  8702.         if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){
  8703.                 if(cpu<3)cpu=3;
  8704.                 op(0x66);
  8705.         }
  8706. }
  8707.  
  8708. int  op67(int ctok)
  8709. {
  8710.         if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){
  8711.                 if(cpu<3)cpu=3;
  8712.                 op(0x67);
  8713.                 return TRUE;
  8714.         }
  8715.         return FALSE;
  8716. }
  8717.  
  8718. void  outseg(ITOK *outtok,unsigned int locadd)
  8719. {
  8720. int rmm1;
  8721.         rmm1=outtok->rm&7;
  8722.         if(outtok->sib!=CODE16){
  8723.                 if(am32==FALSE)op(0x67);
  8724.                 if(rmm1==4)locadd++;
  8725.         }
  8726.         else if(am32!=FALSE)op(0x67);
  8727.         switch(outtok->segm){
  8728.                 case ES: op(0x26); break;
  8729.                 case CS: op(0x2E); break;
  8730.                 case FS: op(0x64);
  8731.                         if(cpu<3)cpu=3;
  8732.                         break;
  8733.                 case GS: op(0x65);
  8734.                         if(cpu<3)cpu=3;
  8735.                         break;
  8736.                 case SS:
  8737.                         if(outtok->sib==CODE16){
  8738.                                 if(rmm1!=2&&rmm1!=3&&!(rmm1==6&&outtok->rm!=6))op(0x36);
  8739.                         }
  8740.                         else{
  8741.                                 if(rmm1==4){
  8742.                                         rmm1=outtok->sib&7;
  8743.                                         if(rmm1!=4){
  8744.                                                 if(rmm1==5){
  8745.                                                         if(outtok->rm==4)op(0x36);
  8746.                                                         break;
  8747.                                                 }
  8748.                                                 op(0x36);
  8749.                                         }
  8750.                                 }
  8751.                                 else if(rmm1==5){
  8752.                                         if(outtok->rm==5)op(0x36);
  8753.                                         else break;
  8754.                                 }
  8755.                                 else op(0x36);
  8756.                         }
  8757.                         break;
  8758.                 case DS:
  8759.                         if(outtok->sib==CODE16){
  8760.                                 if(rmm1==2||rmm1==3||(rmm1==6&&outtok->rm!=6))op(0x3E);
  8761.                         }
  8762.                         else{
  8763.                                 if(rmm1==4){
  8764.                                         rmm1=outtok->sib&7;
  8765.                                         if(rmm1==4||(rmm1==5&&outtok->rm!=4))op(0x3e);
  8766.                                 }
  8767.                                 else if(rmm1==5&&outtok->rm!=5)op(0x3e);
  8768.                         }
  8769.         }
  8770.         CheckPosts();
  8771.         if(outtok->post!=0&&outtok->post!=UNDEF_OFSET){
  8772.                 if((outtok->flag&f_extern)){
  8773.                         (postbuf+posts)->type=EXT_VAR;
  8774.                         (postbuf+posts)->num=outtok->number&0xFFFF;
  8775.                         outtok->number>>=16;
  8776.                 }
  8777.                 else if(outtok->post==USED_DIN_VAR){
  8778.                         (postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32);
  8779. //                      printf("Add tok=%d %08X sib=%d %s\n",outtok->rec->rectok,outtok->rec->right,outtok->rec->recsib,outtok->rec->recid);
  8780.                         if(outtok->rec->rectok==tk_structvar&&outtok->rec->recsib==tp_gvar){
  8781.                                 (postbuf+posts)->num=(int)outtok->rec;//02.09.05 17:10 ->right;
  8782.                         }
  8783.                         else (postbuf+posts)->num=(int)outtok->rec;
  8784.                 }
  8785. //              else if((outtok->flag&f_dataseg))(postbuf+posts)->type=(unsigned short)(am32==0?DATABLOCK_VAR:DATABLOCK_VAR32);
  8786.                 else (postbuf+posts)->type=(unsigned short)(am32==0?POST_VAR:POST_VAR32);
  8787.                 (postbuf+posts)->loc=outptr+locadd;
  8788.                 posts++;
  8789.         }
  8790.         else if(outtok->flag&f_reloc){
  8791.                 (postbuf+posts)->type=(unsigned short)(am32==0?FIX_VAR:FIX_VAR32);
  8792.                 (postbuf+posts)->loc=outptr+locadd;
  8793.                 posts++;
  8794.         }
  8795. }
  8796.  
  8797. int addpoststring(int segm,int len,int term)            /* add a string to the post queue */
  8798. {
  8799. int i;
  8800. int returnvalue;
  8801.         if((returnvalue=FindDublString(segm,len,term))!=-1)return returnvalue;
  8802.         CheckPosts();
  8803.         (postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32);
  8804.         (postbuf+posts)->loc=(segm==CS?outptr:outptrdata);
  8805.         (postbuf+posts)->num=segm;
  8806.         posts++;
  8807.         returnvalue=poststrptr;
  8808.         if((int)(len+poststrptr+1)>=sbufstr){
  8809.                 sbufstr+=SIZEBUF;
  8810.                 bufstr=(char *)REALLOC(bufstr,sbufstr);
  8811.         }
  8812.         for(i=0;i<len;i++,poststrptr++)bufstr[poststrptr]=string[i];
  8813.         switch(term&3){
  8814.                 case zero_term:
  8815.                         if(term&s_unicod){
  8816.                                 poststrptr++;
  8817.                                 bufstr[poststrptr]=0;
  8818.                         }
  8819.                         bufstr[poststrptr]=0;
  8820.                         poststrptr++;
  8821.                         break;
  8822.                 case dos_term:
  8823.                         if(term&s_unicod){
  8824.                                 bufstr[poststrptr]=0;
  8825.                                 poststrptr++;
  8826.                         }
  8827.                         bufstr[poststrptr]='$';
  8828.                         poststrptr++;
  8829.                         break;
  8830.         }
  8831.         return(returnvalue);
  8832. }
  8833.  
  8834. int FindDublString(int segm,unsigned int len,int term)
  8835. {
  8836. STRING_LIST ins,outs;
  8837. void *nextstr=liststring,*prevstr=NULL;
  8838.         ins.len=len;
  8839.         ins.next=NULL;
  8840.         ins.type=term;
  8841. /*      if(splitdata){  //ðàçäåëåíûå äàíûå è êîä
  8842.                 ins.plase=0;
  8843.                 ins.ofs=outptrdata;
  8844.         }
  8845.         else{*/
  8846.                 ins.plase=POST_STRING;
  8847.                 ins.ofs=poststrptr;
  8848. //      }
  8849.  
  8850.         while(nextstr!=NULL){
  8851.                 memcpy(&outs,nextstr,sizeof(STRING_LIST));
  8852.                 if(term==outs.type&&len<=outs.len){
  8853. char *instr,*outstr;
  8854.                         outstr=(char *)nextstr+sizeof(STRING_LIST)+outs.len-1;
  8855.                         instr=(char *)string+len-1;
  8856. char c;
  8857. int i,j;
  8858.                         for(i=len,j=outs.len;i!=0;j--,i--,instr--,outstr--){
  8859.                                 c=*instr;
  8860.                                 if(c!=*outstr)break;
  8861.                         }
  8862.                         if(i==0){       //íàéäåíà ñòðîêà
  8863.                                 if(!optstr)return -1;
  8864.                                 warningstring();
  8865.                                 if(outs.plase==0){      //óæå â ôàéëå
  8866.                                         AddReloc(DS);
  8867.                                         return outs.ofs+j;
  8868.                                 }
  8869.                                 CheckPosts();
  8870.                                 (postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32);
  8871.                                 (postbuf+posts)->loc=(segm==CS?outptr:outptrdata);
  8872.                                 (postbuf+posts)->num=segm;
  8873.                                 posts++;
  8874.                                 return outs.ofs+j;
  8875.                         }
  8876.                 }
  8877.                 prevstr=nextstr;
  8878.                 nextstr=outs.next;
  8879.         }
  8880.         outs.next=(void *)MALLOC(sizeof(STRING_LIST)+len);
  8881.         memcpy(outs.next,&ins,sizeof(STRING_LIST));
  8882.         if(len!=0)memcpy((char *)outs.next+sizeof(STRING_LIST),&string,len);
  8883.         if(prevstr!=NULL)memcpy(prevstr,&outs,sizeof(STRING_LIST));
  8884.         else liststring=outs.next;
  8885.         return -1;
  8886. }
  8887.  
  8888. void killpost(unsigned int poz)
  8889. {
  8890.         posts--;
  8891.         memcpy((postinfo *)(postbuf+poz),(postinfo *)(postbuf+posts),sizeof(postinfo));
  8892. }
  8893.  
  8894. void dopoststrings()
  8895. {
  8896. unsigned int addvalue,i;
  8897.         if(poststrptr==0)return;
  8898.         if(splitdata){
  8899.                 addvalue=outptrdata;
  8900.                 if((outptrdata+poststrptr)>=outdatasize)CheckDataSize();
  8901.         }
  8902.         else{
  8903.                 addvalue=outptr;
  8904.                 if((outptr+poststrptr)>=outptrsize)CheckCodeSize();
  8905.         }
  8906.         datasize+=poststrptr;
  8907.         if(dbg&2)AddDataNullLine(3);
  8908.         memcpy(&outputdata[outptrdata],bufstr,poststrptr);
  8909.         outptrdata+=poststrptr;
  8910.         if(!splitdata)outptr=outptrdata;
  8911.         for(i=0;i<posts;i++){
  8912.                 int segm=(postbuf+i)->num;
  8913.                 if((postbuf+i)->type==POST_STRING){
  8914.                         if(segm==CS)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)addvalue;
  8915.                         else *(unsigned short *)&outputdata[(postbuf+i)->loc]+=(unsigned short)addvalue;
  8916.                         if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR;
  8917.                         else if(FixUp==FALSE)killpost(i--);
  8918.                         else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR:FIX_CODE);
  8919.                 }
  8920.                 else if((postbuf+i)->type==POST_STRING32){
  8921.                         if(segm==CS)*(unsigned int *)&output[(postbuf+i)->loc]+=addvalue;
  8922.                         else *(unsigned int *)&outputdata[(postbuf+i)->loc]+=addvalue;
  8923.                         if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR32;
  8924.                         else if(FixUp==FALSE)killpost(i--);
  8925.                         else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR32:FIX_CODE32);
  8926.                 }
  8927.         }
  8928.         poststrptr=0;    /* reset the poststrptr */
  8929. STRING_LIST ins;
  8930.         void *nextstr=liststring;
  8931.         while(nextstr!=NULL){
  8932.                 memcpy(&ins,nextstr,sizeof(STRING_LIST));
  8933.                 if(ins.plase!=0){
  8934.                         ins.plase=0;
  8935.                         ins.ofs+=addvalue;
  8936.                         memcpy(nextstr,&ins,sizeof(STRING_LIST));
  8937.                 }
  8938.                 nextstr=ins.next;
  8939.         }
  8940.         if(dbg&2)AddCodeNullLine();
  8941. }
  8942.  
  8943. void insertcode()               // force code procedure at specified location
  8944. {
  8945.         nexttok();
  8946.         testInitVar(FALSE);
  8947.         if((itok.flag&f_extern)!=0){
  8948.                 notexternfun();
  8949.                 return;
  8950.         }
  8951.         int tproc=itok.flag&f_typeproc;
  8952.         setuprm();
  8953.         switch(tok){
  8954.                 case tk_undefproc:
  8955.                 case tk_declare:
  8956.                         tok=tk_proc;
  8957.                         itok.number=outptr;
  8958.                         updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0);
  8959.                         if(tproc==tp_fastcall){
  8960.                                 if(includeit(1)==-1)thisundefined(itok.name);
  8961.                         }
  8962.                         else if(includeproc()==-1)thisundefined(itok.name);
  8963.                         break;
  8964.                 case tk_id:
  8965.                 case tk_ID:
  8966.                         tok=tk_proc;
  8967.                         itok.number=outptr;
  8968.                         string[0]=0;
  8969.                         itok.type=tp_ucnovn;
  8970.                         addtotree(itok.name);
  8971.                         if(tproc==tp_fastcall){
  8972.                                 if(includeit(1)==-1)thisundefined(itok.name);
  8973.                         }
  8974.                         else if(includeproc()==-1)thisundefined(itok.name);
  8975.                         break;
  8976.                 case tk_proc:
  8977.                         if(itok.segm<NOT_DYNAMIC)insert_dynamic();
  8978.                         else preerror("Function already inserted in code");
  8979.                         break;
  8980.                 default: idalreadydefined(); break;
  8981.         }
  8982.         nextexpecting2(tk_openbracket);
  8983.         while(tok!=tk_eof&&tok!=tk_closebracket)nexttok();
  8984.         if(tok==tk_eof)unexpectedeof();
  8985.         else nextseminext();
  8986. }
  8987.  
  8988. /************ some of the dynamic procedure support functions *************/
  8989.  
  8990. void insert_dynamic(int insert)
  8991. {
  8992. unsigned char *oinput;
  8993. int oinptr;
  8994. unsigned char ocha;
  8995. int oline;
  8996. int ofile;
  8997. char *ostartline;
  8998. int oendinptr;
  8999. structteg *osearchteg;
  9000. int oinsert;
  9001. _PROCINFO_ *pinfo;
  9002. SAVEPAR *par;
  9003.         if(insert){
  9004.                 osearchteg=searchteg;
  9005.                 searchteg=NULL;
  9006.         }
  9007. //      printf("cur_mod=%08X\n",cur_mod);
  9008.         oinsert=insert;
  9009.         oinput=input;
  9010.         oinptr=inptr2;
  9011.         ocha=cha2;
  9012.         oline=linenum2;
  9013.         ofile=currentfileinfo;
  9014.         (startfileinfo+currentfileinfo)->stlist=staticlist;
  9015.         oendinptr=endinptr;
  9016.         endoffile=0;
  9017.         ostartline=startline;
  9018.         idrec *ptr=itok.rec;
  9019.         pinfo=ptr->pinfo;
  9020.         input=(unsigned char *)pinfo->buf;
  9021.         inptr2=1;
  9022.         startline=(char *)input;
  9023.         cha2=input[0];
  9024.         endinptr=strlen((char *)input);
  9025.         endinput=startline+endinptr;
  9026.         linenumber=linenum2=ptr->line;
  9027.         currentfileinfo=ptr->file;
  9028.         staticlist=(startfileinfo+currentfileinfo)->stlist;
  9029.         par=SRparam(TRUE,NULL);
  9030.         warning=pinfo->warn;
  9031.         optimizespeed=pinfo->speed;
  9032.         dosstring=pinfo->typestring;
  9033.         useinline=pinfo->inlinest;
  9034.         am32=pinfo->code32;
  9035.         alignword=pinfo->align;
  9036.         AlignCycle=pinfo->acycle;
  9037.         idasm=pinfo->idasm;
  9038.         optnumber=pinfo->opnum;
  9039.         divexpand=pinfo->de;
  9040.         optstr=pinfo->ostring;
  9041.         chip=pinfo->chip;
  9042.         aligncycle=pinfo->sizeacycle;
  9043.         uselea=pinfo->uselea;
  9044.         regoverstack=pinfo->regoverstack;
  9045.         if(pinfo->classteg!=NULL){
  9046.                 /*if((itok.flag&f_static)==0)*/searchteg=(structteg *)pinfo->classteg;
  9047.                 insert=0;
  9048.         }
  9049.         if(pinfo->lst)dbg|=2;
  9050.         else dbg&=0xFD;
  9051. //      puts(itok.name);
  9052.         if(!insert){
  9053.                 procedure_start=outptr;
  9054.                 if(dbg){
  9055.                         if(dbg&2){
  9056.                                 char m1[130];
  9057.                                 //11.08.04 23:39
  9058. //                              if(searchteg)sprintf(m1,"%s::%s()",searchteg->name,itok.name);
  9059. //                              else sprintf(m1,"%s()",itok.name);
  9060.                                 sprintf(m1,"%s()",itok.name);
  9061.  
  9062.                                 AddCodeNullLine(m1);
  9063.                         }
  9064.                         else AddLine();
  9065.                 }
  9066.                 if(AlignProc)AlignCD(CS,alignproc);
  9067. //              puts((char *)input);
  9068.                 if(pinfo->classteg==NULL)itok.flag&=~f_static;
  9069.                 setproc(1);
  9070.                 dopoststrings();
  9071.         }
  9072.         else insertproc();
  9073.         input=oinput;
  9074.         inptr2=oinptr;
  9075.         cha2=ocha;
  9076.         linenum2=oline;
  9077. //      printf("cur_mod=%08X\n",cur_mod);
  9078.         (startfileinfo+currentfileinfo)->stlist=staticlist;
  9079.         currentfileinfo=ofile;
  9080.         staticlist=(startfileinfo+currentfileinfo)->stlist;
  9081.         endinptr=oendinptr;
  9082.         endoffile=0;
  9083.         startline=ostartline;
  9084.         SRparam(FALSE,par);
  9085.         if(oinsert)searchteg=osearchteg;
  9086.         else searchteg=NULL;
  9087. //      if(insert)nexttok();
  9088. //      printf("tok=%d %08X\n",tok,cur_mod);
  9089. }
  9090.  
  9091. idrec *addtotree(char *keystring)//äîáàâèòü ñòðîêó â äåðåâî
  9092. {
  9093. struct idrec *ptr,*newptr;
  9094. int cmpresult;
  9095. //âûäåëèòü ïàìÿòü ïîä íîâóþ ïðîö
  9096.         newptr=(struct idrec *)MALLOC(sizeof(struct idrec));
  9097.         ptr=(itok.flag&f_static)!=0?staticlist:treestart;       //íà÷àëî äåðåâà
  9098.         if(ptr==NULL)((itok.flag&f_static)!=0?staticlist:treestart)=newptr;//íà÷àëî äåðåâà
  9099.         else{   //ïîèñê ñòðîêè â äåðåâå
  9100.                 while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)||
  9101.        (cmpresult>0&&ptr->right!=NULL))ptr=(cmpresult<0?ptr->left:ptr->right);
  9102.                 (cmpresult<0?ptr->left:ptr->right)=newptr;
  9103.         }
  9104.         strcpy(newptr->recid,keystring);//ñêîïèð íàçâàíèå
  9105.         newptr->newid=NULL;
  9106.         if(string[0]!=0)newptr->newid=BackString((char *)string);
  9107.         newptr->rectok=tok;
  9108.         newptr->recnumber=itok.number;
  9109.         newptr->recsegm=itok.segm;
  9110.         newptr->recrm=itok.rm;
  9111.         newptr->recpost=itok.post;
  9112.         newptr->flag=itok.flag;
  9113.         newptr->recsize=itok.size;
  9114.         newptr->left=newptr->right=NULL;
  9115.         newptr->sbuf=NULL;
  9116.         newptr->recsib=itok.sib;
  9117.         newptr->line=linenumber;
  9118.         newptr->file=currentfileinfo;
  9119.         newptr->count=0;
  9120.         newptr->type=itok.type;
  9121.         newptr->npointr=itok.npointr;
  9122.         itok.rec=newptr;
  9123.         return newptr;
  9124. }
  9125.  
  9126. long updatetree()                        // returns the old number value
  9127. {
  9128. struct idrec *ptr;
  9129. long hold;
  9130.         ptr=itok.rec;
  9131.         if(ptr==0)internalerror("address record not found when update tree");
  9132.         if(ptr->newid)free(ptr->newid);
  9133.         ptr->newid=NULL;
  9134.         if(string[0]!=0)ptr->newid=BackString((char *)string);
  9135.         ptr->rectok=tok;
  9136.         hold=ptr->recnumber;
  9137.         ptr->recnumber=itok.number;
  9138.         ptr->recsegm=itok.segm;
  9139.         ptr->recrm=itok.rm;
  9140.         ptr->flag=itok.flag;
  9141.         ptr->recsize=itok.size;
  9142.         ptr->recsib=itok.sib;
  9143.         return hold;
  9144. }
  9145.  
  9146. /* --------------- local variable handling starts here ----------------- */
  9147.  
  9148. unsigned int  updatelocalvar(char *str,int tok4,unsigned int num)
  9149. {
  9150. struct localrec *ptr;
  9151. unsigned int retvalue;
  9152. treelocalrec *ntlr=tlr;
  9153.         while(ntlr&&ntlr->level>1)ntlr=ntlr->next;
  9154.         for(ptr=ntlr->lrec;;ptr=ptr->rec.next){
  9155.                 if(strcmp(ptr->rec.recid,str)==0){
  9156.                         retvalue=ptr->rec.recnumber;
  9157.                         ptr->rec.rectok=tok4;
  9158.                         ptr->rec.recnumber=num;
  9159.                         break;
  9160.                 }
  9161.                 if(ptr->rec.next==NULL)break;
  9162.         }
  9163.         return(retvalue);
  9164. }
  9165.  
  9166. localrec * addlocalvar(char *str,int tok4,unsigned int num,int addmain)
  9167. {
  9168. localrec *ptr,*newptr;
  9169. localrec *uptr;
  9170. treelocalrec *ntlr;
  9171.         if(addmain){
  9172.                 ntlr=tlr;
  9173.                 while(ntlr&&ntlr->level>1)ntlr=ntlr->next;
  9174.                 uptr=ntlr->lrec;
  9175.         }
  9176.         else uptr=tlr->lrec;
  9177.         newptr=(struct localrec *)MALLOC(sizeof(struct localrec));
  9178.  
  9179.         if(uptr==NULL){
  9180.                 if(addmain)ntlr->lrec=newptr;
  9181.                 else tlr->lrec=newptr;
  9182.         }
  9183.         else{
  9184.                 ptr=uptr;
  9185.                 while(ptr->rec.next!=NULL)ptr=ptr->rec.next;
  9186.                 ptr->rec.next=newptr;
  9187.         }
  9188.         strcpy(newptr->rec.recid,str);
  9189.         newptr->rec.rectok=tok4;
  9190.         newptr->rec.recnumber=num;
  9191.         newptr->rec.next=NULL;
  9192.         newptr->rec.right=NULL;
  9193.         newptr->rec.recsize=0;
  9194.         newptr->fuse=NOTINITVAR;
  9195.         newptr->rec.type=tp_ucnovn;
  9196.         newptr->rec.flag=0;
  9197.         newptr->rec.npointr=0;
  9198.         newptr->rec.recpost=LOCAL;
  9199.         newptr->li.count=0;
  9200.         newptr->li.start=linenumber;
  9201.         return newptr;
  9202. }
  9203.  
  9204. void KillTegList(structteg *tteg)
  9205. {
  9206.         if(tteg){
  9207.                 KillTegList(tteg->left);
  9208.                 KillTegList(tteg->right);
  9209.                 if(tteg->baza)free(tteg->baza);
  9210.                 free(tteg);
  9211.         }
  9212. }
  9213.  
  9214. void killlocals(/*int endp*/)
  9215. /* Clear and free the local linked list, check for any unresolved local
  9216. jump labels. */
  9217. {
  9218. /*      if(endp){
  9219.                 dopoststrings();
  9220.                 for(int i=0;i<posts;i++){
  9221. //                              printf("%d type=%d num=%08X\n",i+1,(postbuf+i)->type,(postbuf+i)->num);
  9222.                         if((postbuf+i)->type==DIN_VAR||(postbuf+i)->type==DIN_VAR32){
  9223.                                 idrec *ptr=(idrec *)(postbuf+i)->num;
  9224. //                              printf("sib=%d num=%08X %s\n",ptr->recsib,ptr->recnumber,ptr->recid);
  9225.                                 if(ptr->recsib!=tp_gvar)continue;
  9226.                                 puts("recsib=tp_gvar");
  9227.                                 if(ptr->recpost==USED_DIN_VAR){
  9228. unsigned int otok,otok2;
  9229. ITOK oitok;
  9230.                                         oitok=itok;
  9231.                                         otok=tok;
  9232.                                         otok2=tok2;
  9233.                                         setdindata(ptr,i);
  9234.                                         itok=oitok;
  9235.                                         tok=otok;
  9236.                                         tok2=otok2;
  9237.                                 }
  9238.                                 else{
  9239.                                         if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber);
  9240.                                         else *(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber;
  9241.                                 }
  9242.                                 if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32);
  9243.                                 else killpost(i--);
  9244.                         }
  9245.                 }
  9246.                 dopoststrings();
  9247.         }
  9248.         */
  9249. treelocalrec *ftlr,*ftlr1;
  9250. struct localrec *ptr, *ptr1;
  9251.         for(ftlr=btlr;ftlr!=NULL;){
  9252.                 ftlr1=ftlr;
  9253.                 for(ptr=ftlr->lrec;ptr!=NULL;){
  9254.                         ptr1=ptr;
  9255.                         if(ptr->rec.rectok==tk_locallabel){  /* check for unresolved labels */
  9256. char holdstr[32+IDLENGTH];
  9257.                                 sprintf(holdstr,"local jump label '%s' unresolved",ptr1->rec.recid);
  9258.                                 preerror(holdstr);
  9259.                         }
  9260. //                      printf("type=%d post=%08X %s\n",ptr->rec.type,ptr->rec.recpost,ptr->rec.recid);
  9261.                         if(ptr->rec.rectok==tk_structvar){
  9262.                                 if(ptr->rec.count==0){
  9263.                                         warningnotused(ptr->rec.recid,5);
  9264.                                         if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf);
  9265.                                 }
  9266.                         }
  9267.                         else if(ptr->fuse<USEDVAR){
  9268.                                 if(ptr->rec.type==tp_localvar||ptr->rec.type==tp_postvar||ptr->rec.type==tp_gvar)warningnotused(ptr->rec.recid,3);
  9269.                                 else if(ptr->rec.type==tp_paramvar)warningnotused(ptr->rec.recid,4);
  9270.                                 if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf);
  9271.                         }
  9272.                         ptr=ptr->rec.next;
  9273.                         if(ptr1->rec.recpost!=USED_DIN_VAR)free(ptr1);
  9274.                 }
  9275.                 ftlr=ftlr->next;
  9276.                 free(ftlr1);
  9277.         }
  9278.         btlr=NULL;
  9279.         paramsize=0;
  9280.         localsize=0;
  9281.         KillTegList(ltegtree);
  9282.         ltegtree=NULL;
  9283. }
  9284.  
  9285. /* ================ input procedures start ================= */
  9286. int loadinputfile(char *inpfile)        //ñ÷èòûâàíèå ôàéëà â ïàìÿòü
  9287. {
  9288. unsigned long size;
  9289. int filehandle;
  9290.         if((filehandle=open(inpfile,O_BINARY|O_RDONLY))==-1)return -2;
  9291.         if((size=getfilelen(filehandle))==0){
  9292.                 badinfile(inpfile);
  9293.                 close(filehandle);
  9294.                 return(-1);
  9295.         }
  9296.         if(totalmodule==0){
  9297.                 startfileinfo=(struct FILEINFO *)MALLOC(sizeof(FILEINFO));
  9298.                 totalmodule=1;
  9299.                 currentfileinfo=0;
  9300.         }      
  9301.         else{   //ïîèñê åìåíè ôàéëà â ñïèñêå îáðàáîòàííûõ
  9302.                 for(currentfileinfo=0;currentfileinfo<totalmodule;currentfileinfo++){
  9303.                         if(stricmp(inpfile,(startfileinfo+currentfileinfo)->filename)==0)break;
  9304.                 }
  9305.                 if(currentfileinfo!=totalmodule){
  9306.                         if(crif!=FALSE)return 1;
  9307.                         goto cont_load;
  9308.                 }
  9309.                 totalmodule++;
  9310.                 startfileinfo=(struct FILEINFO *)REALLOC(startfileinfo,sizeof(FILEINFO)*(totalmodule));
  9311.         }
  9312.  
  9313.         (startfileinfo+currentfileinfo)->stlist=NULL;
  9314.         (startfileinfo+currentfileinfo)->filename=(char *)MALLOC(strlen(inpfile)+1);
  9315.         strcpy((startfileinfo+currentfileinfo)->filename,inpfile);
  9316.         (startfileinfo+currentfileinfo)->numdline=0;
  9317.         //GetFileTime(filehandle,&(startfileinfo+currentfileinfo)->time); // bug
  9318. //      getftime(filehandle,&(startfileinfo+currentfileinfo)->time);
  9319. cont_load:
  9320.         staticlist=(startfileinfo+currentfileinfo)->stlist;
  9321.         input=(unsigned char *)MALLOC(size+1);
  9322.         printf("%08lX %s %lu\n",input,inpfile,size);
  9323.         if((endinptr=read(filehandle,input,size))!=size){
  9324. printf("%d\n",endinptr);
  9325.                
  9326.                 errorreadingfile(inpfile);
  9327.                 close(filehandle);
  9328.                 return(-1);
  9329.         }
  9330.         close(filehandle);
  9331.         return(0);
  9332. }
  9333.  
  9334. void notnegit(int notneg)
  9335. /* produce NOT .. or NEG .. */
  9336. {
  9337. int wordadd=0,i=0;
  9338.         getoperand();
  9339.         switch(tok){
  9340.                 case tk_reg: wordadd=1; op66(r16);
  9341.                         ClearReg(itok.number);
  9342.                 case tk_beg:
  9343.                         if(optimizespeed&&(chip==5||chip==6)){
  9344.                                 if(wordadd==0&&itok.number==AL)outword(0xFF34);
  9345.                                 else{
  9346.                                         if(wordadd)op(0x83);
  9347.                                         else op(0x80);
  9348.                                         op(0xF0+itok.number);
  9349.                                         op(0xFF);
  9350.                                 }
  9351.                                 if(notneg){
  9352.                                         if(wordadd){
  9353.                                                 op66(r16);
  9354.                                                 op(0x40+itok.number);
  9355.                                         }
  9356.                                         else{
  9357.                                                 op(0xFE);
  9358.                                                 op(0xC0+itok.number);
  9359.                                         }
  9360.                                 }
  9361.                         }
  9362.                         else{
  9363.                                 op(0xF6+wordadd);
  9364.                                 op(0xD0+notneg+itok.number);
  9365.                         }
  9366.                         if(wordadd==0)ClearReg(itok.number&3);
  9367.                         break;
  9368.                 case tk_wordvar:
  9369.                 case tk_intvar: wordadd=1;
  9370.                         i=1;
  9371.                 case tk_bytevar:
  9372.                 case tk_charvar:
  9373.                         i++;
  9374.                         CheckAllMassiv(bufrm,i,&strinf);
  9375.                         if(wordadd)op66(r16);
  9376.                         outseg(&itok,2);
  9377.                         if((!notneg)&&optimizespeed&&(chip==5||chip==6)){
  9378.                                 op(wordadd!=0?0x83:0x80);
  9379.                                 op(0x30+itok.rm);
  9380.                                 outaddress(&itok);
  9381.                                 op(0xFF);
  9382.                         }
  9383.                         else{
  9384.                                 op(0xF6+wordadd);
  9385.                                 op(0x10+notneg+itok.rm);
  9386.                                 outaddress(&itok);
  9387.                         }
  9388.                         KillVar(itok.name);
  9389.                         break;
  9390.                 case tk_reg32:
  9391.                         op66(r32);
  9392.                         if(optimizespeed&&(chip==5||chip==6)){
  9393.                                 op(0x83);
  9394.                                 outword(0xFFF0+itok.number);
  9395.                                 if(notneg){
  9396.                                         op66(r32);
  9397.                                         op(0x40+itok.number);
  9398.                                 }
  9399.                         }
  9400.                         else{
  9401.                                 op(0xF7);
  9402.                                 op(0xD0+notneg+itok.number);
  9403.                         }
  9404.                         if(cpu<3)cpu=3;
  9405.                         ClearReg(itok.number);
  9406.                         break;
  9407.                 case tk_reg64:
  9408.                         int r1,r2;
  9409.                         r1=itok.number&255;
  9410.                         r2=itok.number/256;
  9411.                         op66(r32);
  9412.                         op(0xF7);
  9413.                         op(0xD0+notneg+r2);  // NEG reg
  9414.                         op66(r32);
  9415.                         op(0xF7);
  9416.                         op(0xD0+notneg+r1);  // NEG reg
  9417.                         op66(r32);
  9418.                         op(0x83);
  9419.                         op(0xD8+r2);
  9420.                         op(0);
  9421.                         ClearReg(r1);
  9422.                         ClearReg(r2);
  9423.                         break;
  9424.                 case tk_longvar:
  9425.                 case tk_dwordvar:
  9426.                         CheckAllMassiv(bufrm,4,&strinf);
  9427.                         op66(r32);
  9428.                         outseg(&itok,2);
  9429.                         if((!notneg)&&optimizespeed&&(chip==5||chip==6)){
  9430.                                 op(0x83);
  9431.                                 op(0x30+itok.rm);
  9432.                                 outaddress(&itok);
  9433.                                 op(0xFF);
  9434.                         }
  9435.                         else{
  9436.                                 op(0xF7);
  9437.                                 op(0x10+notneg+itok.rm);
  9438.                                 outaddress(&itok);
  9439.                         }
  9440.                         if(cpu<3)cpu=3;
  9441.                         KillVar(itok.name);
  9442.                         break;
  9443.                 case tk_qword:
  9444.                         itok.number+=4;
  9445.                         compressoffset(&itok);
  9446.                         for(i=0;i<2;i++){
  9447.                                 CheckAllMassiv(bufrm,8,&strinf);
  9448.                                 op66(r32);
  9449.                                 outseg(&itok,2);
  9450.                                 op(0xF7);
  9451.                                 op(0x10+notneg+itok.rm);
  9452.                                 outaddress(&itok);
  9453.                                 if(i==1)break;
  9454.                                 itok.number-=4;
  9455.                                 compressoffset(&itok);
  9456.                         }
  9457.                         itok.number-=4;
  9458.                         compressoffset(&itok);
  9459.                         CheckAllMassiv(bufrm,8,&strinf);
  9460.                         op66(r32);
  9461.                         outseg(&itok,2);
  9462.                         op(0x83); op(0x18+itok.rm);
  9463.                         outaddress(&itok);
  9464.                         op(0);
  9465.                         KillVar(itok.name);
  9466.                         if(cpu<3)cpu=3;
  9467.                         break;
  9468.                 case tk_doublevar:
  9469.                         i=4;
  9470.                 case tk_floatvar:
  9471.                         if(notneg!=8)illegalfloat();
  9472.                         CheckAllMassiv(bufrm,4+i,&strinf);
  9473.                         outseg(&itok,2); //fld var
  9474.                         op(0xd9+i);
  9475.                         op(itok.rm);
  9476.                         outaddress(&itok);
  9477.                         outword(0xe0d9);    //fchs
  9478.                         outseg(&itok,2);//fstp var
  9479.                         op(0xd9+i);
  9480.                         op(itok.rm+0x18);
  9481.                         outaddress(&itok);
  9482.                         fwait3();
  9483.                         break;
  9484.                 default: varexpected(0);
  9485.         }
  9486. }
  9487.  
  9488. void setreturn()
  9489. {
  9490.         if(numreturn){
  9491. unsigned int pos,dist;
  9492. //int j=0;
  9493. //restart:
  9494.                 for(int i=0;i<numreturn;i++){
  9495. //                      if(!(listreturn+i)->use)continue;
  9496.                         pos=(listreturn+i)->loc;
  9497.                         dist=outptr-pos;
  9498.                         if((listreturn+i)->type==tk_RETURN){
  9499.                                 dist--;
  9500. //                              if(dist){
  9501.                                         if(dist>127/*&&i>=j*/)jumperror((listreturn+i)->line,mesRETURN);
  9502.                                         output[pos]=(unsigned char)dist;
  9503. /*                              }
  9504.                                 else{
  9505.                                         outptr-=2;
  9506.                                         j=i;
  9507.                                         (listreturn+i)->use=FALSE;
  9508.                                         goto restart;
  9509.                                 }*/
  9510.                         }
  9511.                         else{
  9512.                                 dist-=(am32==0?2:4);
  9513. //                              if(dist){
  9514.                                         if(dist<128/*&&i>=j*/)warningjmp(mesRETURN,(listreturn+i)->line,currentfileinfo);
  9515.                                         if(am32)*(unsigned long *)&output[pos]=dist;
  9516.                                         else*(unsigned short *)&output[pos]=(unsigned short)dist;
  9517. /*                              }
  9518.                                 else{
  9519.                                         outptr-=3;
  9520.                                         if(am32)outptr-=2;
  9521.                                         j=i;
  9522.                                         (listreturn+i)->use=FALSE;
  9523.                                         goto restart;
  9524.                                 }*/
  9525.                         }
  9526.                 }
  9527.                 free(listreturn);
  9528.                 listreturn=NULL;
  9529.                 numreturn=0;
  9530.         }
  9531. }
  9532.  
  9533. void RestoreSaveReg()
  9534. {
  9535.         if(psavereg->all){
  9536.                 op(0x61);
  9537.                 addESP-=am32==FALSE?16:32;
  9538.         }
  9539.         else{
  9540.                 for(int i=7;i>=0;i--){
  9541.                         if(psavereg->reg[i]){
  9542.                                 op66(psavereg->reg[i]);
  9543.                                 op(0x58+i);
  9544.                                 addESP-=am32==FALSE?2:4;
  9545.                         }
  9546.                 }
  9547.         }
  9548. }
  9549.  
  9550. void AddRetList(int pos,int line,int type)
  9551. {
  9552.         if(numreturn==0)listreturn=(RETLIST *)MALLOC(sizeof(RETLIST));
  9553.         else listreturn=(RETLIST *)REALLOC(listreturn,sizeof(RETLIST)*(numreturn+1));
  9554.         (listreturn+numreturn)->loc=pos;
  9555.         (listreturn+numreturn)->line=line;
  9556.         (listreturn+numreturn)->type=type;
  9557. //      (listreturn+numreturn)->use=TRUE;
  9558.         if(type==tk_return)jumploc0();
  9559.         else outword(0x00EB);   // JMP SHORT
  9560.         numreturn++;
  9561. }
  9562.  
  9563. void RetProc()
  9564. {
  9565.         if((current_proc_type&f_far)){
  9566.                 if((current_proc_type&f_typeproc)==tp_cdecl)retf();
  9567.                 else{
  9568.                         if(paramsize==0)retf();                                                         /* RETF */
  9569.                         else{
  9570.                                 op(0xCA);
  9571.                                 outword(paramsize);
  9572.                         }
  9573.                 }
  9574.         }
  9575.         else{
  9576.                 if((current_proc_type&f_typeproc)==tp_cdecl)ret();
  9577.                 else if(current_proc_type==f_interrupt)op(0xCF);//interrupt procedure IRET
  9578.                 else{
  9579.                         if(paramsize==0)ret();                                                   /* RET */
  9580.                         else{
  9581.                                 op(0xC2);
  9582.                                 outword(paramsize);
  9583.                         }
  9584.                 }
  9585.         }
  9586. }
  9587.  
  9588. void doreturn(int typer)         /* do return(...); */
  9589. {
  9590. char sign=0;
  9591. int line=linenumber;
  9592. char *ofsstr=NULL;
  9593. int i;
  9594. unsigned int oaddESP=addESP;
  9595.         if(tok2==tk_openbracket)nexttok();
  9596.         if((ofsstr=GetLecsem(tk_closebracket,tk_semicolon))){
  9597.                 int retreg;
  9598.                 int razr=getrazr(returntype);
  9599.                 if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){
  9600.                         GetEndLex(tk_closebracket,tk_semicolon);
  9601.                         if(razr==r16)tok=tk_reg;
  9602.                         else if(razr==r32)tok=tk_reg32;
  9603.                         else tok=tk_beg;
  9604.                         itok.number=retreg==SKIPREG?AX:retreg;
  9605.                         goto nn1;
  9606.                 }
  9607.         }
  9608.         getoperand();
  9609.         if(tok!=tk_closebracket&&tok!=tk_semicolon){
  9610. nn1:
  9611.                 switch(returntype){
  9612.                         case tk_int: sign=1;
  9613.                         case tk_word: do_e_axmath(sign,r16,&ofsstr); break;
  9614.                         case tk_char: sign=1;
  9615.                         case tk_byte: doalmath(sign,&ofsstr); break;
  9616.                         case tk_long: sign=1;
  9617.                         case tk_dword: do_e_axmath(sign,r32,&ofsstr); break;
  9618.                         case tk_qword:
  9619.                                 getintoreg64(EAX|(EDX*256));
  9620.                                 if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare)doregmath64(EAX|(EDX*256));
  9621.                                 break;
  9622.                         case tk_void: retvoid(); nexttok(); break;
  9623.                         case tk_double:
  9624. /*                              if(tok2==tk_closebracket)doregmath64(EAX|(EDX*256));
  9625.                                 else doeaxfloatmath(tk_reg64);
  9626.                                 break;*/
  9627.                         case tk_fpust:
  9628.                                 doeaxfloatmath(tk_fpust);
  9629.                                 break;
  9630.                         case tk_float:
  9631.                                 if(itok2.type==tp_stopper&&(tok==tk_floatvar||tok==tk_number)){
  9632.                                         if(tok==tk_floatvar){
  9633.                                                 tok=tk_dwordvar;
  9634.                                                 do_e_axmath(0,r32,&ofsstr);
  9635.                                         }
  9636.                                         else doeaxfloatmath(tk_reg32,0,0);
  9637.                                 }
  9638.                                 else{
  9639.                                         doeaxfloatmath(tk_stackstart,0,0);
  9640.                                         op66(r32);
  9641.                                         op(0x58);       //pop eax
  9642.                                 }
  9643.                                 break;
  9644. //                      default:
  9645. //                              printf("returntype=%d\n",returntype);
  9646.                 }
  9647.         }
  9648.         if(tok==tk_closebracket)nexttok();
  9649.         seminext();
  9650.         if(ofsstr)free(ofsstr);
  9651.         clearregstat();
  9652. #ifdef OPTVARCONST
  9653.         ClearLVIC();
  9654. #endif
  9655.         if(typer!=tokens){
  9656.                 i=(am32==0?2:4);
  9657.                 if(typer==tk_RETURN)i=1;
  9658.                 if(paramsize||localsize)i--;
  9659.                 if(insertmode||((!optimizespeed)&&paramsize&&
  9660.                                 (current_proc_type&f_typeproc)!=tp_cdecl)||psavereg->size>i){
  9661.                         if(numblocks>1){        //çàìåíèòü return íà goto
  9662.                                 AddRetList(outptr+1,line,typer);
  9663.                                 retproc=TRUE;
  9664.                                 return;
  9665.                         }
  9666.                         else{
  9667.                                 setreturn();
  9668.                                 if(insertmode)return;
  9669.                         }
  9670.                 }
  9671.         }
  9672.         if(numblocks==1)setreturn();    //06.09.04 22:20
  9673.         if(!inlineflag)leaveproc();
  9674.         else{
  9675.                 AutoDestructor();
  9676.                 RestoreStack();
  9677.                 RestoreSaveReg();
  9678.                 RetProc();
  9679.         }
  9680.         retproc=TRUE;
  9681.         if(numblocks>1||(numblocks==1&&tok!=tk_closebrace))addESP=oaddESP;
  9682. }
  9683.  
  9684. int IsSaveReg()
  9685. {
  9686.         if(psavereg->all)return TRUE;
  9687.         for(int i=7;i>=0;i--){
  9688.                 if(psavereg->reg[i])return TRUE;
  9689.         }
  9690.         return FALSE;
  9691. }
  9692.  
  9693. void leaveproc()
  9694. {
  9695.         AutoDestructor();
  9696.         RestoreStack();
  9697.         RestoreSaveReg();
  9698.         if(ESPloc==FALSE||am32==FALSE){
  9699.                 if(localsize)Leave();
  9700.                 else if(paramsize)op(0x5D); /* POP BP */
  9701.                 else if(initBP)Leave();
  9702.         }
  9703.         else if(localsize){
  9704.                 if(short_ok(localsize,TRUE)){
  9705.                         outword(0xC483);
  9706.                         op(localsize);
  9707.                 }
  9708.                 else{
  9709.                         outword(0xC481);
  9710.                         outdword(localsize);
  9711.                 }
  9712.         }
  9713.         RetProc();
  9714. }
  9715.  
  9716. DLLLIST *FindDLL()
  9717. {
  9718. DLLLIST *newdll;
  9719.         if(listdll!=NULL){      //ñïèñîê DLL íå ïóñò
  9720.                 for(newdll=listdll;stricmp(newdll->name,(char *)string)!=0;newdll=newdll->next){
  9721.                         if(newdll->next==NULL){ //ïîñëåäíÿÿ â ñïèñêå
  9722.                                 newdll->next=(DLLLIST *)MALLOC(sizeof(DLLLIST));//ñîçäàòü íîâóþ
  9723.                                 newdll=newdll->next;
  9724.                                 newdll->next=NULL;
  9725.                                 newdll->num=0;
  9726.                                 newdll->list=NULL;
  9727.                                 strcpy(newdll->name,(char *)string);
  9728.                                 break;
  9729.                         }
  9730.                 }
  9731.         }
  9732.         else{
  9733.                 listdll=newdll=(DLLLIST *)MALLOC(sizeof(DLLLIST));
  9734.                 newdll->next=NULL;
  9735.                 newdll->num=0;
  9736.                 newdll->list=NULL;
  9737.                 strcpy(newdll->name,(char *)string);
  9738.         }
  9739.         return newdll;
  9740. }
  9741.  
  9742. void declareextern()
  9743. {
  9744. int next;
  9745.         nexttok();
  9746.         if(comfile==file_w32&&strcmp(itok.name,"WINAPI")==0){
  9747.                 nexttok();
  9748.                 if(tok!=tk_string)stringexpected();
  9749.                 DLLLIST *newdll;
  9750.                 newdll=FindDLL();
  9751.                 nextexpecting2(tk_openbrace);   //îòêðûòèå ñïèñêà ïðîöåäóð
  9752.                 APIPROC *listapi=newdll->list;
  9753.                 returntype=tk_declare;
  9754.                 do{
  9755.                         if(tok==tk_enum)doenum();
  9756.                         else if(tok==tk_struct)InitStruct();
  9757.                         else{
  9758.                                 next=TRUE;
  9759.                                 if(testInitVar(FALSE)!=FALSE)preerror("Error declare WINAPI");
  9760.                                 if(itok.rm==tokens)itok.rm=tk_dword;
  9761.                                 if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word);
  9762.                                 ITOK hitok=itok;
  9763.                                 int htok=tok;
  9764.                                 param[0]=0;
  9765.                                 hitok.sib=hitok.size=-1;
  9766.                                 if(tok2==tk_period){
  9767.                                         nexttok();
  9768.                                         if(tok2==tk_number){
  9769.                                                 nexttok();
  9770.                                                 hitok.sib=itok.number;
  9771.                                         }
  9772.                                 }
  9773.                                 if(tok2==tk_at){
  9774.                                         nexttok();
  9775.                                         if(tok2==tk_number){
  9776.                                                 nexttok();
  9777.                                                 hitok.size=itok.number;
  9778.                                         }
  9779.                                 }
  9780.                                 else{
  9781.                                         nextexpecting2(tk_openbracket);
  9782.                                         if((hitok.flag&f_typeproc)==tp_fastcall)declareparamreg();
  9783.                                         else declareparamstack();
  9784.                                 }
  9785.                                 if(htok==tk_id||htok==tk_ID){
  9786.                                         tok=tk_apiproc;
  9787.                                         itok=hitok;
  9788.                                         itok.number=secondcallnum++;
  9789.                                         itok.segm=NOT_DYNAMIC;
  9790.                                         itok.post=dEBX|dEDI|dESI;       //05.09.04 01:36
  9791.                                         strcpy((char *)string,param);
  9792.                                         itok.type=tp_ucnovn;
  9793.                                         if(newdll->num==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC));   //ïåðâàÿ â ñïèñêå
  9794.                                         else listapi=(APIPROC *)REALLOC(listapi,sizeof(APIPROC)*(newdll->num+1));
  9795.                                         (listapi+newdll->num)->recapi=addtotree(itok.name);
  9796.                                         if(tok2==tk_openbracket){
  9797.                                                 next=0;
  9798.                                                 nexttok();
  9799.                                                 IsUses((listapi+newdll->num)->recapi);
  9800.                                         }
  9801.                                         newdll->num++;
  9802.                                 }
  9803.                                 else warningdefined(hitok.name);
  9804.                                 if(next)nexttok();
  9805.                                 seminext();
  9806.                         }
  9807.                 }while(tok!=tk_closebrace);
  9808.                 returntype=tokens;
  9809.                 newdll->list=listapi;
  9810.                 nexttok();
  9811.         }
  9812.         else{
  9813.                 itok.flag=f_extern;
  9814.                 // { Added by Coldy
  9815.                 // extern is dynamical variable
  9816.                 // This also suppress warning if variable is unused
  9817.                 dynamic_flag = TRUE;
  9818.                 // }
  9819.                 switch(tok){
  9820.                         case tk_far:
  9821.                         case tk_cdecl:
  9822.                         case tk_pascal:
  9823.                         case tk_stdcall:
  9824.                         case tk_fastcall:
  9825.                         case tk_declare:
  9826.                         case tk_undefproc:
  9827.                         case tk_ID:
  9828.                         case tk_id:
  9829.                         case tk_float:
  9830.                         case tk_long:
  9831.                         case tk_dword:
  9832.                         case tk_word:
  9833.                         case tk_byte:
  9834.                         case tk_char:
  9835.                         case tk_int:
  9836.                         case tk_void:
  9837.                                 int j;
  9838.                                 if((j=testInitVar())==FALSE)define_procedure();
  9839.                                 else if(j==TRUE)globalvar();
  9840.                                 break;
  9841.                         case tk_struct: InitStruct(); break;
  9842.                         default: preerror("Error declare extern");
  9843.                 }
  9844.                 if((!fobj)&&(!sobj))preerror("extern using only for compilation obj files");
  9845.         }
  9846. }
  9847.  
  9848. int testInitVar(int checkaldef)
  9849. {
  9850. unsigned int ffar=0;
  9851. unsigned int fexport=0;
  9852. unsigned int tproc=0;
  9853. unsigned int fretproc=0;
  9854. int rettype=tokens;
  9855. unsigned int flag=itok.flag;
  9856. unsigned int npointr=0;
  9857.         if(fstatic){
  9858.                 flag|=f_static;
  9859.                 fstatic=FALSE;
  9860.         }
  9861.         if(tok==tk_inline){
  9862.                 flag=f_inline;
  9863.                 nexttok();
  9864.         }
  9865.         for(;;){
  9866.                 if(tok==tk_far)ffar=f_far;
  9867.                 else if(tok==tk_export)fexport=f_export;
  9868.                 else if(tok>=tk_pascal&&tok<=tk_fastcall)tproc=tok;
  9869.                 else if((tok>=tk_void&&tok<=tk_double)||tok==tk_fpust){
  9870.                         if(rettype!=tokens)unknowntype();
  9871.                         rettype=tok;
  9872.                 }
  9873.                 else if(tok==tk_id){
  9874.                         if(CheckDef())continue;
  9875.                         if(tok2==tk_dblcolon)goto classdecl;
  9876.                         if(tproc==0)tproc=(comfile==file_w32?tp_stdcall:tp_pascal);     //òèï ïðîö ïî óìîë÷àíèþ
  9877.                         else tproc=(tproc-tk_pascal)*2;
  9878.                         break;
  9879.                 }
  9880.                 else if(tok==tk_ID){
  9881.                         if(CheckDef())continue;
  9882.                         if(tok2==tk_dblcolon){
  9883. classdecl:
  9884.                                 itok.flag=(unsigned int)(flag|ffar|fexport|fretproc|f_classproc);
  9885.                                 itok.rm=rettype;
  9886.                                 itok.npointr=(unsigned short)npointr;
  9887.                                 doclassproc(tproc);
  9888.                                 return 2;
  9889.                         }
  9890.                         if(tproc==0)tproc=tp_fastcall;  //òèï ïðîö ïî óìîë÷àíèþ
  9891.                         else tproc=(tproc-tk_pascal)*2;
  9892.                         break;
  9893.                 }
  9894.                 else if(tok==tk_undefproc||tok==tk_declare/*||tok==tk_apiproc*/){
  9895.  
  9896.                         flag|=itok.flag;        //new 18.04.07 12:19
  9897.  
  9898.                         if(tproc==0){
  9899.                                 if(CidOrID()==tk_ID)tproc=tp_fastcall;
  9900.                                 else tproc=(comfile==file_w32?tp_stdcall:tp_pascal);
  9901.                         }
  9902.                         else tproc=(tproc-tk_pascal)*2; //   17.09.05 17:06
  9903.                         if((flag&f_extern)!=0||tproc!=(itok.flag&f_typeproc)||
  9904.                                 ffar!=(itok.flag&f_far)||(unsigned short)npointr!=itok.npointr||
  9905.                                 ((flag&f_static)&&(itok.flag&f_static)==0)){
  9906.                                 if(strcmp(itok.name,"main")){
  9907.                                         if(rettype==itok.rm||(rettype==tokens&&(itok.rm==(am32==0?tk_word:tk_dword))))break;
  9908. //                                      printf("rm=%d rmnew=%d\n",itok.rm,rettype);
  9909.                                         if(checkaldef)redeclare(itok.name);
  9910.                                 }
  9911.                         }
  9912.                         break;
  9913.                 }
  9914.                 else if(tok==tk_proc||tok==tk_apiproc){
  9915.                         if(checkaldef)idalreadydefined();
  9916.                         break;
  9917.                 }
  9918.                 else if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_structvar||tok==tk_pointer){
  9919.                         idalreadydefined();
  9920.                         return 2;
  9921.                 }
  9922.                 else if(tok==tk_mult){
  9923.                         do{
  9924.                                 npointr++;
  9925.                                 nexttok();
  9926.                         }while(tok==tk_mult);
  9927.                         if(rettype==tokens)rettype=am32==FALSE?tk_word:tk_dword;
  9928.                         continue;
  9929.                 }
  9930.                 else if(tok==tk_openbracket){
  9931.                         if(tok2!=tk_mult){
  9932.                                 unuseableinput();
  9933.                                 return 2;
  9934.                         }
  9935.                         if(tproc!=0)tproc=(tproc-tk_pascal)*2;
  9936.                         itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc);
  9937.                         itok.rm=rettype;
  9938.                         itok.npointr=(unsigned short)npointr;
  9939.                         return TRUE;
  9940.                 }
  9941.                 else if((tok>=tk_overflowflag&&tok<=tk_notzeroflag)||tok==tk_minusflag||
  9942.                                 tok==tk_plusflag)fretproc=(tok-tk_overflowflag+1)*256;
  9943.                 else if(tok==tk_static)flag|=f_static;
  9944.                 else if(tok==tk_fpust)rettype=tk_fpust;
  9945.                 else{
  9946.                         unuseableinput();
  9947.                         return 2;
  9948.                 }
  9949.                 nexttok();
  9950.         }
  9951.         itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc);
  9952.         itok.rm=rettype;
  9953.         itok.npointr=(unsigned short)npointr;
  9954.         if(returntype==tk_declare&&
  9955.                         (tok2==tk_openbracket||tok2==tk_at||tok2==tk_period))return FALSE;
  9956.         if(tok2==tk_openbracket)return CheckDeclareProc();
  9957.         if(rettype==tokens){
  9958.                 thisundefined(itok.name);//02.09.04 20:55 was unuseableinput();
  9959.                 return 2;
  9960.         }
  9961.         return TRUE;
  9962. /*-----------------23.12.01 02:11-------------------
  9963.  rerurn:
  9964.  FALSE - åñëè îïðåäåëåíèå, âñòàâêà ïðîöåäóðû
  9965.  TRUE  - ïåðåìåííàÿ èëè îáúÿâëåíèå ïðîöåäóðû
  9966.  2 - îøèáêà èëè îáðàáîòàíî - íèêàêèõ äåéñòâèé íå ïðåäïðèíèìàòü.
  9967.         --------------------------------------------------*/
  9968. }
  9969.  
  9970. int CidOrID()
  9971. {
  9972. unsigned char cha;
  9973. unsigned char *string4=(unsigned char *)itok.name;
  9974.         for(;;){
  9975.                 cha=*string4;
  9976.                 if(cha>='a'&&cha<='z')return tk_id;
  9977.                 if(cha==0)break;
  9978.                 string4++;
  9979.         }
  9980.         return tk_ID;
  9981. }
  9982.  
  9983. void unpackteg(structteg *tteg)
  9984. {
  9985. int i;
  9986. elementteg *bazael;
  9987. structteg *newteg;
  9988. int ssize=0,count;
  9989. idrec *newrec,*ptr;
  9990.         if(alignword){  //âûðîâíÿòü íà ÷åòíûé àäðåñ
  9991.                 if(am32==0){
  9992.                         if(postsize%2==1)postsize++;
  9993.                 }
  9994.                 else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4);
  9995.         }
  9996.         bazael=tteg->baza;
  9997.         string[0]=0;
  9998.         for(i=0;i<tteg->numoper;i++){
  9999. //              printf("tok=%d %s\n",(bazael+i)->tok,(bazael+i)->name);
  10000.                 switch((bazael+i)->tok){
  10001.                         case tk_floatvar:
  10002.                         case tk_longvar:
  10003.                         case tk_dwordvar:
  10004.                         case tk_wordvar:
  10005.                         case tk_bytevar:
  10006.                         case tk_charvar:
  10007.                         case tk_intvar:
  10008.                         case tk_doublevar:
  10009.                         case tk_qwordvar:
  10010.                                 ssize=GetVarSize((bazael+i)->tok);      //ðàçìåð ïåðåìåííîé
  10011.                                 itok.type=tp_ucnovn;
  10012.                                 tok=(bazael+i)->tok;
  10013.                                 count=FindOff((unsigned char *)(bazael+i)->name,VARPOST);
  10014.                                 itok.post=1;
  10015.                                 itok.segm=DS;
  10016.                                 itok.number=postsize;
  10017.                                 itok.flag=tteg->flag;
  10018.                                 itok.size=(bazael+i)->numel*ssize;
  10019.                                 itok.rm=(am32==FALSE?rm_d16:rm_d32);
  10020.                                 itok.npointr=0;
  10021.                                 newrec=addtotree((bazael+i)->name);
  10022.                                 newrec->count=count;
  10023.                                 break;
  10024.                         case tk_struct:
  10025.                         case tk_structvar:
  10026.                                 strcpy(itok.name,(bazael+i)->name);
  10027.                                 newteg=(structteg *)(bazael+i)->nteg;
  10028.                                 newrec=(struct idrec *)MALLOC(sizeof(struct idrec));
  10029.                                 ptr=((tteg->flag&f_static)==0?treestart:staticlist);    //íà÷àëî äåðåâà
  10030.                                 if(ptr==NULL)((tteg->flag&f_static)==0?treestart:staticlist)=newrec;//íà÷àëî äåðåâà
  10031.                                 else{   //ïîèñê ñòðîêè â äåðåâå
  10032.                                         while(((ssize=strcmp(ptr->recid,itok.name))<0&&ptr->left!=NULL)||(ssize>0&&ptr->right!=NULL)){
  10033.                                                 ptr=(ssize<0?ptr->left:ptr->right);
  10034.                                         }
  10035.                                         (ssize<0?ptr->left:ptr->right)=newrec;  //ñòðîêà ìåíüøå
  10036.                                 }
  10037.                                 newrec->recsib=0;
  10038.                                 strcpy(newrec->recid,itok.name);//ñêîïèð íàçâàíèå
  10039.                                 newrec->newid=(char *)newteg;
  10040.                                 newrec->left=NULL;
  10041.                                 newrec->right=NULL;
  10042.                                 newrec->rectok=tk_structvar;
  10043.                                 newrec->flag=tteg->flag|newteg->flag;
  10044.                                 newrec->line=linenumber;
  10045.                                 newrec->file=currentfileinfo;
  10046.                                 if(FixUp)newrec->flag|=f_reloc;
  10047.                                 newrec->recrm=(bazael+i)->numel;
  10048.                                 newrec->recsize=(bazael+i)->numel*newteg->size;
  10049.                                 newrec->recpost=1;
  10050.                                 count=FindOff((unsigned char *)newrec->recid,VARPOST);
  10051.                                 newrec->count=count;
  10052.                                 break;
  10053.                         default:
  10054.                                 declareanonim();
  10055.                                 break;
  10056.                 }
  10057.         }
  10058.         AddPostData(tteg->size);
  10059. }
  10060.  
  10061. void unpackteg2(structteg *tteg)
  10062. {
  10063. int i;
  10064. elementteg *bazael;
  10065. structteg *newteg;
  10066. //idrec *newrec,*trec;
  10067. localrec *lrec;
  10068.         bazael=tteg->baza;
  10069.         string[0]=0;
  10070.         for(i=0;i<tteg->numoper;i++){
  10071.                 switch((bazael+i)->tok){
  10072.                         case tk_floatvar:
  10073.                         case tk_longvar:
  10074.                         case tk_dwordvar:
  10075.                         case tk_wordvar:
  10076.                         case tk_bytevar:
  10077.                         case tk_charvar:
  10078.                         case tk_intvar:
  10079.                         case tk_doublevar:
  10080.                         case tk_qwordvar:
  10081.                                 lrec=addlocalvar((bazael+i)->name,(bazael+i)->tok,localsize);
  10082.                                 lrec->rec.recsize=(bazael+i)->numel*GetVarSize((bazael+i)->tok);
  10083.                                 lrec->rec.type=tp_localvar;
  10084.                                 lrec->rec.npointr=0;
  10085.                                 lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4));
  10086.                                 break;
  10087.                         case tk_struct:
  10088.                         case tk_structvar:
  10089.                                 newteg=(structteg *)(bazael+i)->nteg;
  10090.                                 lrec=addlocalvar((bazael+i)->name,tk_structvar,localsize);
  10091.                                 lrec->rec.newid=(char *)tteg;
  10092.                                 lrec->rec.flag=tteg->flag;
  10093.                                 lrec->rec.type=tp_localvar;
  10094.                                 lrec->rec.recrm=(bazael+i)->numel;
  10095.                                 lrec->rec.recsize=(bazael+i)->numel*newteg->size;
  10096.                                 lrec->rec.recpost=LOCAL;
  10097.                                 lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4));
  10098.                                 break;
  10099.                         default:
  10100.                                 declareanonim();
  10101.                                 break;
  10102.                 }
  10103.         }
  10104.         localsize+=tteg->size;
  10105.         localsize=Align(localsize,(am32==FALSE?2:4));
  10106. }
  10107.  
  10108. unsigned long dounion(int Global,int flag)
  10109. {
  10110. structteg *tteg;
  10111. int noname=FALSE;
  10112.         nexttok();
  10113.         if(tok==tk_openbrace)noname=TRUE;
  10114.         else if((tok!=tk_id&&tok!=tk_ID)||FindTeg(Global)||(Global==FALSE&&FindTeg(TRUE))){
  10115.                 idalreadydefined();
  10116.                 SkipBlock2();
  10117.                 return 0;
  10118.         }
  10119.         if((tteg=CreatTeg(Global,TRUE,noname))!=NULL){
  10120.                 if(tok==tk_semicolon){
  10121.                         if(noname==TRUE){
  10122.                                 if(Global)unpackteg(tteg);
  10123.                                 else unpackteg2(tteg);
  10124.                                 if(tteg->baza)free(tteg->baza);
  10125.                                 free(tteg);
  10126.                         }
  10127.                         nexttok();
  10128.                 }
  10129.                 else{
  10130.                         if(Global)InitStruct2(flag,tteg);
  10131.                         else return LocalStruct2(flag,0,0,0,tteg);
  10132.                 }
  10133.         }
  10134.         else declareunion();
  10135.         return 0;
  10136. }
  10137.  
  10138. char *BackString(char *str)
  10139. {
  10140.         char *retbuf=(char *)MALLOC(strlen(str)+1);
  10141.         strcpy(retbuf,str);
  10142.         return retbuf;
  10143. }
  10144.  
  10145.  
  10146. void GetFileTime(int fd,struct ftime *buf)
  10147. {
  10148. /*
  10149. struct stat sb;
  10150. struct tm *tblock;
  10151.         fstat(fd,&sb);
  10152.         tblock=localtime(&sb.st_atime);
  10153.         buf->ft_tsec=tblock->tm_sec;
  10154.         buf->ft_min=tblock->tm_min;
  10155.         buf->ft_hour=tblock->tm_hour;
  10156.         buf->ft_day=tblock->tm_mday;
  10157.         buf->ft_month=tblock->tm_mon;
  10158.         buf->ft_year=tblock->tm_year-80;*/
  10159. }
  10160.  
  10161. void CheckPosts()
  10162. {
  10163.         if(posts==maxposts){
  10164.                 maxposts+=MAXPOSTS;
  10165.                 postbuf=(postinfo *)REALLOC(postbuf,maxposts*sizeof(postinfo));
  10166.         }
  10167. }
  10168.  
  10169. void CheckRealizable()
  10170. {
  10171.         switch(tok){
  10172.                 case tk_case:
  10173.                 case tk_CASE:
  10174.                 case tk_default:
  10175.                 case tk_closebrace:
  10176.                         return;
  10177.         }
  10178.         if(tok2==tk_colon)return;
  10179.         if(notunreach){
  10180.                 notunreach=FALSE;
  10181.                 return;
  10182.         }
  10183.         warningunreach();
  10184. //      preerror("Unreachable code");
  10185. }
  10186.  
  10187. void AddRegistr(int razr,int reg)
  10188. {
  10189.         if(razr==r8&&reg>3)reg-=4;
  10190.         if(razr==r64){
  10191.                 stat_reg[reg&255]=1;
  10192.                 stat_reg[reg/256]=1;
  10193.         }
  10194.         else stat_reg[reg]=1;
  10195. }
  10196.  
  10197. void ClearRegister()
  10198. {
  10199.         for(int i=0;i<8;i++)stat_reg[i]=0;
  10200. }
  10201.  
  10202. int GetRegister(int mode)
  10203. {
  10204. int reg=SI;
  10205.         if(am32!=FALSE||mode){
  10206.                 if(stat_reg[AX]==0)reg=AX;
  10207.                 else if(stat_reg[SI]==0)reg=SI;
  10208.                 else if(stat_reg[DI]==0)reg=DI;
  10209.                 else if(stat_reg[BX]==0)reg=BX;
  10210.                 else if(stat_reg[CX]==0)reg=CX;
  10211.                 else if(stat_reg[DX]==0)reg=DX;
  10212.         }
  10213.         else{
  10214.                 if(stat_reg[SI]==0)reg=SI;
  10215.                 else if(stat_reg[DI]==0)reg=DI;
  10216.                 else if(stat_reg[BX]==0)reg=BX;
  10217.         }
  10218.         return reg;
  10219. }
  10220.  
  10221. void RegAddNum(int reg)
  10222. {
  10223.         if((!structadr.post)&&optnumadd(structadr.number,reg,am32==FALSE?r16:r32,0)!=FALSE)return;
  10224.         if(reg==AX)op(5);
  10225.         else{
  10226.                 op(0x81);
  10227.                 op(0xC0+reg);
  10228.         }
  10229.         if(structadr.post)setwordpost(&structadr);
  10230.         if(am32)outdword(structadr.number);
  10231.         else outword(structadr.number);
  10232. }
  10233.  
  10234. void RestoreStack()
  10235. {
  10236.         if(addstack&&sizestack){
  10237.                 if(short_ok(sizestack,am32)){
  10238.                         outword(0xC483);
  10239.                         op(sizestack);
  10240.                 }
  10241.                 else{
  10242.                         outword(0xC481);
  10243.                         if(am32==FALSE)outword(sizestack);
  10244.                         else outdword(sizestack);
  10245.                 }
  10246. //              printf("%s(%d)> Restore %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,sizestack);
  10247.                 addESP-=sizestack;
  10248.                 sizestack=0;
  10249.         }
  10250. }
  10251.  
  10252. void startblock()
  10253. {
  10254. treelocalrec *nrec;
  10255.         numblocks++;
  10256. //      printf("start block %d\n",numblocks);
  10257.         nrec=(treelocalrec*)MALLOC(sizeof(treelocalrec));
  10258.         nrec->level=numblocks;
  10259.         nrec->lrec=NULL;
  10260.         nrec->addesp=addESP;
  10261.         nrec->next=tlr;
  10262.         tlr=nrec;
  10263. }
  10264.  
  10265. void endblock()
  10266. {
  10267. treelocalrec *orec;
  10268. //      printf("end block %d\n",numblocks);
  10269.         orec=tlr;
  10270.         tlr=tlr->next;
  10271.         if(tlr)numblocks=tlr->level;
  10272.         else numblocks=0;
  10273.         if(orec->lrec==NULL){
  10274.                 free(orec);
  10275.                 return;
  10276.         }
  10277.         orec->endline=linenumber;
  10278.         orec->next=btlr;
  10279.         btlr=orec;
  10280. //      if(addESP!=orec->addesp)???
  10281. }
  10282. /* end of TOKC.C */
  10283.