Subversion Repositories Kolibri OS

Rev

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