Subversion Repositories Kolibri OS

Rev

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

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