Subversion Repositories Kolibri OS

Rev

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