Subversion Repositories Kolibri OS

Rev

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