Subversion Repositories Kolibri OS

Rev

Rev 6618 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6446 GerdtR 1
#define _TOKC_
2
 
3
#include 	 /* 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)<
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<
408
//	printf("ofs=%Xh mask=%X value=%X\n",s,GetBitMask(ofs,size),(num<
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
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
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_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
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
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
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
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
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
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
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
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
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
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((toktk_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
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
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
5047
						opd(aligner);
5048
					}
5049
				}
5050
			}
5051
			break;
5052
		case tk_from:	//считать файл с данными
5053
			nexttok();
5054
			loop=dofrom();
5055
			if(elements!=0){
5056
				for(;loop
5057
			}
5058
			nexttok();
5059
			break;
5060
		case tk_extract:	//считать фрагмент файла с данными
5061
			nexttok();
5062
			loop=doextract();
5063
			if(elements!=0){
5064
				for(;loop
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
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
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&®!=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<
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
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
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
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;inumoper;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&¶msize>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(¶m[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(¶m[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(¶m[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(¶m[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(¶m[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(¶m[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
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
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<
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
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
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
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
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
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
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
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
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
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
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
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
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)&¶msize&&
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;inumoper;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;inumoper;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&®>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 */