Subversion Repositories Kolibri OS

Rev

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