Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6446 GerdtR 1
#define _TOKE_
2
 
3
#include 
4
#include 
5
#include "tok.h"
6
 
7
 
8
unsigned char gotoendif=FALSE;
9
 
10
unsigned char atex=FALSE;
11
 
12
unsigned char usedirectiv=TRUE;	//идет обработка директивы
13
 
14
unsigned char parsecommandline = 0; 	// parse command line flag
15
 
16
unsigned char sdp_mode=FALSE;	//режим принудительной выгрузки динамических процедур
17
 
18
unsigned int startexit;
19
 
20
extern int	maxerrors; 				// number of errors to stop at
21
 
22
unsigned int postnumflag;	//флаг последнего идентификатора в вычислении номера
23
 
24
int calcnumber=FALSE;
25
 
26
 
27
 
28
char mesmain[]="main";
29
 
30
char *macroname[]={"inp","inportb","inport","inportd","outp","outportb",
31
 
32
                   "outport","outportd","sqrt","cos","sin","atan2",
33
 
34
									 "tan","log","log10","exp","atan","fabs",NULL};
35
 
36
enum{m_ib,m_ibt,m_iw,m_id,m_ob,m_obt,m_ow,m_od,m_sqrt,m_cos,m_sin,m_atan2,
37
 
38
     m_tan,m_log,m_log10,m_exp,m_atan,m_fabs,m_end};
39
 
40
 
41
 
42
int FindProcLib(int);
43
 
44
int RetAtExit();
45
 
46
int ConvRetCode(int i);
47
 
48
int CompConst(int firstval);
49
 
50
int dirmode;
51
 
52
 
53
 
54
#define NUMIFDEF 32	//максимальная вложеность директив ifdef/ifndef
55
 
56
int	endifcount=-1; 		 // depth count of ?if
57
 
58
char ujo[]="Unknown #jumptomain option";
59
 
60
char toelse[]="#else use once in #if";
61
 
62
char ido[]="Unknown #inline option";
63
 
64
unsigned char startuptomain=FALSE;
65
 
66
unsigned char dosstring=FALSE;
67
 
68
unsigned char useelse[NUMIFDEF];	//флаги использования директивы else
69
 
70
unsigned char jumptomain = CALL_NEAR; // jump to the main()
71
 
72
unsigned char resizemem = 1;					// set owned memory block to 64K
73
 
74
unsigned char fargc=FALSE;
75
 
76
unsigned int	startptrdata = 0x100; 	// data start address
77
 
78
unsigned int resizesizeaddress;  /* location of resize memory size descr. */
79
 
80
unsigned int stackstartaddress;  /* location of SP assignment */
81
 
82
 
83
 
84
/*-----------------18.09.98 23:20-------------------
85
 
86
 Реализация SYS
87
 
88
--------------------------------------------------*/
89
 
90
char sysname[8]="NO_NAME";
91
 
92
int sysatr=0x2000;
93
 
94
int sysstack=0;
95
 
96
int sysnumcom=0;
97
 
98
int syscom;
99
 
100
//переменные для компиляции rom-bios
101
 
102
int unsigned romsize=0;
103
 
104
int dataromstart,dataromsize;
105
 
106
int dataseg=0x70;
107
 
108
 
109
 
110
unsigned int numdomain=0;	//число процедур запускаемых до main
111
 
112
char *domain;	//буфер имен процедур запускаемых до main
113
 
114
 
115
 
116
int ifdefconst();
117
 
118
void CheckNumIF();
119
 
120
void KillVarOfTree(idrec **treestart);
121
 
122
void IncludeFile(char *fileincl,int tfind);
123
 
124
 
125
 
126
char *pragmalist[]={"option","line","startup","resource","pack","debug","indexregs",""};
127
 
128
enum{p_op,p_li,p_st,p_re,p_pa,p_db,p_idx,p_end};
129
 
130
int strpackdef=1;
131
 
132
int strpackcur=1;
133
 
134
struct STACKALIGN {
135
 
136
	STACKALIGN *prev;
137
 
138
	int size;
139
 
140
	char id[IDLENGTH];
141
 
142
};
143
 
144
#ifdef DEBUGMODE
145
 
146
int debug=FALSE;
147
 
148
#endif
149
 
150
 
151
 
152
STACKALIGN *stackalign=NULL;
153
 
154
/* -------------- constant math procedures start --------------- */
155
 
156
 
157
 
158
int calcqwordnumber(unsigned long long *retnum,unsigned long long number,int operand)
159
 
160
{
161
 
162
unsigned long long value;
163
 
164
	value=*retnum;
165
 
166
	switch(operand){
167
 
168
		case tk_minus: value-=number; break;
169
 
170
		case tk_plus: value+=number; break;
171
 
172
		case tk_xor: value^=number; break;
173
 
174
		case tk_and: value&=number; break;
175
 
176
		case tk_or: value|=number; break;
177
 
178
		case tk_mod: value%=number; break;
179
 
180
		case tk_div: value/=number; break;
181
 
182
		case tk_mult: value*=number; break;
183
 
184
		case tk_rr: value>>=number; break;
185
 
186
		case tk_ll: value<<=number; break;
187
 
188
		case tk_xorminus: value^=-number; break;
189
 
190
		case tk_andminus: value&=-number; break;
191
 
192
		case tk_orminus: value|=-number; break;
193
 
194
		case tk_modminus: value%=-number; break;
195
 
196
		case tk_divminus: value/=-number; break;
197
 
198
		case tk_multminus: value*=-number; break;
199
 
200
		case tk_rrminus: value>>=-number; break;
201
 
202
		case tk_llminus: value<<=-number; break;
203
 
204
		default: return FALSE;
205
 
206
	}
207
 
208
	*retnum=value;
209
 
210
	return TRUE;
211
 
212
}
213
 
214
 
215
 
216
unsigned long long doconstqwordmath()
217
 
218
{
219
 
220
unsigned long long value;
221
 
222
unsigned int htok;
223
 
224
int fundef;	//флаг использования неизв адреса
225
 
226
	CheckMinusNum();
227
 
228
	if(tok!=tk_number){
229
 
230
		numexpected();
231
 
232
		return(0);
233
 
234
	}
235
 
236
	if(itok.rm==tk_float)value=*(float *)&itok.number;
237
 
238
	else if(itok.rm==tk_double)value=*(double *)&itok.lnumber;
239
 
240
	else value=itok.lnumber;
241
 
242
	fundef=itok.rm;
243
 
244
	postnumflag=itok.flag;
245
 
246
//	usedirectiv=TRUE;
247
 
248
	calcnumber=TRUE;
249
 
250
	while(itok2.type==tp_opperand){
251
 
252
		if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break;
253
 
254
		nexttok();
255
 
256
		htok=tok;
257
 
258
		if(tok2!=tk_number){
259
 
260
			if(tok2!=tk_dollar&&tok2!=tk_not){
261
 
262
				calcnumber=FALSE;
263
 
264
				return(value);
265
 
266
			}
267
 
268
			nexttok();
269
 
270
			if(tok!=tk_number){
271
 
272
				calcnumber=FALSE;
273
 
274
				return(value);
275
 
276
			}
277
 
278
		}
279
 
280
		else nexttok();
281
 
282
		if(itok.rm==tk_float)itok.number=*(float *)&itok.number;
283
 
284
		else if(itok.rm==tk_double)itok.lnumber=*(double *)&itok.lnumber;
285
 
286
		if(calcqwordnumber(&value,itok.lnumber,htok)==FALSE)beep();
287
 
288
		postnumflag^=itok.flag;
289
 
290
	}
291
 
292
	nexttok();
293
 
294
	calcnumber=FALSE;
295
 
296
	return(value);
297
 
298
}
299
 
300
 
301
 
302
int calcdwordnumber(unsigned long *retnum,unsigned long number,int operand)
303
 
304
{
305
 
306
unsigned long value;
307
 
308
	value=*retnum;
309
 
310
	switch(operand){
311
 
312
		case tk_minus: value-=number; break;
313
 
314
		case tk_plus: value+=number; break;
315
 
316
		case tk_xor: value^=number; break;
317
 
318
		case tk_and: value&=number; break;
319
 
320
		case tk_or: value|=number; break;
321
 
322
		case tk_mod: value%=number; break;
323
 
324
		case tk_div: value/=number; break;
325
 
326
		case tk_mult: value*=number; break;
327
 
328
		case tk_rr: value>>=number; break;
329
 
330
		case tk_ll: value<<=number; break;
331
 
332
		case tk_xorminus: value^=-number; break;
333
 
334
		case tk_andminus: value&=-number; break;
335
 
336
		case tk_orminus: value|=-number; break;
337
 
338
		case tk_modminus: value%=-number; break;
339
 
340
		case tk_divminus: value/=-number; break;
341
 
342
		case tk_multminus: value*=-number; break;
343
 
344
		case tk_rrminus: value>>=-number; break;
345
 
346
		case tk_llminus: value<<=-number; break;
347
 
348
		default: return FALSE;
349
 
350
	}
351
 
352
	*retnum=value;
353
 
354
	return TRUE;
355
 
356
}
357
 
358
 
359
 
360
unsigned long doconstdwordmath()
361
 
362
{
363
 
364
unsigned long value;
365
 
366
unsigned int htok;
367
 
368
int fundef;	//флаг использования неизв адреса
369
 
370
	CheckMinusNum();
371
 
372
	if(tok!=tk_number){
373
 
374
		numexpected();
375
 
376
		return(0);
377
 
378
	}
379
 
380
	if(itok.rm==tk_float)value=*(float *)&itok.number;
381
 
382
	else value=itok.number;
383
 
384
	fundef=itok.rm;
385
 
386
	postnumflag=itok.flag;
387
 
388
//	usedirectiv=TRUE;
389
 
390
	calcnumber=TRUE;
391
 
392
	while(itok2.type==tp_opperand){
393
 
394
		if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break;
395
 
396
		nexttok();
397
 
398
		htok=tok;
399
 
400
		if(tok2!=tk_number){
401
 
402
			if(tok2!=tk_dollar&&tok2!=tk_not){
403
 
404
				calcnumber=FALSE;
405
 
406
				return(value);
407
 
408
			}
409
 
410
			nexttok();
411
 
412
			if(tok!=tk_number){
413
 
414
				calcnumber=FALSE;
415
 
416
				return(value);
417
 
418
			}
419
 
420
		}
421
 
422
		else nexttok();
423
 
424
		if(itok.rm==tk_float)itok.number=*(float *)&itok.number;
425
 
426
		if(itok.rm==tk_double)itok.number=*(double *)&itok.lnumber;
427
 
428
		if(calcdwordnumber(&value,itok.number,htok)==FALSE)beep();
429
 
430
		postnumflag^=itok.flag;
431
 
432
	}
433
 
434
	nexttok();
435
 
436
	calcnumber=FALSE;
437
 
438
	return(value);
439
 
440
}
441
 
442
 
443
 
444
int calclongnumber(long *retnum,long number,int operand)
445
 
446
{
447
 
448
long value;
449
 
450
	value=*retnum;
451
 
452
	switch(operand){
453
 
454
		case tk_minus: value-=number; break;
455
 
456
		case tk_plus: value+=number; break;
457
 
458
		case tk_xor: value^=number; break;
459
 
460
		case tk_and: value&=number; break;
461
 
462
		case tk_or: value|=number; break;
463
 
464
		case tk_mod: value%=number; break;
465
 
466
		case tk_div: value/=number; break;
467
 
468
		case tk_mult: value*=number; break;
469
 
470
		case tk_rr: value>>=number; break;
471
 
472
		case tk_ll: value<<=number; break;
473
 
474
		case tk_xorminus: value^=-number; break;
475
 
476
		case tk_andminus: value&=-number; break;
477
 
478
		case tk_orminus: value|=-number; break;
479
 
480
		case tk_modminus: value%=-number; break;
481
 
482
		case tk_divminus: value/=-number; break;
483
 
484
		case tk_multminus: value*=-number; break;
485
 
486
		case tk_rrminus: value>>=-number; break;
487
 
488
		case tk_llminus: value<<=-number; break;
489
 
490
		default: return FALSE;
491
 
492
	}
493
 
494
	*retnum=value;
495
 
496
	return TRUE;
497
 
498
}
499
 
500
 
501
 
502
signed long doconstlongmath()
503
 
504
//вычислить выражение
505
 
506
{
507
 
508
long value;
509
 
510
unsigned int htok;
511
 
512
int fundef;	//флаг использования неизв адреса
513
 
514
	CheckMinusNum();
515
 
516
	if(tok!=tk_number){
517
 
518
		numexpected();
519
 
520
		return(0);
521
 
522
	}
523
 
524
	fundef=itok.rm;
525
 
526
	if(itok.rm==tk_float)value=*(float *)&itok.number;
527
 
528
	else value=itok.number;
529
 
530
//	value=itok.number;
531
 
532
	postnumflag=itok.flag;
533
 
534
//	usedirectiv=TRUE;
535
 
536
	calcnumber=TRUE;
537
 
538
	while(itok2.type==tp_opperand){	//пока операнд
539
 
540
		if(fundef==tk_undefofs&&tok2!=tk_plus&&tok2!=tk_minus)break;
541
 
542
		nexttok();
543
 
544
//		printf("tok=%d tok2=%d\n",tok,tok2);
545
 
546
		htok=tok;
547
 
548
		if(tok2!=tk_number){
549
 
550
			if(tok2!=tk_dollar&&tok2!=tk_not){
551
 
552
				calcnumber=FALSE;
553
 
554
				return(value);
555
 
556
			}
557
 
558
			nexttok();
559
 
560
			if(tok!=tk_number){
561
 
562
				calcnumber=FALSE;
563
 
564
				return(value);
565
 
566
			}
567
 
568
		}
569
 
570
		else nexttok();
571
 
572
		if(itok.rm==tk_float)itok.number=*(float *)&itok.number;
573
 
574
		if(itok.rm==tk_double)itok.number=*(double *)&itok.lnumber;
575
 
576
		if(calclongnumber(&value,itok.number,htok)==FALSE)beep();
577
 
578
		postnumflag^=itok.flag;
579
 
580
	}
581
 
582
	nexttok();
583
 
584
	calcnumber=FALSE;
585
 
586
	return(value);
587
 
588
}
589
 
590
 
591
 
592
int calcfloatnumber(float *retnum,float number,int operand)
593
 
594
{
595
 
596
float value;
597
 
598
	value=*retnum;
599
 
600
	switch(operand){
601
 
602
		case tk_minus: value-=number; break;
603
 
604
		case tk_plus: value+=number; break;
605
 
606
		case tk_div: value/=number; break;
607
 
608
		case tk_mult: value*=number; break;
609
 
610
		case tk_divminus: value/=-number; break;
611
 
612
		case tk_multminus: value*=-number; break;
613
 
614
		default: return FALSE;
615
 
616
	}
617
 
618
	*retnum=value;
619
 
620
	return TRUE;
621
 
622
}
623
 
624
 
625
 
626
long doconstfloatmath()
627
 
628
//вычислить выражение
629
 
630
{
631
 
632
float value;
633
 
634
	postnumflag=0;
635
 
636
	CheckMinusNum();
637
 
638
	if(tok!=tk_number){
639
 
640
		numexpected();
641
 
642
		return(0);
643
 
644
	}
645
 
646
	if(itok.rm==tk_double)*(float *)&itok.number=itok.dnumber;
647
 
648
	else if(itok.rm!=tk_float){
649
 
650
		float temp=itok.number;
651
 
652
		*(float *)&itok.number=temp;
653
 
654
	}
655
 
656
	value=itok.fnumber;
657
 
658
//	usedirectiv=TRUE;
659
 
660
	calcnumber=TRUE;
661
 
662
	while(itok2.type==tp_opperand){	//пока операнд
663
 
664
		nexttok();
665
 
666
		if(tok2!=tk_number){
667
 
668
			calcnumber=FALSE;
669
 
670
			return *(long *) &value;//нет никаких действий
671
 
672
		}
673
 
674
		if(itok2.rm==tk_double)*(float *)&itok2.number=itok2.dnumber;
675
 
676
		else if(itok2.rm!=tk_float)*(float *)&itok2.number=itok2.number;
677
 
678
		itok2.rm=tk_float;
679
 
680
		if(calcfloatnumber(&value,itok2.fnumber,tok)==FALSE)beep();
681
 
682
		nexttok();
683
 
684
	}
685
 
686
	nexttok();
687
 
688
	calcnumber=FALSE;
689
 
690
	return *(long *) &value;
691
 
692
}
693
 
694
 
695
 
696
int calcdoublenumber(double *retnum,double number,int operand)
697
 
698
{
699
 
700
double value;
701
 
702
	value=*retnum;
703
 
704
	switch(operand){
705
 
706
		case tk_minus: value-=number; break;
707
 
708
		case tk_plus: value+=number; break;
709
 
710
		case tk_div: value/=number; break;
711
 
712
		case tk_mult: value*=number; break;
713
 
714
		case tk_divminus: value/=-number; break;
715
 
716
		case tk_multminus: value*=-number; break;
717
 
718
		default: return FALSE;
719
 
720
	}
721
 
722
	*retnum=value;
723
 
724
	return TRUE;
725
 
726
}
727
 
728
 
729
 
730
long long doconstdoublemath()
731
 
732
//вычислить выражение
733
 
734
{
735
 
736
double value;
737
 
738
	postnumflag=0;
739
 
740
	CheckMinusNum();
741
 
742
	if(tok!=tk_number){
743
 
744
		numexpected();
745
 
746
		return(0);
747
 
748
	}
749
 
750
	if(itok.rm==tk_float){
751
 
752
		itok.dnumber=*(float *)&itok.number;
753
 
754
		itok.rm=tk_double;
755
 
756
	}
757
 
758
	else if(itok.rm!=tk_double){
759
 
760
		itok.dnumber=itok.lnumber;
761
 
762
	}
763
 
764
	value=itok.dnumber;
765
 
766
//	usedirectiv=TRUE;
767
 
768
	calcnumber=TRUE;
769
 
770
	while(itok2.type==tp_opperand){	//пока операнд
771
 
772
		nexttok();
773
 
774
		if(tok2!=tk_number){
775
 
776
			calcnumber=FALSE;
777
 
778
			return *(long long *) &value;//нет никаких действий
779
 
780
		}
781
 
782
		if(itok2.rm==tk_float)itok2.dnumber=*(float *)&itok2.number;
783
 
784
		else if(itok2.rm!=tk_double)itok2.dnumber=itok2.lnumber;;
785
 
786
		itok2.rm=tk_double;
787
 
788
		if(calcdoublenumber(&value,itok2.dnumber,tok)==FALSE)beep();
789
 
790
		nexttok();
791
 
792
	}
793
 
794
	nexttok();
795
 
796
	calcnumber=FALSE;
797
 
798
	return *(long long *) &value;
799
 
800
}
801
 
802
 
803
 
804
/* ================= simple syntax procedures start =================== */
805
 
806
 
807
 
808
void nextseminext()
809
 
810
{
811
 
812
	nexttok();
813
 
814
	seminext();
815
 
816
}
817
 
818
 
819
 
820
void seminext()
821
 
822
{
823
 
824
	if(tok!=tk_semicolon)expected(';');
825
 
826
	else nexttok();
827
 
828
}
829
 
830
 
831
 
832
void beep() 			 /* beep for any internal errors */
833
 
834
{
835
 
836
	printf("\a");
837
 
838
}
839
 
840
 
841
 
842
int expecting(int want)
843
 
844
/* compares current token with want token.	If different, issues error
845
 
846
	 message and returns 1, else advances to next token and returns 0 */
847
 
848
{
849
 
850
	if(want!=tok){
851
 
852
		SwTok(want);
853
 
854
		return(1);
855
 
856
	}
857
 
858
	nexttok();
859
 
860
	return(0);
861
 
862
}
863
 
864
 
865
 
866
void expectingoperand(int want)
867
 
868
/* compares current token with want token.	If different, issues error
869
 
870
	 message and returns 1, else advances to next token and returns 0 */
871
 
872
{
873
 
874
	if(want!=tok)SwTok(want);
875
 
876
	else getoperand();
877
 
878
}
879
 
880
 
881
 
882
void SwTok(int want)
883
 
884
{
885
 
886
	switch(want){
887
 
888
		case tk_closebracket: expected(')'); break;
889
 
890
		case tk_openbracket: expected('('); break;
891
 
892
		case tk_semicolon: expected(';'); break;
893
 
894
		case tk_colon: expected(':'); break;
895
 
896
		case tk_openblock: expected('['); break;
897
 
898
		case tk_closeblock: expected(']'); break;
899
 
900
		case tk_openbrace: expected('{'); break;
901
 
902
		case tk_closebrace: expected('}'); break;
903
 
904
		case tk_camma: expected(','); break;
905
 
906
		default: preerror("expecting a different token"); break;
907
 
908
	}
909
 
910
}
911
 
912
 
913
 
914
/*-----------------03.07.99 22:48-------------------
915
 
916
 Внутренние процедуры
917
 
918
	--------------------------------------------------*/
919
 
920
void  outprocedure(unsigned char *array,unsigned int length)
921
 
922
{
923
 
924
	if((outptr+length)>=outptrsize)CheckCodeSize();
925
 
926
	memcpy(output+outptr,array,length);
927
 
928
	outptr+=length;
929
 
930
	if(splitdata==0)outptrdata=outptr;
931
 
932
}
933
 
934
 
935
 
936
#define MMBANER 11
937
 
938
unsigned char aabaner[]={
939
 
940
	0x53,0x50,0x48,0x49,0x4E,0x58,0x43,0x2d,0x2d,ver1,ver2};	//надпись SPHINXC--ver
941
 
942
 
943
 
944
#define MMEXP 18
945
 
946
unsigned char aaEXP[]={
947
 
948
	0xD9,0xE8,		 //	fld1
949
 
950
	0xD9,0xEA,		 //fldl2e
951
 
952
	0xD8,0xCA,		 //fmul	 st, st(2)
953
 
954
	0xDD,0xD2,		 //fst	 st(2)
955
 
956
	0xD9,0xF8,		 //fprem
957
 
958
	0xD9,0xF0,		 //f2xm1
959
 
960
	0xDE,0xC1,		 //faddp	 st(1),	st
961
 
962
	0xD9,0xFD,		 //fscale
963
 
964
	0xDD,0xD9 };	 //fstp	 st(1)
965
 
966
 
967
 
968
void CallExitProcess()
969
 
970
//вызов процедуры ExitProcess
971
 
972
{
973
 
974
	tok=tk_id;
975
 
976
	searchvar("ExitProcess");
977
 
978
	if(FastCallApi==TRUE){
979
 
980
		outword(0x15FF);
981
 
982
		AddApiToPost(itok.number);
983
 
984
	}
985
 
986
	else{
987
 
988
		addacall((unsigned int)itok.number,(unsigned char)CALL_32);
989
 
990
		callloc0();		/* produce CALL [#] */
991
 
992
	}
993
 
994
}
995
 
996
 
997
 
998
int includeit(int type)
999
 
1000
{
1001
 
1002
int i=0;
1003
 
1004
	itok.post=1;
1005
 
1006
	if(strcmp("ABORT",itok.name)==0){
1007
 
1008
		RestoreStack();
1009
 
1010
		clearregstat();
1011
 
1012
#ifdef OPTVARCONST
1013
 
1014
		ClearLVIC();
1015
 
1016
#endif
1017
 
1018
		type=0;
1019
 
1020
		if(type==1&&dbg&2)AddCodeNullLine("ABORT()");
1021
 
1022
		if(comfile==file_w32)outword(0xC031);	//xor eax,eax
1023
 
1024
		if(atex==TRUE)i=RetAtExit();
1025
 
1026
		if(i==0){
1027
 
1028
			if(comfile==file_exe)outdword(0x21CD4CB4);
1029
 
1030
			else if(comfile==file_w32){
1031
 
1032
				if(jumptomain!=CALL_NONE)jumploc(startexit);
1033
 
1034
				else{
1035
 
1036
					op(0x50);
1037
 
1038
					CallExitProcess();
1039
 
1040
				}
1041
 
1042
			}
1043
 
1044
			else outword(0x20CD);
1045
 
1046
		}
1047
 
1048
		retproc=TRUE;
1049
 
1050
	}
1051
 
1052
	else if(strcmp("ATEXIT",itok.name)==0){
1053
 
1054
		if(type&&AlignProc)AlignCD(CS,alignproc);
1055
 
1056
		if(atex==FALSE)preerror("?atexit must be set for ATEXIT");
1057
 
1058
		if(type==1&&dbg&2)AddCodeNullLine("ATEXIT()");
1059
 
1060
		searchvar("__atexitproc");
1061
 
1062
		itok2=itok;
1063
 
1064
		searchvar("__numatexit");
1065
 
1066
		if(am32){
1067
 
1068
			op(0x51);	//push ecx
1069
 
1070
			outword(0x0D8B);	//mov ecx,numatex
1071
 
1072
			if(itok.post)setwordpost(&itok);
1073
 
1074
			outdword(itok.number);
1075
 
1076
			outdword(0x7310F983);
1077
 
1078
			outdword(0x8D04890F);  //cmp ecx,10 jnb bp mov [numatexit+4+ECX*4]=EAX
1079
 
1080
			if(itok2.post)setwordpost(&itok2);
1081
 
1082
			outdword(itok2.number);
1083
 
1084
			outword(0x05FF);	//inc numatexit
1085
 
1086
			if(itok.post)setwordpost(&itok);
1087
 
1088
			outdword(itok.number);
1089
 
1090
			outword(0xC031);	//xor eax,eax
1091
 
1092
			//bp:
1093
 
1094
			op(0x59);	//pop ECX
1095
 
1096
		}
1097
 
1098
		else{
1099
 
1100
			outword(0x368B);
1101
 
1102
			if(itok.post)setwordpost(&itok);
1103
 
1104
			outword(itok.number);
1105
 
1106
			op(0x83);
1107
 
1108
			outdword(0x0C7310FE);	//cmp si,10  jnb
1109
 
1110
			outdword(0x8489F601);	//si+=si
1111
 
1112
			if(itok2.post)setwordpost(&itok2);
1113
 
1114
			outword(itok2.number);
1115
 
1116
			outword(0x06FF);
1117
 
1118
			if(itok.post)setwordpost(&itok);
1119
 
1120
			outword(itok.number);
1121
 
1122
			outword(0xC031);
1123
 
1124
		}
1125
 
1126
	}
1127
 
1128
	else if(strcmp("EXIT",itok.name)==0){
1129
 
1130
		RestoreStack();
1131
 
1132
		clearregstat();
1133
 
1134
#ifdef OPTVARCONST
1135
 
1136
		ClearLVIC();
1137
 
1138
#endif
1139
 
1140
		type=0;
1141
 
1142
		if(dbg&2)AddCodeNullLine("EXIT()");
1143
 
1144
		if(atex==TRUE)i=RetAtExit();
1145
 
1146
		if(i==0){
1147
 
1148
			if(comfile==file_w32){
1149
 
1150
				if(jumptomain!=CALL_NONE)jumploc(startexit);
1151
 
1152
				else{
1153
 
1154
					op(0x50);
1155
 
1156
					CallExitProcess();
1157
 
1158
				}
1159
 
1160
			}
1161
 
1162
			else if(comfile==file_meos){
1163
 
1164
				outdword(0xCDFFC883);
1165
 
1166
				op(0x40);
1167
 
1168
			}
1169
 
1170
			else outdword(0x21CD4CB4);
1171
 
1172
		}
1173
 
1174
		retproc=TRUE;
1175
 
1176
	}
1177
 
1178
	else return ConvRetCode(FindProcLib(type));
1179
 
1180
	if(type==1)ret();	/* if it is a REG Proc not a MACRO */
1181
 
1182
	return (am32==FALSE?tk_word:tk_dword);
1183
 
1184
}
1185
 
1186
 
1187
 
1188
int ConvRetCode(int i)
1189
 
1190
{
1191
 
1192
	switch(i){
1193
 
1194
		case 0: return tk_void;
1195
 
1196
		case 1: return tk_char;
1197
 
1198
		case 2: return tk_byte;
1199
 
1200
		case 3: return tk_int;
1201
 
1202
		case 4: return tk_word;
1203
 
1204
		case 5: return tk_long;
1205
 
1206
		case 6: return tk_dword;
1207
 
1208
		case 7: return tk_float;
1209
 
1210
		default: return -1;
1211
 
1212
	}
1213
 
1214
}
1215
 
1216
 
1217
 
1218
int RetAtExit()
1219
 
1220
{
1221
 
1222
	if(comfile==file_exe||fobj!=FALSE||comfile==file_w32||comfile==file_meos){
1223
 
1224
		jumploc(startexit);
1225
 
1226
		return 1;
1227
 
1228
	}
1229
 
1230
	else callloc(startexit);
1231
 
1232
	return 0;
1233
 
1234
}
1235
 
1236
 
1237
 
1238
int includeproc()
1239
 
1240
{
1241
 
1242
	return ConvRetCode(FindProcLib(1));
1243
 
1244
}
1245
 
1246
 
1247
 
1248
/*-----------------18.01.99 22:42-------------------
1249
 
1250
 Макропроцедуры
1251
 
1252
 --------------------------------------------------*/
1253
 
1254
int CheckMacros()
1255
 
1256
{
1257
 
1258
int m,app=0,s32=0;
1259
 
1260
unsigned int num;
1261
 
1262
char *ofsstr=NULL;
1263
 
1264
int razr;
1265
 
1266
	for(m=0;m
1267
 
1268
	if(m==m_end)return tokens;
1269
 
1270
	nexttok();
1271
 
1272
	ofsstr=GetLecsem(tk_closebracket,tk_camma);
1273
 
1274
	nexttok();
1275
 
1276
	if(m
1277
 
1278
		switch(m){
1279
 
1280
			case m_id:
1281
 
1282
				s32++;
1283
 
1284
			case m_iw:
1285
 
1286
				app++;
1287
 
1288
			case m_ib:
1289
 
1290
			case m_ibt:
1291
 
1292
				if(tok!=tk_closebracket){
1293
 
1294
					if(tok==tk_number){
1295
 
1296
						num=doconstlongmath();
1297
 
1298
						if(num<256){
1299
 
1300
							if(s32!=0)op66(r32);
1301
 
1302
							else if(app==1)op66(r16);
1303
 
1304
							op(0xe4+app);
1305
 
1306
							op(num);
1307
 
1308
							break;
1309
 
1310
						}
1311
 
1312
						if(optimizespeed){
1313
 
1314
							op(0xB8+DX);	// MOV reg,#
1315
 
1316
							if(am32)outdword(num);
1317
 
1318
							else outword(num);
1319
 
1320
						}
1321
 
1322
						else{
1323
 
1324
							op66(r16);
1325
 
1326
							op(0xB8+DX);	// MOV reg,#
1327
 
1328
							outword(num);
1329
 
1330
						}
1331
 
1332
					}
1333
 
1334
					else getintoreg(EDX,r16,0,&ofsstr);
1335
 
1336
					if(ofsstr){
1337
 
1338
						IDZToReg(ofsstr,DX,r16);
1339
 
1340
						free(ofsstr);
1341
 
1342
						ofsstr=NULL;
1343
 
1344
					}
1345
 
1346
				}
1347
 
1348
				if(s32!=0)op66(r32);
1349
 
1350
				else if(app==1)op66(r16);
1351
 
1352
				op(0xEC+app);
1353
 
1354
				ClearReg(AL);
1355
 
1356
				break;
1357
 
1358
			case m_od:
1359
 
1360
				s32++;
1361
 
1362
			case m_ow:
1363
 
1364
				app++;
1365
 
1366
			case m_ob:
1367
 
1368
			case m_obt:
1369
 
1370
				if(tok!=tk_closebracket){
1371
 
1372
					if(s32!=0){
1373
 
1374
						do_e_axmath(0,r32,&ofsstr);
1375
 
1376
						razr=r32;
1377
 
1378
					}
1379
 
1380
					else if(app!=0){
1381
 
1382
						do_e_axmath(0,r16,&ofsstr);
1383
 
1384
						razr=r16;
1385
 
1386
					}
1387
 
1388
					else{
1389
 
1390
						doalmath(0,&ofsstr);
1391
 
1392
						razr=r8;
1393
 
1394
					}
1395
 
1396
					if(ofsstr){
1397
 
1398
						IDZToReg(ofsstr,AX,razr);
1399
 
1400
						free(ofsstr);
1401
 
1402
						ofsstr=NULL;
1403
 
1404
					}
1405
 
1406
					if(tok==tk_camma){
1407
 
1408
						ofsstr=GetLecsem(tk_camma,tk_closebracket);
1409
 
1410
						nexttok();
1411
 
1412
						if(tok==tk_number){
1413
 
1414
							num=doconstlongmath();
1415
 
1416
							if(num<256){
1417
 
1418
								if(s32!=0)op66(r32);
1419
 
1420
								else if(app==1)op66(r16);
1421
 
1422
								op(0xe6+app);
1423
 
1424
								op(num);
1425
 
1426
								goto enout;
1427
 
1428
							}
1429
 
1430
							if(optimizespeed){
1431
 
1432
								op(0xB8+DX);	// MOV reg,#
1433
 
1434
								if(am32)outdword(num);
1435
 
1436
								else outword(num);
1437
 
1438
							}
1439
 
1440
							else{
1441
 
1442
								op66(r16);
1443
 
1444
								op(0xB8+DX);	// MOV reg,#
1445
 
1446
								outword(num);
1447
 
1448
							}
1449
 
1450
						}
1451
 
1452
						else getintoreg(EDX,r16,0,&ofsstr);
1453
 
1454
						if(ofsstr){
1455
 
1456
							IDZToReg(ofsstr,DX,r16);
1457
 
1458
							free(ofsstr);
1459
 
1460
							ofsstr=NULL;
1461
 
1462
						}
1463
 
1464
					}
1465
 
1466
				}
1467
 
1468
				if(s32!=0)op66(r32);
1469
 
1470
				else if(app==1)op66(r16);
1471
 
1472
				op(0xEE + app);
1473
 
1474
enout:
1475
 
1476
				if(ofsstr)free(ofsstr);
1477
 
1478
				return tk_void;
1479
 
1480
		}
1481
 
1482
		if(ofsstr)free(ofsstr);
1483
 
1484
	}
1485
 
1486
	else{
1487
 
1488
		if(ofsstr)free(ofsstr);
1489
 
1490
		if(tok==tk_closebracket){
1491
 
1492
			missingpar(macroname[m]);
1493
 
1494
			return(tokens);
1495
 
1496
		}
1497
 
1498
		doeaxfloatmath(tk_fpust);
1499
 
1500
		switch(m){
1501
 
1502
			case m_sqrt:
1503
 
1504
				outword(0xFAD9);	//FSQRT
1505
 
1506
				return tk_fpust;	//результат в стеке fpu
1507
 
1508
			case m_cos:
1509
 
1510
				outword(0xFFD9);
1511
 
1512
				return tk_fpust;	//результат в стеке fpu
1513
 
1514
			case m_sin:
1515
 
1516
				outword(0xFED9);
1517
 
1518
				return tk_fpust;	//результат в стеке fpu
1519
 
1520
			case m_atan2:
1521
 
1522
				if(expecting(tk_camma)){
1523
 
1524
					missingpar(macroname[m]);
1525
 
1526
					return tokens;
1527
 
1528
				}
1529
 
1530
				doeaxfloatmath(tk_fpust);
1531
 
1532
				outword(0xF3D9);	//FPATAN
1533
 
1534
				return tk_fpust;	//результат в стеке fpu
1535
 
1536
			case m_tan:
1537
 
1538
				outdword(0xD8DDF2D9);	//FPTAN fstp st
1539
 
1540
				return tk_fpust;	//результат в стеке fpu
1541
 
1542
			case m_log:
1543
 
1544
				outword(0xEDD9);	//fldln2
1545
 
1546
				outdword(0xF1D9C9D9);	//fxch st1  fyl2x
1547
 
1548
				return tk_fpust;	//результат в стеке fpu
1549
 
1550
			case m_log10:
1551
 
1552
				outword(0xECD9);	//fldlg2
1553
 
1554
				outdword(0xF1D9C9D9);	//fxch st1  fyl2x
1555
 
1556
				return tk_fpust;	//результат в стеке fpu
1557
 
1558
			case m_exp:
1559
 
1560
				outprocedure(aaEXP,MMEXP);
1561
 
1562
				return tk_fpust;	//результат в стеке fpu
1563
 
1564
			case m_atan:
1565
 
1566
				outdword(0xF3D9E8D9);	//FLD1 FPATAN
1567
 
1568
				return tk_fpust;	//результат в стеке fpu
1569
 
1570
			case m_fabs:
1571
 
1572
				outword(0xE1D9);	//FABS
1573
 
1574
				return tk_fpust;	//результат в стеке fpu
1575
 
1576
		}
1577
 
1578
	}
1579
 
1580
	if(s32!=0)return tk_dword;
1581
 
1582
	if(app!=0)return  tk_word;
1583
 
1584
	return tk_byte;
1585
 
1586
}
1587
 
1588
 
1589
 
1590
/*-----------------06.02.99 16:09-------------------
1591
 
1592
 Работа с внешней библиотекой
1593
 
1594
	--------------------------------------------------*/
1595
 
1596
typedef struct _IPROC_
1597
 
1598
{
1599
 
1600
	unsigned short size;
1601
 
1602
	unsigned short ofs;
1603
 
1604
	unsigned char cpu;
1605
 
1606
}IPROC;
1607
 
1608
 
1609
 
1610
struct _HLIB_
1611
 
1612
{
1613
 
1614
	char name[33];
1615
 
1616
	unsigned char rettype;
1617
 
1618
	unsigned short size;
1619
 
1620
	unsigned char dosr[2];
1621
 
1622
	IPROC info[4];
1623
 
1624
}hlib;
1625
 
1626
 
1627
 
1628
int FindProcLib(int type)
1629
 
1630
{
1631
 
1632
static int lhandl=-1;
1633
 
1634
long ofs=0;
1635
 
1636
char m1[80];
1637
 
1638
int index;
1639
 
1640
	if(am32)return -1;
1641
 
1642
	if(lhandl==-1){
1643
 
1644
		sprintf(m1,"%s%s",findpath[0],"mainlib.ldp");
1645
 
1646
		if((lhandl=open(m1,O_RDONLY|O_BINARY))==-1)return -1;
1647
 
1648
	}
1649
 
1650
	lseek(lhandl,0,SEEK_SET);
1651
 
1652
		if(chip<3){
1653
 
1654
		if(optimizespeed==0)index=0;
1655
 
1656
		else index=1;
1657
 
1658
	}
1659
 
1660
	else{
1661
 
1662
		if(optimizespeed==0)index=2;
1663
 
1664
		else index=3;
1665
 
1666
	}
1667
 
1668
	for(;;){
1669
 
1670
		if(read(lhandl,&hlib,sizeof(_HLIB_))!=sizeof(_HLIB_))break;
1671
 
1672
		if(strcmp((char *)itok.name,hlib.name)==0){
1673
 
1674
int size;
1675
 
1676
			if((outptr+hlib.size)>=outptrsize)CheckCodeSize();
1677
 
1678
			lseek(lhandl,ofs+sizeof(_HLIB_)+hlib.info[index].ofs,SEEK_SET);
1679
 
1680
			size=hlib.info[index].size;
1681
 
1682
			if(type!=1)size--;
1683
 
1684
			else if(dbg&2){
1685
 
1686
				sprintf(m1,"%s()",itok.name);
1687
 
1688
				AddCodeNullLine(m1);
1689
 
1690
			}
1691
 
1692
			if(read(lhandl,output+outptr,size)!=size)break;
1693
 
1694
			outptr+=size;
1695
 
1696
			if(splitdata==0)outptrdata=outptr;
1697
 
1698
			if(cpu
1699
 
1700
			if(hlib.dosr[1]!=0){
1701
 
1702
				if(hlib.dosr[1]>dos1){
1703
 
1704
					dos1=hlib.dosr[1];
1705
 
1706
					dos2=hlib.dosr[0];
1707
 
1708
				}
1709
 
1710
				else if(hlib.dosr[1]==dos1&&hlib.dosr[0]>dos2)dos2=hlib.dosr[0];
1711
 
1712
			}
1713
 
1714
			clearregstat();
1715
 
1716
#ifdef OPTVARCONST
1717
 
1718
			ClearLVIC();
1719
 
1720
#endif
1721
 
1722
			return hlib.rettype;
1723
 
1724
		}
1725
 
1726
		ofs+=sizeof(_HLIB_)+hlib.size;
1727
 
1728
		lseek(lhandl,ofs,SEEK_SET);
1729
 
1730
	}
1731
 
1732
	return -1;
1733
 
1734
}
1735
 
1736
 
1737
 
1738
void addconsttotree(char *keystring,long long constvalue,int type)
1739
 
1740
//вставить константу в дерево
1741
 
1742
{
1743
 
1744
struct idrec *ptr,*newptr;
1745
 
1746
int cmpresult;
1747
 
1748
	newptr=(struct idrec *)MALLOC(sizeof(struct idrec));//новый блок константы
1749
 
1750
	ptr=definestart;
1751
 
1752
	if(ptr==NULL)definestart=newptr;
1753
 
1754
	else{
1755
 
1756
		while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)||(cmpresult>0&&ptr->right!=NULL)){
1757
 
1758
			if(cmpresult<0)ptr=ptr->left;
1759
 
1760
			else if(cmpresult>0)ptr=ptr->right;
1761
 
1762
		}
1763
 
1764
		if(cmpresult<0)ptr->left=newptr;
1765
 
1766
		else if(cmpresult>0)ptr->right=newptr;
1767
 
1768
		else{
1769
 
1770
			free(newptr);
1771
 
1772
			if(ptr->newid){
1773
 
1774
				free(ptr->newid);
1775
 
1776
				ptr->newid=NULL;
1777
 
1778
			}
1779
 
1780
			if(ptr->sbuf){
1781
 
1782
				free(ptr->sbuf);
1783
 
1784
				ptr->sbuf=NULL;
1785
 
1786
			}
1787
 
1788
			ptr->recnumber=constvalue;
1789
 
1790
			ptr->recrm=type;
1791
 
1792
			ptr->rectok=tk_number;
1793
 
1794
			ptr->recsegm=DS;
1795
 
1796
			ptr->recpost=0;
1797
 
1798
			ptr->flag=0;
1799
 
1800
			ptr->recsize=0;
1801
 
1802
			return;
1803
 
1804
		}
1805
 
1806
	}
1807
 
1808
	strcpy(newptr->recid,keystring);
1809
 
1810
	newptr->newid=NULL;
1811
 
1812
	newptr->rectok=tk_number;
1813
 
1814
	newptr->reclnumber=constvalue;
1815
 
1816
	newptr->recsegm=DS;
1817
 
1818
	newptr->recrm=type;
1819
 
1820
	newptr->recpost=0;
1821
 
1822
	newptr->flag=0;
1823
 
1824
	newptr->recsize=0;
1825
 
1826
	newptr->left=NULL;
1827
 
1828
	newptr->right=NULL;
1829
 
1830
//	newptr->count=1;
1831
 
1832
}
1833
 
1834
 
1835
 
1836
void addtodefine(char *keystring)//добавить строку в дерево define
1837
 
1838
{
1839
 
1840
struct idrec *ptr,*newptr,*left=NULL,*right=NULL;
1841
 
1842
int cmpresult;
1843
 
1844
//выделить память под новую проц
1845
 
1846
	newptr=(struct idrec *)MALLOC(sizeof(struct idrec));
1847
 
1848
	ptr=definestart;	//начало дерева
1849
 
1850
	if(ptr==NULL)definestart=newptr;
1851
 
1852
	else{	//поиск строки в дереве
1853
 
1854
		while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)||
1855
 
1856
		       (cmpresult>0&&ptr->right!=NULL)){
1857
 
1858
			if(cmpresult<0)ptr=ptr->left;
1859
 
1860
			else if(cmpresult>0)ptr=ptr->right;
1861
 
1862
		}
1863
 
1864
		if(cmpresult<0)ptr->left=newptr;	//строка меньше
1865
 
1866
		else if(cmpresult>0)ptr->right=newptr;
1867
 
1868
		else{
1869
 
1870
			free(newptr);
1871
 
1872
			newptr=ptr;
1873
 
1874
			left=ptr->left;
1875
 
1876
			right=ptr->right;
1877
 
1878
			if(newptr->newid)free(newptr->newid);
1879
 
1880
			if(newptr->sbuf)free(newptr->sbuf);
1881
 
1882
		}
1883
 
1884
	}
1885
 
1886
	strcpy(newptr->recid,keystring);//скопир название
1887
 
1888
	newptr->newid=NULL;
1889
 
1890
	if(tok==tk_string){
1891
 
1892
		newptr->newid=(char *)MALLOC(itok.number);
1893
 
1894
		memcpy(newptr->newid,string,itok.number);
1895
 
1896
		if(itok.rm==1)newptr->sbuf=BackString((char *)string3);
1897
 
1898
	}
1899
 
1900
	else{
1901
 
1902
		if(string[0]!=0)newptr->newid=BackString((char *)string);
1903
 
1904
		newptr->sbuf=NULL;
1905
 
1906
	}
1907
 
1908
	newptr->rectok=tok;
1909
 
1910
	newptr->recnumber=itok.number;
1911
 
1912
	newptr->recsegm=itok.segm;
1913
 
1914
	newptr->recrm=itok.rm;
1915
 
1916
	newptr->recpost=itok.post;
1917
 
1918
	newptr->flag=itok.flag;
1919
 
1920
	newptr->recsize=itok.size;
1921
 
1922
	newptr->left=left;
1923
 
1924
	newptr->right=right;
1925
 
1926
	newptr->recsib=itok.sib;
1927
 
1928
	newptr->line=linenumber;
1929
 
1930
	newptr->file=currentfileinfo;
1931
 
1932
	newptr->count=0;
1933
 
1934
	newptr->type=itok.type;
1935
 
1936
	newptr->npointr=itok.npointr;
1937
 
1938
	itok.rec=newptr;
1939
 
1940
}
1941
 
1942
 
1943
 
1944
unsigned char get_directive_value()  //return the 0 or 1 value for directive
1945
 
1946
{
1947
 
1948
	nexttok();
1949
 
1950
	if(tok==tk_number){
1951
 
1952
		if(doconstlongmath())return(1);//если значение не нулевое вернуть 1
1953
 
1954
		return(0);
1955
 
1956
	}
1957
 
1958
	numexpected();
1959
 
1960
	nexttok();
1961
 
1962
	return(0);
1963
 
1964
}
1965
 
1966
 
1967
 
1968
int GetStringAsIt()
1969
 
1970
{
1971
 
1972
int tstr;
1973
 
1974
	if(tok2==tk_string){
1975
 
1976
		nexttok();
1977
 
1978
		tstr=1;
1979
 
1980
	}
1981
 
1982
	else{
1983
 
1984
		inptr=inptr2;
1985
 
1986
		cha=cha2;
1987
 
1988
		whitespace();
1989
 
1990
		if(cha=='<'){
1991
 
1992
			tstr=0;
1993
 
1994
			for(int i=0;i
1995
 
1996
				nextchar();
1997
 
1998
				if(cha=='>'){
1999
 
2000
					string3[i]=0;
2001
 
2002
					break;
2003
 
2004
				}
2005
 
2006
				if(cha==13||cha==26)goto errstr;
2007
 
2008
				string3[i]=cha;
2009
 
2010
			}
2011
 
2012
			nextchar();
2013
 
2014
		}
2015
 
2016
		else{
2017
 
2018
errstr:
2019
 
2020
			stringexpected();
2021
 
2022
			tstr=-1;
2023
 
2024
		}
2025
 
2026
		inptr2=inptr;
2027
 
2028
		linenum2=linenumber;
2029
 
2030
		cha2=cha;
2031
 
2032
	}
2033
 
2034
	return tstr;
2035
 
2036
}
2037
 
2038
 
2039
 
2040
void InitDefineConst()
2041
 
2042
{
2043
 
2044
	addconsttotree("TRUE",TRUE);
2045
 
2046
	addconsttotree("FALSE",FALSE);
2047
 
2048
	addconsttotree("__SECOND__",timeptr.tm_sec);
2049
 
2050
	addconsttotree("__MINUTE__",timeptr.tm_min);
2051
 
2052
	addconsttotree("__HOUR__",timeptr.tm_hour);
2053
 
2054
	addconsttotree("__DAY__",timeptr.tm_mday);
2055
 
2056
	addconsttotree("__MONTH__",timeptr.tm_mon);
2057
 
2058
	addconsttotree("__YEAR__",timeptr.tm_year+1900);
2059
 
2060
	addconsttotree("__WEEKDAY__",timeptr.tm_wday);
2061
 
2062
	addconsttotree("__VER1__",ver1);
2063
 
2064
	addconsttotree("__VER2__",ver2);
2065
 
2066
	tok=tk_string;
2067
 
2068
	itok.flag=zero_term;
2069
 
2070
	itok.rm=0;
2071
 
2072
	strcpy((char *)string,(char *)compilerstr);
2073
 
2074
	itok.number=strlen((char *)string);
2075
 
2076
	addtodefine("__COMPILER__");
2077
 
2078
	strcpy((char *)string,asctime(&timeptr));
2079
 
2080
	itok.number=strlen((char *)string)-1;
2081
 
2082
	string[itok.number]=0;
2083
 
2084
	addtodefine("__DATESTR__");
2085
 
2086
	DateToStr((char *)string);
2087
 
2088
	itok.number=11;
2089
 
2090
	addtodefine("__DATE__");
2091
 
2092
	sprintf((char *)string,"%02d:%02d:%02d",timeptr.tm_hour,timeptr.tm_min,timeptr.tm_sec);
2093
 
2094
	itok.number=8;
2095
 
2096
	addtodefine("__TIME__");
2097
 
2098
	strcpy((char *)string,"struct");
2099
 
2100
	tok=tk_struct;
2101
 
2102
	itok.number=6;
2103
 
2104
	addtodefine("class");
2105
 
2106
}
2107
 
2108
 
2109
 
2110
char *AddTextToBuf(char *buf,int *size,int start,int add)
2111
 
2112
{
2113
 
2114
int addsize;
2115
 
2116
	addsize=(add==0?itok.number-1:inptr)-start;
2117
 
2118
	*size+=addsize;
2119
 
2120
	if(!buf){
2121
 
2122
		buf=(char *)MALLOC(*size+1+add);
2123
 
2124
		buf[0]=0;
2125
 
2126
	}
2127
 
2128
	else buf=(char *)REALLOC(buf,*size+1+add);
2129
 
2130
//	printf("size=%d %s\n",*size+1+add,(char *)(input+start));
2131
 
2132
	strncat(buf,(char *)(input+start),addsize);
2133
 
2134
	buf[*size]=0;
2135
 
2136
	return buf;
2137
 
2138
}
2139
 
2140
 
2141
 
2142
void AddMacro(char *name,int numpar,char *paramstr)
2143
 
2144
{
2145
 
2146
int start,size;
2147
 
2148
char *bstring=NULL;
2149
 
2150
idrec *ptr;
2151
 
2152
	start=inptr-1;
2153
 
2154
	size=0;
2155
 
2156
	do{
2157
 
2158
		FastTok(2);
2159
 
2160
		if(tok==tk_comment1){
2161
 
2162
			inptr=itok.number;
2163
 
2164
			cha=input[itok.number-1];
2165
 
2166
			break;
2167
 
2168
		}
2169
 
2170
		if(tok==tk_comment2){
2171
 
2172
			bstring=AddTextToBuf(bstring,&size,start,0);
2173
 
2174
			start=inptr-1;
2175
 
2176
		}
2177
 
2178
	}while(tok!=tk_endline&&tok!=tk_eof);
2179
 
2180
	bstring=AddTextToBuf(bstring,&size,start,1);
2181
 
2182
	strbtrim(bstring);
2183
 
2184
	size=strlen(bstring);
2185
 
2186
	bstring[size]=0x20;
2187
 
2188
	bstring[size+1]=0;
2189
 
2190
	inptr2=inptr;
2191
 
2192
	cha2=cha;
2193
 
2194
	linenum2=linenumber;
2195
 
2196
	tok=tk_macro;
2197
 
2198
	itok.size=numpar;
2199
 
2200
	string[0]=0;
2201
 
2202
/*	int i;
2203
 
2204
	for(i=0,size=0;i
2205
 
2206
		puts(paramstr+size);
2207
 
2208
		size+=strlen(paramstr+size)+1;
2209
 
2210
	}*/
2211
 
2212
 
2213
 
2214
//	printf("tok=%d %s %s\n",tok,name,bstring);
2215
 
2216
	addtodefine(name);
2217
 
2218
	ptr=itok.rec;
2219
 
2220
	ptr->newid=paramstr;
2221
 
2222
	ptr->sbuf=bstring;
2223
 
2224
	ptr->line=linenumber-1;
2225
 
2226
}
2227
 
2228
 
2229
 
2230
void GetMacro(char *name)
2231
 
2232
{
2233
 
2234
int size,nsize,numpar=0;
2235
 
2236
char *paramstr;
2237
 
2238
	inptr=inptr2;
2239
 
2240
	cha=cha2;
2241
 
2242
	FastTok(0);
2243
 
2244
	FastTok(1);
2245
 
2246
	size=0;
2247
 
2248
	while(tok!=tk_closebracket&&tok!=tk_eof){
2249
 
2250
		if(tok!=tk_id)varexpected(numpar+1);
2251
 
2252
		nsize=strlen(itok.name)+1;
2253
 
2254
		if(size==0)paramstr=(char *)MALLOC(nsize);
2255
 
2256
		else paramstr=(char *)REALLOC(paramstr,size+nsize);
2257
 
2258
		strcpy(paramstr+size,itok.name);
2259
 
2260
		size+=nsize;
2261
 
2262
		numpar++;
2263
 
2264
		FastTok(0);
2265
 
2266
		if(tok!=tk_closebracket){
2267
 
2268
			if(tok!=tk_camma)expected(',');
2269
 
2270
			FastTok(1);
2271
 
2272
		}
2273
 
2274
	}
2275
 
2276
	if(tok==tk_eof)unexpectedeof();
2277
 
2278
	AddMacro(name,numpar,paramstr);
2279
 
2280
}
2281
 
2282
 
2283
 
2284
int pushpop(int i)
2285
 
2286
{
2287
 
2288
STACKALIGN *newpar;
2289
 
2290
	switch(i){
2291
 
2292
		case 1:
2293
 
2294
			newpar=(STACKALIGN *)MALLOC(sizeof(STACKALIGN));
2295
 
2296
			newpar->prev=stackalign;
2297
 
2298
			newpar->size=strpackcur;
2299
 
2300
			newpar->id[0]=0;
2301
 
2302
			stackalign=newpar;
2303
 
2304
			return TRUE;
2305
 
2306
		case 2:
2307
 
2308
			newpar=stackalign->prev;
2309
 
2310
			free(stackalign);
2311
 
2312
			stackalign=newpar;
2313
 
2314
 
2315
 
2316
			strpackcur=(stackalign!=NULL?stackalign->size:strpackdef);
2317
 
2318
			return TRUE;
2319
 
2320
	}
2321
 
2322
	return FALSE;
2323
 
2324
}
2325
 
2326
 
2327
 
2328
void doifdef(int intok)
2329
 
2330
{
2331
 
2332
int defcond;
2333
 
2334
int curcond;
2335
 
2336
int bracket;
2337
 
2338
int notflag;
2339
 
2340
int next;
2341
 
2342
int locrez,endrez,lastoper;
2343
 
2344
int stopscan;
2345
 
2346
unsigned int i;
2347
 
2348
int oscanlexmode;
2349
 
2350
	dirmode=dm_if;
2351
 
2352
/*	string3[0]=cha2;
2353
 
2354
	int j=1;
2355
 
2356
	for(i=inptr2;input[i]>13;i++,j++)string3[j]=input[i];
2357
 
2358
	string3[j]=0;
2359
 
2360
	printf("%s (%u) %s %s",(startfileinfo+currentfileinfo)->filename,linenumber,itok.name,string3);
2361
 
2362
	*/
2363
 
2364
	defcond=intok;
2365
 
2366
	if(intok==d_if||intok==d_elif)defcond=d_ifdef;
2367
 
2368
	curcond=defcond;
2369
 
2370
	oscanlexmode=scanlexmode;
2371
 
2372
	bracket=0;
2373
 
2374
	lastoper=tk_oror;
2375
 
2376
	endrez=0;
2377
 
2378
	stopscan=FALSE;
2379
 
2380
	do{
2381
 
2382
		scanlexmode=DEFLEX;
2383
 
2384
		nexttok();
2385
 
2386
		notflag=FALSE;
2387
 
2388
		next=TRUE;
2389
 
2390
		while(tok==tk_openbracket){
2391
 
2392
			nexttok();
2393
 
2394
			bracket++;
2395
 
2396
		}
2397
 
2398
		if(tok==tk_not){
2399
 
2400
			notflag=TRUE;
2401
 
2402
			nexttok();
2403
 
2404
		}
2405
 
2406
		if(tok==tk_id&&strcmp("defined",itok.name)==0){
2407
 
2408
			nexttok();
2409
 
2410
			curcond=(notflag==FALSE?d_ifdef:d_ifndef);
2411
 
2412
		}
2413
 
2414
		while(tok==tk_openbracket){
2415
 
2416
			nexttok();
2417
 
2418
			bracket++;
2419
 
2420
		}
2421
 
2422
//			printf("tok=%d type2=%d\n",tok,itok2.type);
2423
 
2424
		if(tok==tk_number){
2425
 
2426
			locrez=1;
2427
 
2428
			if(itok2.type==tp_opperand){
2429
 
2430
				i=doconstdwordmath();
2431
 
2432
				next=0;
2433
 
2434
				if(itok.type==tp_compare)locrez=CompConst(i);
2435
 
2436
			}
2437
 
2438
			else if(itok2.type==tp_compare){
2439
 
2440
				i=itok.number;
2441
 
2442
				nexttok();
2443
 
2444
				locrez=CompConst(i);
2445
 
2446
			}
2447
 
2448
		}
2449
 
2450
		else if((locrez=ifdefconst())==2){
2451
 
2452
			if(tok==tk_id||tok==tk_ID){
2453
 
2454
				if(FindTeg(TRUE))locrez=1;
2455
 
2456
				else locrez=0;
2457
 
2458
			}
2459
 
2460
			else locrez=1;
2461
 
2462
		}
2463
 
2464
		if(curcond==d_ifndef)locrez^=1;
2465
 
2466
		if(stopscan==FALSE){
2467
 
2468
			if(lastoper==tk_oror)endrez|=locrez;
2469
 
2470
			else{
2471
 
2472
				endrez&=locrez;
2473
 
2474
				if(endrez==FALSE)stopscan=TRUE;
2475
 
2476
			}
2477
 
2478
		}
2479
 
2480
//			printf("lastoper=%d endrez=%d locrez=%d\n",lastoper,endrez,locrez);
2481
 
2482
		if(next)nexttok();
2483
 
2484
		while(tok==tk_closebracket){
2485
 
2486
			nexttok();
2487
 
2488
			bracket--;
2489
 
2490
		}
2491
 
2492
		if(tok==tk_endline||tok2==tk_endline){
2493
 
2494
			scanlexmode=oscanlexmode;
2495
 
2496
//			retoldscanmode(oscanlexmode);
2497
 
2498
			dirmode=dm_other;
2499
 
2500
			nexttok();
2501
 
2502
			break;
2503
 
2504
		}
2505
 
2506
		if(tok==tk_oror||tok==tk_andand)lastoper=tok;
2507
 
2508
		else{
2509
 
2510
			preerror("bad token in 'ifdef/ifndef/if'");
2511
 
2512
//			printf("tok=%d\n",tok);
2513
 
2514
		}
2515
 
2516
	}while(tok!=tk_eof&&tok!=tk_endline);
2517
 
2518
	dirmode=dm_other;
2519
 
2520
	scanlexmode=oscanlexmode;
2521
 
2522
//	retoldscanmode(oscanlexmode);
2523
 
2524
	if(bracket>0)preerror("missing ')'");
2525
 
2526
	else if(bracket<0)preerror("extra ')'");
2527
 
2528
	gotoendif=1^endrez;
2529
 
2530
	if(intok!=d_elif){
2531
 
2532
		endifcount++;
2533
 
2534
		CheckNumIF();
2535
 
2536
		useelse[endifcount]=1;
2537
 
2538
	}
2539
 
2540
//	printf(" %s endifcount=%d\n",endrez==0?"FALSE":"TRUE",endifcount);
2541
 
2542
}
2543
 
2544
 
2545
 
2546
void InitIdxRegs()
2547
 
2548
{
2549
 
2550
unsigned char lreg[8];
2551
 
2552
int i,j;
2553
 
2554
	for(i=0;i<8;i++)lreg[i]=0;
2555
 
2556
	nexttok();
2557
 
2558
//	printf("tok=%d %s\n",tok,itok.name);
2559
 
2560
	for(i=0;tok==tk_reg32||tok==tk_reg||tok==tk_beg;i++){
2561
 
2562
		if(i<4){
2563
 
2564
			if(tok==tk_beg&&itok.number>3)itok.number-=4;
2565
 
2566
			idxregs[i]=itok.number;
2567
 
2568
			if(lreg[itok.number])preerror("expected unique register for \"pragma indexregs\"");
2569
 
2570
			lreg[itok.number]=1;
2571
 
2572
		}
2573
 
2574
		nexttok();
2575
 
2576
		if(tok==tk_camma)nexttok();
2577
 
2578
	}
2579
 
2580
	lreg[ESP]=lreg[EBP]=1;
2581
 
2582
	for(;i<4;i++){
2583
 
2584
		if(lreg[idxregs[i]]==0)lreg[idxregs[i]]=1;
2585
 
2586
		else{
2587
 
2588
			for(j=7;j>=0;j--){
2589
 
2590
				if(lreg[j]==0){
2591
 
2592
					lreg[j]=1;
2593
 
2594
					idxregs[i]=j;
2595
 
2596
					break;
2597
 
2598
				}
2599
 
2600
			}
2601
 
2602
		}
2603
 
2604
	}
2605
 
2606
}
2607
 
2608
 
2609
 
2610
void directive()
2611
 
2612
{
2613
 
2614
unsigned char next=1;
2615
 
2616
char holdid[IDLENGTH];
2617
 
2618
long longhold,longhold2;
2619
 
2620
long long llhold;
2621
 
2622
unsigned int i;
2623
 
2624
int oscanlexmode;
2625
 
2626
	holdid[0]=DS;
2627
 
2628
	usedirectiv=TRUE;
2629
 
2630
	dirmode=dm_other;
2631
 
2632
	switch(itok.number){
2633
 
2634
		case d_alignc:
2635
 
2636
			holdid[0]=CS;
2637
 
2638
		case d_align: //использовать байт вставки если нечетный адрес
2639
 
2640
			if(notdoneprestuff==TRUE)doprestuff();	//начальный код
2641
 
2642
			i=2;
2643
 
2644
			nexttok();
2645
 
2646
			next=0;
2647
 
2648
			if(tok==tk_number){
2649
 
2650
				i=doconstlongmath();
2651
 
2652
				if(i<2)i=2;
2653
 
2654
			}
2655
 
2656
			i=AlignCD(holdid[0],i);
2657
 
2658
			if(holdid[0]==DS)alignersize+=i;
2659
 
2660
			break;
2661
 
2662
		case d_aligner://значение байта вставки
2663
 
2664
			nexttok();
2665
 
2666
			if(tok==tk_number){
2667
 
2668
				aligner=(unsigned char)doconstlongmath();//вычислить значение
2669
 
2670
				next=0;
2671
 
2672
			}
2673
 
2674
			else numexpected();
2675
 
2676
			break;
2677
 
2678
		case d_alignw://выравнивание адресов
2679
 
2680
			alignword=get_directive_value();
2681
 
2682
			next=0;
2683
 
2684
			break;
2685
 
2686
//		case d_beep: beep(); break;
2687
 
2688
		case d_code: optimizespeed=0; break;
2689
 
2690
		case d_ctrl:
2691
 
2692
			killctrlc=get_directive_value();
2693
 
2694
			next=0;
2695
 
2696
			break;
2697
 
2698
		case d_define:
2699
 
2700
			dirmode=dm_def0;
2701
 
2702
			oscanlexmode=scanlexmode;
2703
 
2704
			scanlexmode=DEFLEX2;
2705
 
2706
			nexttok();
2707
 
2708
			scanlexmode=DEFLEX;
2709
 
2710
			dirmode=dm_def;
2711
 
2712
			strcpy(holdid,itok.name);
2713
 
2714
//			printf("1 line=%d\n",linenumber);
2715
 
2716
//			printf("tok=%d %s\n",tok,itok.name);
2717
 
2718
			if(tok==tk_id||tok==tk_ID){
2719
 
2720
				if(cha2=='('){
2721
 
2722
					GetMacro(holdid);
2723
 
2724
				}
2725
 
2726
				else{
2727
 
2728
					longhold=inptr2;
2729
 
2730
					longhold2=cha2;
2731
 
2732
					nexttok();
2733
 
2734
//		printf("2 line=%d\n",linenumber);
2735
 
2736
					i=tk_dword;
2737
 
2738
					if((tok==tk_float||tok==tk_double||tok==tk_qword)&&(tok2==tk_minus||tok2==tk_number)){
2739
 
2740
						i=tok;
2741
 
2742
						nexttok();
2743
 
2744
					}
2745
 
2746
//			printf("tok=%d tok2=%d %s %s\n",tok,tok2,itok.name,string);
2747
 
2748
					if(tok!=tk_endline&&tok!=tk_minus&&tok!=tk_number&&tok2!=tk_endline&&tok2!=tk_semicolon){
2749
 
2750
						inptr=longhold;
2751
 
2752
						cha=longhold2;
2753
 
2754
						AddMacro(holdid,0,NULL);
2755
 
2756
					}
2757
 
2758
					else{
2759
 
2760
						switch(tok){
2761
 
2762
							case tk_structvar:
2763
 
2764
								struct idrec *ptrs,*ptrsnew;
2765
 
2766
								ptrs=itok.rec;
2767
 
2768
								addtodefine(holdid);
2769
 
2770
								ptrsnew=itok.rec;
2771
 
2772
								if(ptrsnew->newid)free(ptrsnew->newid);
2773
 
2774
								ptrsnew->newid=ptrs->newid;
2775
 
2776
								break;
2777
 
2778
							case tk_eof: unexpectedeof(); break;
2779
 
2780
							case tk_string:
2781
 
2782
//			printf("tok=%d tok2=%d %s %s\n",tok,tok2,itok.name,string);
2783
 
2784
								if(cha2==13&&itok.name[0]==0){
2785
 
2786
									cha2=input[inptr2];
2787
 
2788
									inptr2++;
2789
 
2790
								}
2791
 
2792
								goto endef;
2793
 
2794
							case tk_minus:
2795
 
2796
								if(tok2==tk_number){
2797
 
2798
									if(i==tk_dword&&(itok2.rm==tk_float||itok2.rm==tk_double||
2799
 
2800
											itok2.rm==tk_qword))i=itok2.rm;
2801
 
2802
							case tk_number:
2803
 
2804
									if(i==tk_dword&&(itok.rm==tk_float||itok.rm==tk_double||itok.rm==tk_qword))i=itok.rm;
2805
 
2806
									switch(i){
2807
 
2808
										case tk_float:
2809
 
2810
											llhold=doconstfloatmath();
2811
 
2812
											break;
2813
 
2814
										case tk_double:
2815
 
2816
											llhold=doconstdoublemath();
2817
 
2818
											break;
2819
 
2820
										case tk_qword:
2821
 
2822
											llhold=doconstqwordmath();
2823
 
2824
											break;
2825
 
2826
										default:
2827
 
2828
											llhold=doconstdwordmath();
2829
 
2830
											break;
2831
 
2832
									}
2833
 
2834
									itok.flag=(unsigned char)postnumflag;
2835
 
2836
									addconsttotree(holdid,llhold,i);
2837
 
2838
									next=0;
2839
 
2840
									break;
2841
 
2842
								}
2843
 
2844
							case tk_proc:
2845
 
2846
							case tk_apiproc:
2847
 
2848
							case tk_declare:
2849
 
2850
							case tk_undefproc:
2851
 
2852
								tok=tk_id;
2853
 
2854
								strcpy((char *)string,itok.name);
2855
 
2856
							default:
2857
 
2858
endef:
2859
 
2860
								if(itok.type!=tp_modif)itok.type=tp_ucnovn;
2861
 
2862
								addtodefine(holdid); break;
2863
 
2864
						}
2865
 
2866
					}
2867
 
2868
				}
2869
 
2870
			}
2871
 
2872
			else idalreadydefined();
2873
 
2874
//			retoldscanmode(oscanlexmode);
2875
 
2876
			scanlexmode=oscanlexmode;
2877
 
2878
			if(tok==tk_endline){
2879
 
2880
//				nextchar();
2881
 
2882
				nexttok();
2883
 
2884
				next=0;
2885
 
2886
			}
2887
 
2888
//			printf("3 line=%d cha=%02X\n",linenumber,cha2);
2889
 
2890
			break;
2891
 
2892
		case d_DOS:
2893
 
2894
			nexttok();
2895
 
2896
			if(tok==tk_number){
2897
 
2898
				longhold=doconstlongmath();
2899
 
2900
				longhold2=dos1*256+dos2;
2901
 
2902
				if(longhold>longhold2){
2903
 
2904
					dos1=(unsigned char)(longhold/256);
2905
 
2906
					dos2=(unsigned char)(longhold%256);
2907
 
2908
				}
2909
 
2910
				next=0;
2911
 
2912
			}
2913
 
2914
			else numexpected();
2915
 
2916
			break;
2917
 
2918
		case d_endif:
2919
 
2920
			if(endifcount==-1) preerror("?endif without preceeding ?if");
2921
 
2922
			else endifcount--;
2923
 
2924
//			printf("%s (%u) endif: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount);
2925
 
2926
			break;
2927
 
2928
		case d_ifdef:
2929
 
2930
		case d_if:
2931
 
2932
		case d_ifndef:
2933
 
2934
			doifdef(itok.number);
2935
 
2936
			if(gotoendif==0)useelse[endifcount]|=2;
2937
 
2938
			next=0;
2939
 
2940
			break;
2941
 
2942
		case d_incl:
2943
 
2944
			i=GetStringAsIt();
2945
 
2946
			usedirectiv=FALSE;
2947
 
2948
			if((int)i!=-1){
2949
 
2950
				char *a;
2951
 
2952
				if((a=strrchr((char *)string3,'.'))!=NULL){
2953
 
2954
					if(stricmp(a,".obj")==0){
2955
 
2956
						AddNameObj((char *)string3,i,0);
2957
 
2958
						break;
2959
 
2960
					}
2961
 
2962
					if(stricmp(a,".lib")==0){
2963
 
2964
						AddNameObj((char *)string3,i,1);
2965
 
2966
						break;
2967
 
2968
					}
2969
 
2970
				}
2971
 
2972
//				puts((char *)string3);
2973
 
2974
				IncludeFile((char *)string3,i);
2975
 
2976
			}
2977
 
2978
			break;
2979
 
2980
		case d_jump:
2981
 
2982
			nexttok();
2983
 
2984
			if(tok==tk_number){
2985
 
2986
				jumptomain=CALL_NEAR;
2987
 
2988
				if((unsigned int)itok.number==0){
2989
 
2990
					jumptomain=CALL_NONE;
2991
 
2992
					header=0;
2993
 
2994
				}
2995
 
2996
			}
2997
 
2998
			else if(stricmp(itok.name,"NONE")==0){
2999
 
3000
				jumptomain=CALL_NONE;
3001
 
3002
				header=0;
3003
 
3004
			}
3005
 
3006
			else if(stricmp(itok.name,"SHORT")==0)jumptomain=CALL_SHORT;
3007
 
3008
			else if(stricmp(itok.name,"NEAR")==0)jumptomain=CALL_NEAR;
3009
 
3010
			else preerror(ujo);
3011
 
3012
			break;
3013
 
3014
		case d_error:
3015
 
3016
			nexttok();
3017
 
3018
			if(tok==tk_number){
3019
 
3020
				maxerrors=doconstlongmath();
3021
 
3022
				next=0;
3023
 
3024
			}
3025
 
3026
			else numexpected();
3027
 
3028
			break;
3029
 
3030
		case d_command:
3031
 
3032
			parsecommandline=get_directive_value();
3033
 
3034
			next=0;
3035
 
3036
			break;
3037
 
3038
		case d_argc:
3039
 
3040
			parsecommandline=fargc=get_directive_value();
3041
 
3042
			next=0;
3043
 
3044
			break;
3045
 
3046
		case d_print:
3047
 
3048
			nexttok();
3049
 
3050
			i=0;
3051
 
3052
			if(strcmp(itok.name,"error")==0){
3053
 
3054
				i=1;
3055
 
3056
				nexttok();
3057
 
3058
			}
3059
 
3060
			switch(tok){
3061
 
3062
				case tk_string:
3063
 
3064
					printf("%s",string);
3065
 
3066
					break;
3067
 
3068
				case tk_number:
3069
 
3070
					printf("\n%u",itok.number);
3071
 
3072
					break;
3073
 
3074
				default: preerror("unsupported token for #print"); break;
3075
 
3076
			}
3077
 
3078
			if(i)exit(e_preprocess);
3079
 
3080
			break;
3081
 
3082
		case d_prnex:
3083
 
3084
			nexttok();
3085
 
3086
			if(tok==tk_number)printf("%X",itok.number);
3087
 
3088
			else numexpected();
3089
 
3090
			break;
3091
 
3092
		case d_random:
3093
 
3094
			if(notdoneprestuff==TRUE)doprestuff();
3095
 
3096
			op(rand());
3097
 
3098
			break;
3099
 
3100
		case d_resize:
3101
 
3102
			resizemem=get_directive_value();
3103
 
3104
			next=0;
3105
 
3106
			break;
3107
 
3108
		case d_resmes:
3109
 
3110
			nexttok();
3111
 
3112
			if(tok==tk_string){
3113
 
3114
				itok.flag=dos_term;
3115
 
3116
				addtotree("__RESIZEMESSAGE");
3117
 
3118
				addconsttotree("__resizemessage",TRUE);
3119
 
3120
			}
3121
 
3122
			else stringexpected();
3123
 
3124
			break;
3125
 
3126
		case d_speed: optimizespeed=1; break;
3127
 
3128
		case d_stack:
3129
 
3130
			nexttok();
3131
 
3132
			if(tok==tk_number){
3133
 
3134
				longhold=doconstlongmath();
3135
 
3136
				if(am32==FALSE&&(longhold>0xFEFF||longhold<0))preerror("invalid size for stack");
3137
 
3138
				else{
3139
 
3140
					if(comfile!=file_sys)stacksize=longhold;
3141
 
3142
					else sysstack=longhold;
3143
 
3144
				}
3145
 
3146
				next=0;
3147
 
3148
			}
3149
 
3150
			else numexpected();
3151
 
3152
			break;
3153
 
3154
		case d_start:
3155
 
3156
			nexttok();
3157
 
3158
			if(comfile==file_com){
3159
 
3160
				if(tok==tk_number){
3161
 
3162
					startptrdata=startptr=doconstlongmath();
3163
 
3164
					if(startStartup!=0x100)startStartup=startptr;
3165
 
3166
				}
3167
 
3168
				else{
3169
 
3170
					numexpected();
3171
 
3172
					nexttok();
3173
 
3174
				}
3175
 
3176
				next=0;
3177
 
3178
			}
3179
 
3180
			else OnlyComFile();
3181
 
3182
			break;
3183
 
3184
		case d_8086: case d_8088: chip=0; break;
3185
 
3186
		case d_80186: chip=1; break;
3187
 
3188
		case d_80286: chip=2; break;
3189
 
3190
		case d_80386: chip=3; break;
3191
 
3192
		case d_80486: chip=4; break;
3193
 
3194
		case d_80586: chip=5; break;
3195
 
3196
		case d_80686: chip=6; break;
3197
 
3198
		case d_80786: chip=7; break;
3199
 
3200
		case d_atr:
3201
 
3202
			nexttok();
3203
 
3204
			if(tok==tk_number){
3205
 
3206
				sysatr=doconstlongmath();
3207
 
3208
				next=0;
3209
 
3210
			}
3211
 
3212
			else numexpected();
3213
 
3214
			break;
3215
 
3216
		case d_name:
3217
 
3218
			nexttok();
3219
 
3220
			if(tok==tk_string){
3221
 
3222
				int i;
3223
 
3224
				for(i=0;i<8&&string[i]!=0;i++)sysname[i]=string[i];
3225
 
3226
				for(;i<8;i++)sysname[i]=' ';
3227
 
3228
			}
3229
 
3230
			else stringexpected();
3231
 
3232
			break;
3233
 
3234
		case d_com:	//список команд для SYS
3235
 
3236
			listcom=(LISTCOM *)MALLOC(sizeof(LISTCOM)*MAXSYSCOM);
3237
 
3238
			do{
3239
 
3240
				nexttok();
3241
 
3242
				if(tok==tk_id||tok==tk_ID){
3243
 
3244
					strncpy((listcom+sysnumcom)->name,(char *)string,32);
3245
 
3246
					(listcom+sysnumcom)->name[32]=0;
3247
 
3248
					sysnumcom++;
3249
 
3250
				}
3251
 
3252
				else{
3253
 
3254
					idalreadydefined();
3255
 
3256
					break;
3257
 
3258
				}
3259
 
3260
				nexttok();
3261
 
3262
				if(tok==tk_semicolon)break;
3263
 
3264
				if(tok!=tk_camma){
3265
 
3266
					expected(',');
3267
 
3268
					break;
3269
 
3270
				}
3271
 
3272
			}while(sysnumcom<=MAXSYSCOM);
3273
 
3274
			if(sysnumcom>MAXSYSCOM)preerror("to many commands");
3275
 
3276
			else if(sysnumcom!=0&&sysnumcom!=MAXSYSCOM)listcom=(LISTCOM *)REALLOC(listcom,sysnumcom*sizeof(LISTCOM));
3277
 
3278
			break;
3279
 
3280
		case d_sdp:	//выгрузить динамические процедуры
3281
 
3282
			next=notdoneprestuff;
3283
 
3284
			sdp_mode=TRUE;
3285
 
3286
			usedirectiv=FALSE;
3287
 
3288
			docalls();
3289
 
3290
			sdp_mode=FALSE;
3291
 
3292
			notdoneprestuff=next;
3293
 
3294
			next=1;
3295
 
3296
			break;
3297
 
3298
		case d_warning:
3299
 
3300
			warning=get_directive_value();
3301
 
3302
			next=0;
3303
 
3304
			break;
3305
 
3306
		case d_ip:
3307
 
3308
			if(	GetStringAsIt()!=-1)IncludePath((char *)string3);
3309
 
3310
			break;
3311
 
3312
		case d_us:	//использовать код STARTUP
3313
 
3314
			if(comfile==file_com)useStartup=TRUE;
3315
 
3316
			break;
3317
 
3318
		case d_suv:	//адрес начала использования под неинициализированные переменные
3319
 
3320
			nexttok();
3321
 
3322
			if(comfile==file_com){
3323
 
3324
				if(tok==tk_number)startStartup=doconstlongmath();
3325
 
3326
				else{
3327
 
3328
					numexpected();
3329
 
3330
					nexttok();
3331
 
3332
				}
3333
 
3334
				next=0;
3335
 
3336
			}
3337
 
3338
			else OnlyComFile();
3339
 
3340
			break;
3341
 
3342
		case d_iav:	//инициализировать все переменные
3343
 
3344
			notpost=get_directive_value();
3345
 
3346
			next=0;
3347
 
3348
			break;
3349
 
3350
		case d_atex:	//механизм ATEXIT
3351
 
3352
			atex=TRUE;
3353
 
3354
			break;
3355
 
3356
		case d_dseg:	//сегмент данных для rom-bios
3357
 
3358
			nexttok();
3359
 
3360
			if(tok==tk_number){
3361
 
3362
				dataseg=doconstlongmath();
3363
 
3364
				next=0;
3365
 
3366
			}
3367
 
3368
			else numexpected();
3369
 
3370
			break;
3371
 
3372
		case d_rsize:	//размер rom-bios
3373
 
3374
			nexttok();
3375
 
3376
			if(tok==tk_number){
3377
 
3378
				romsize=doconstlongmath();
3379
 
3380
				next=0;
3381
 
3382
			}
3383
 
3384
			else numexpected();
3385
 
3386
			break;
3387
 
3388
		case d_mdr:	//переносить данные а  опер память
3389
 
3390
			splitdata=modelmem=get_directive_value();
3391
 
3392
			next=0;
3393
 
3394
			break;
3395
 
3396
		case d_am32:	//32 битная адресация
3397
 
3398
			nexttok();
3399
 
3400
			if(tok!=tk_number)numexpected();
3401
 
3402
			else am32=(unsigned char)(itok.number==0?FALSE:TRUE);
3403
 
3404
			break;
3405
 
3406
		case d_undef:	//undef
3407
 
3408
			oscanlexmode=scanlexmode;
3409
 
3410
			scanlexmode=DEFLEX2;
3411
 
3412
			nexttok();
3413
 
3414
			scanlexmode=oscanlexmode;
3415
 
3416
//			retoldscanmode(oscanlexmode);
3417
 
3418
			if(tok==tk_string){
3419
 
3420
				strcpy(itok.name,(char *)string);
3421
 
3422
				KillVarOfTree(&treestart);
3423
 
3424
			}
3425
 
3426
			else KillVarOfTree(&definestart);
3427
 
3428
			break;
3429
 
3430
		case d_stm:	//startuptomain
3431
 
3432
			startuptomain=TRUE;
3433
 
3434
			break;
3435
 
3436
		case d_ib:	//imagebase
3437
 
3438
			nexttok();
3439
 
3440
			ImageBase=doconstlongmath();
3441
 
3442
			next=0;
3443
 
3444
			break;
3445
 
3446
		case d_fut:	//fixuptable
3447
 
3448
			FixUpTable=get_directive_value();
3449
 
3450
			next=0;
3451
 
3452
			break;
3453
 
3454
		case d_fca:	//fastcallapi
3455
 
3456
			FastCallApi=get_directive_value();
3457
 
3458
			next=0;
3459
 
3460
			break;
3461
 
3462
		case d_dstr:
3463
 
3464
			dosstring=get_directive_value();
3465
 
3466
			next=0;
3467
 
3468
			break;
3469
 
3470
		case d_cv:
3471
 
3472
			int v1,v2;
3473
 
3474
			v1=v2=0;
3475
 
3476
			cha=cha2;
3477
 
3478
			inptr=inptr2;
3479
 
3480
			linenumber=linenum2;
3481
 
3482
			whitespace(); //пропуск нзначащих символов
3483
 
3484
			while(isdigit(cha)){
3485
 
3486
				v1=v1*10+(cha-'0');
3487
 
3488
				nextchar();
3489
 
3490
			}
3491
 
3492
			if(cha!='.')expected('.');
3493
 
3494
			nextchar();
3495
 
3496
			i=0;
3497
 
3498
			while(isdigit(cha)){
3499
 
3500
				v2=v2*10+(cha-'0');
3501
 
3502
				nextchar();
3503
 
3504
				i++;
3505
 
3506
			}
3507
 
3508
			while(i<3){
3509
 
3510
				v2=v2*10;
3511
 
3512
				i++;
3513
 
3514
			}
3515
 
3516
			cha2=cha;
3517
 
3518
			inptr2=inptr;
3519
 
3520
			linenum2=linenumber;
3521
 
3522
			if(v1>=ver1){
3523
 
3524
				if(v1==ver1&&v2<=ver2)break;
3525
 
3526
			}
3527
 
3528
			sprintf((char *)string,"needed compiler version %0u.%03u or best",v1,v2);
3529
 
3530
			preerror((char *)string);
3531
 
3532
			break;
3533
 
3534
		case d_else:
3535
 
3536
			if(endifcount==-1) preerror("#else without preceeding #if");
3537
 
3538
			else if((useelse[endifcount]&1)==0)preerror(toelse);
3539
 
3540
			else useelse[endifcount]&=0xFE;
3541
 
3542
			if(gotoendif==1) gotoendif=0;
3543
 
3544
			else gotoendif=1;
3545
 
3546
			break;
3547
 
3548
		case d_elif:
3549
 
3550
			if(endifcount==-1) preerror("#elif without preceeding #if");
3551
 
3552
			doifdef(d_elif);
3553
 
3554
			next=0;
3555
 
3556
			gotoendif=1;
3557
 
3558
			break;
3559
 
3560
		case d_wmb: //формирование одного блока под win
3561
 
3562
			WinMonoBlock=get_directive_value();
3563
 
3564
			next=0;
3565
 
3566
			break;
3567
 
3568
		case d_pragma:
3569
 
3570
			char *ptr;
3571
 
3572
			inptr=inptr2;
3573
 
3574
			cha=cha2;
3575
 
3576
			FastTok(1);
3577
 
3578
//			printf("%c %s\n",cha,itok.name);
3579
 
3580
			i=0;
3581
 
3582
			while(cha!=13&&cha!=26){
3583
 
3584
				if(cha=='/'){
3585
 
3586
					if(input[inptr]=='/'){
3587
 
3588
						while(cha!=13&&cha!=26)nextchar();
3589
 
3590
						break;
3591
 
3592
					}
3593
 
3594
					if(input[inptr]=='*'){
3595
 
3596
						while(cha!=26){
3597
 
3598
							nextchar();
3599
 
3600
							if(cha=='*'&&input[inptr]=='/'){
3601
 
3602
								nextchar();
3603
 
3604
								nextchar();
3605
 
3606
								break;
3607
 
3608
							}
3609
 
3610
							if(cha==13)linenumber++;
3611
 
3612
						}
3613
 
3614
						break;
3615
 
3616
					}
3617
 
3618
				}
3619
 
3620
				string[i++]=cha;
3621
 
3622
				nextchar();
3623
 
3624
			}
3625
 
3626
			cha2=cha;
3627
 
3628
			inptr2=inptr;
3629
 
3630
			linenum2=linenumber;
3631
 
3632
			string[i]=0;
3633
 
3634
			strbtrim((char *)string);
3635
 
3636
//			printf("%s %s\n",itok.name,string);
3637
 
3638
			if(strlen((char *)string))ptr=BackString((char *)string);
3639
 
3640
			else ptr=NULL;
3641
 
3642
			for(i=0;i
3643
 
3644
			if(i!=p_li&&ptr==NULL){
3645
 
3646
				unknownpragma(pragmalist[i]);
3647
 
3648
				break;
3649
 
3650
			}
3651
 
3652
			switch(i){
3653
 
3654
				case p_op:
3655
 
3656
					SelectComand(ptr,0);
3657
 
3658
					break;
3659
 
3660
				case p_li:
3661
 
3662
					printf("%s (%u) %s\n",(startfileinfo+currentfileinfo)->filename,linenumber,ptr==NULL?"":ptr);
3663
 
3664
					break;
3665
 
3666
				case p_st:
3667
 
3668
					i=0;
3669
 
3670
					char c;
3671
 
3672
					do{
3673
 
3674
						c=ptr[i++];
3675
 
3676
					}while(isalnum(c)||c=='_');
3677
 
3678
					ptr[i]=0;
3679
 
3680
					if(numdomain==0)domain=(char *)MALLOC(IDLENGTH);
3681
 
3682
					else domain=(char *)REALLOC(domain,IDLENGTH*(numdomain+1));
3683
 
3684
					strcpy(domain+numdomain*IDLENGTH,ptr);
3685
 
3686
					numdomain++;
3687
 
3688
					break;
3689
 
3690
				case p_re:
3691
 
3692
					if(strcmp(ptr,"start")==0){
3693
 
3694
						scanlexmode=RESLEX;
3695
 
3696
						input_res();
3697
 
3698
					}
3699
 
3700
					else if(strcmp(ptr,"end")==0)
3701
 
3702
						scanlexmode=STDLEX;
3703
 
3704
//					retoldscanmode(STDLEX);
3705
 
3706
					else preerror("for '#pragma resource' used only 'start' or 'end'");
3707
 
3708
					break;
3709
 
3710
				case p_db:
3711
 
3712
#ifdef DEBUGMODE
3713
 
3714
					if(strcmp(ptr,"start")==0){
3715
 
3716
						debug=TRUE;
3717
 
3718
					}
3719
 
3720
					else if(strcmp(ptr,"end")==0)debug=FALSE;
3721
 
3722
					else unknownpragma("debug");
3723
 
3724
#endif
3725
 
3726
					break;
3727
 
3728
				case p_pa:
3729
 
3730
//					printf("ptr=%08X input=%08X tok=%d\n",ptr,input,tok);
3731
 
3732
					SetNewStr(ptr);
3733
 
3734
					displaytokerrors=1;
3735
 
3736
					FastTok(1);
3737
 
3738
					if(tok!=tk_openbracket){
3739
 
3740
						expected('(');
3741
 
3742
						break;
3743
 
3744
					}
3745
 
3746
					FastTok(1);
3747
 
3748
					if(tok==tk_closebracket)strpackcur=strpackdef;
3749
 
3750
					i=0;
3751
 
3752
					STACKALIGN *newpar;
3753
 
3754
					while(tok!=tk_closebracket&&tok!=tk_eof){
3755
 
3756
						switch(tok){
3757
 
3758
							case tk_number:
3759
 
3760
								if(caselong(itok.number)==NUMNUM){
3761
 
3762
									preerror("bad align size");
3763
 
3764
									break;
3765
 
3766
								}
3767
 
3768
								if(pushpop(i))i=3;
3769
 
3770
								strpackcur=itok.number;
3771
 
3772
								break;
3773
 
3774
							case tk_id:
3775
 
3776
								if(strcmp(itok.name,"push")==0){
3777
 
3778
									if(i)unknownpragma("pack(push)");
3779
 
3780
									i=1;
3781
 
3782
								}
3783
 
3784
								else if(strcmp(itok.name,"pop")==0){
3785
 
3786
									if(i)unknownpragma("pack(pop)");
3787
 
3788
									i=2;
3789
 
3790
								}
3791
 
3792
								else if(strcmp(itok.name,"show")==0){
3793
 
3794
									printf("%s (%u) Current packing alignment for structure = %d\n",(startfileinfo+currentfileinfo)->filename,linenumber,strpackcur);
3795
 
3796
									i=3;
3797
 
3798
								}
3799
 
3800
								else{
3801
 
3802
									switch(i){
3803
 
3804
										case 0:
3805
 
3806
											unknownpragma("pack");
3807
 
3808
											break;
3809
 
3810
										case 1:
3811
 
3812
											newpar=(STACKALIGN *)MALLOC(sizeof(STACKALIGN));
3813
 
3814
											newpar->prev=stackalign;
3815
 
3816
											newpar->size=strpackcur;
3817
 
3818
											strcpy(newpar->id,itok.name);
3819
 
3820
											stackalign=newpar;
3821
 
3822
											i=3;
3823
 
3824
											break;
3825
 
3826
										case 2:
3827
 
3828
											while(stackalign!=NULL&&strcmp(itok.name,stackalign->id)!=0){
3829
 
3830
												newpar=stackalign->prev;
3831
 
3832
												free(stackalign);
3833
 
3834
												stackalign=newpar;
3835
 
3836
											}
3837
 
3838
											if(stackalign==NULL){
3839
 
3840
												strpackcur=strpackdef;
3841
 
3842
												warpragmapackpop();
3843
 
3844
												break;
3845
 
3846
											}
3847
 
3848
											newpar=stackalign->prev;
3849
 
3850
											free(stackalign);
3851
 
3852
											stackalign=newpar;
3853
 
3854
											strpackcur=(stackalign==NULL?strpackdef:stackalign->size);
3855
 
3856
											i=3;
3857
 
3858
											break;
3859
 
3860
										default:
3861
 
3862
											unknownpragma("pack");
3863
 
3864
											break;
3865
 
3866
									}
3867
 
3868
								}
3869
 
3870
						}
3871
 
3872
						FastTok(1);
3873
 
3874
						if(tok==tk_camma)FastTok(1);
3875
 
3876
					}
3877
 
3878
					pushpop(i);
3879
 
3880
//					printf("ptr=%08X input=%08X tok=%d\n",ptr,input,tok);
3881
 
3882
					inptr2=inptr;
3883
 
3884
					cha2=cha;
3885
 
3886
					while(ptr==(char*)input)nexttok();
3887
 
3888
					next=0;
3889
 
3890
					break;
3891
 
3892
				case p_idx:
3893
 
3894
					SetNewStr(ptr);
3895
 
3896
					inptr2=1;
3897
 
3898
					InitIdxRegs();
3899
 
3900
					next=0;
3901
 
3902
					break;
3903
 
3904
				default:
3905
 
3906
					unknownpragma("");
3907
 
3908
					break;
3909
 
3910
			}
3911
 
3912
			if(ptr)free(ptr);
3913
 
3914
			break;
3915
 
3916
		case d_inline:
3917
 
3918
			nexttok();
3919
 
3920
			if(tok==tk_number){
3921
 
3922
				if(itok.number>=0&&itok.number<=2)useinline=itok.number;
3923
 
3924
				else preerror(ido);
3925
 
3926
			}
3927
 
3928
			else if(strcmp(itok.name,"AUTO")==0)useinline=2;
3929
 
3930
			else preerror(ido);
3931
 
3932
			break;
3933
 
3934
		default:
3935
 
3936
			preerror("compiler directive expected");
3937
 
3938
	}
3939
 
3940
	if(next)nexttok();
3941
 
3942
	while(gotoendif){
3943
 
3944
		if(tok==tk_question){
3945
 
3946
			if(itok.number==d_endif){
3947
 
3948
				gotoendif--;
3949
 
3950
				endifcount--;
3951
 
3952
//			printf("%s (%u) endif shadow: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount);
3953
 
3954
			}
3955
 
3956
			else if(itok.number==d_ifdef||itok.number==d_ifndef||itok.number==d_if){
3957
 
3958
				gotoendif++;
3959
 
3960
				endifcount++;
3961
 
3962
//			printf("%s (%u) if shadow: endifcount=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,endifcount);
3963
 
3964
				CheckNumIF();
3965
 
3966
				useelse[endifcount]=1;
3967
 
3968
			}
3969
 
3970
			else if(itok.number==d_else){
3971
 
3972
				if((useelse[endifcount]&1)==0)preerror(toelse);
3973
 
3974
				else useelse[endifcount]&=0xFE;
3975
 
3976
				if(gotoendif==1&&useelse[endifcount]==0){
3977
 
3978
					gotoendif=0;
3979
 
3980
					useelse[endifcount]|=2;
3981
 
3982
				}
3983
 
3984
			}
3985
 
3986
			else if(itok.number==d_elif){
3987
 
3988
				if(gotoendif==1){
3989
 
3990
					doifdef(d_elif);
3991
 
3992
					if(gotoendif==0){
3993
 
3994
						if((useelse[endifcount]&2)==0){
3995
 
3996
							useelse[endifcount]|=2;
3997
 
3998
							break;
3999
 
4000
						}
4001
 
4002
						gotoendif=1;
4003
 
4004
					}
4005
 
4006
				}
4007
 
4008
			}
4009
 
4010
		}
4011
 
4012
		else if(tok==tk_eof){
4013
 
4014
			unexpectedeof();
4015
 
4016
			break;
4017
 
4018
		}
4019
 
4020
		if(gotoendif)FindDirectiv();
4021
 
4022
		else{
4023
 
4024
			nexttok();
4025
 
4026
			break;
4027
 
4028
		}
4029
 
4030
	}
4031
 
4032
	usedirectiv=FALSE;
4033
 
4034
	dirmode=dm_none;
4035
 
4036
}
4037
 
4038
 
4039
 
4040
void doenum()
4041
 
4042
{
4043
 
4044
long counter=0;
4045
 
4046
unsigned char next;
4047
 
4048
char holdid[IDLENGTH];
4049
 
4050
	nexttok();
4051
 
4052
	if(tok!=tk_openbrace){
4053
 
4054
		if(tok2!=tk_openbrace)expected('{');
4055
 
4056
		nexttok();
4057
 
4058
	}
4059
 
4060
	do{
4061
 
4062
		next=1;
4063
 
4064
		nexttok();
4065
 
4066
		switch(tok){
4067
 
4068
			case tk_ID:
4069
 
4070
			case tk_id:
4071
 
4072
				strcpy(holdid,(char *)string);
4073
 
4074
				if(tok2==tk_assign){
4075
 
4076
					nexttok();
4077
 
4078
					nexttok();
4079
 
4080
					CheckMinusNum();
4081
 
4082
					if(tok==tk_number){
4083
 
4084
						counter=doconstlongmath();
4085
 
4086
						next=0;
4087
 
4088
						postnumflag=0;
4089
 
4090
					}
4091
 
4092
					else numexpected();
4093
 
4094
				}
4095
 
4096
				addconsttotree(holdid,counter);
4097
 
4098
				counter++;
4099
 
4100
				break;
4101
 
4102
			case tk_closebrace:
4103
 
4104
				next=0;
4105
 
4106
				break;
4107
 
4108
			default:
4109
 
4110
				idalreadydefined();
4111
 
4112
				break;
4113
 
4114
		}
4115
 
4116
		if(next)nexttok();
4117
 
4118
	}while(tok==tk_camma);
4119
 
4120
	if(tok!=tk_closebrace)expected('}');
4121
 
4122
	nextseminext();
4123
 
4124
}
4125
 
4126
 
4127
 
4128
int CompConst(int firstval)
4129
 
4130
{
4131
 
4132
	int otok=tok;
4133
 
4134
	nexttok();
4135
 
4136
	if(tok!=tk_number)unknowncompop();
4137
 
4138
	switch(otok){
4139
 
4140
		case tk_equalto:
4141
 
4142
			if(firstval==itok.number)return TRUE;
4143
 
4144
			break;
4145
 
4146
		case tk_notequal:
4147
 
4148
			if(firstval!=itok.number)return TRUE;
4149
 
4150
			break;
4151
 
4152
		case tk_greater:
4153
 
4154
			if(firstval>itok.number)return TRUE;
4155
 
4156
			break;
4157
 
4158
		case tk_less:
4159
 
4160
			if(firstval
4161
 
4162
			break;
4163
 
4164
		case tk_greaterequal:
4165
 
4166
			if(firstval>=itok.number)return TRUE;
4167
 
4168
			break;
4169
 
4170
		case tk_lessequal:
4171
 
4172
			if(firstval<=itok.number)return TRUE;
4173
 
4174
			break;
4175
 
4176
		default: unknowncompop();
4177
 
4178
	}
4179
 
4180
	return FALSE;
4181
 
4182
}
4183
 
4184
 
4185
 
4186
int ifdefconst()
4187
 
4188
{
4189
 
4190
	if(optimizespeed==TRUE){
4191
 
4192
		if(strcmp((char *)string,"speed")==0)return TRUE;
4193
 
4194
	}
4195
 
4196
	else if(strcmp((char *)string,"codesize")==0)return TRUE;
4197
 
4198
	if(strcmp((char *)string,"cpu")==0){
4199
 
4200
		nexttok();
4201
 
4202
		return CompConst(chip);
4203
 
4204
	}
4205
 
4206
	if(itok2.type==tp_compare){
4207
 
4208
//		unknowncompop();
4209
 
4210
		nexttok();
4211
 
4212
		nexttok();
4213
 
4214
		return FALSE;
4215
 
4216
	}
4217
 
4218
	if(comfile==file_w32&&strcmp((char *)string,"_WIN32")==0)return TRUE;
4219
 
4220
	if(*(short *)&string[0]==0x5F5F){
4221
 
4222
		if(comfile==file_w32){
4223
 
4224
			if(strcmp((char *)string+2,"TLS__")==0)return TRUE;
4225
 
4226
			if(dllflag&&strcmp((char *)string+2,"DLL__")==0)return TRUE;
4227
 
4228
			else{
4229
 
4230
				if(wconsole&&strcmp((char *)string+2,"CONSOLE__")==0)return TRUE;
4231
 
4232
				else if(strcmp((char *)string+2,"WIN32__")==0)return TRUE;
4233
 
4234
			}
4235
 
4236
		}
4237
 
4238
		if(am32){
4239
 
4240
			if(strcmp((char *)string+2,"FLAT__")==0)return TRUE;
4241
 
4242
		}
4243
 
4244
		else{
4245
 
4246
			if(strcmp((char *)string+2,"MSDOS__")==0)return TRUE;
4247
 
4248
			if(modelmem==TINY&&strcmp((char *)string+2,"TINY__")==0)return TRUE;
4249
 
4250
			if(modelmem==SMALL&&strcmp((char *)string+2,"SMALL__")==0)return TRUE;
4251
 
4252
		}
4253
 
4254
		if(comfile==file_d32&&strcmp((char *)string+2,"DOS32__")==0)return TRUE;
4255
 
4256
		if(comfile==file_com&&strcmp((char *)string+2,"COM__")==0)return TRUE;
4257
 
4258
		if(comfile==file_sys&&strcmp((char *)string+2,"SYS__")==0)return TRUE;
4259
 
4260
		if(comfile==file_rom&&strcmp((char *)string+2,"ROM__")==0)return TRUE;
4261
 
4262
		if(comfile==file_bin&&strcmp((char *)string+2,"BIN32__")==0)return TRUE;
4263
 
4264
		if(comfile==file_meos&&strcmp((char *)string+2,"MEOS__")==0)return TRUE;
4265
 
4266
		if((sobj||fobj)&&strcmp((char *)string+2,"OBJ__")==0)return TRUE;
9695 Coldy 4267
 
4268
		// Added by Coldy (for mark MSCOFF build)
4269
		if ((ocoff&&sobj) && strcmp((char *)string + 2, "COFF__") == 0)return TRUE;
6446 GerdtR 4270
 
4271
		if(comfile==file_exe){
4272
 
4273
			if(modelmem==TINY){
4274
 
4275
				if(strcmp((char *)string+2,"TEXE__")==0)return TRUE;
4276
 
4277
			}
4278
 
4279
			else if(strcmp((char *)string+2,"EXE__")==0)return TRUE;
4280
 
4281
		}
4282
 
4283
	}
4284
 
4285
	return 2;
4286
 
4287
}
4288
 
4289
 
4290
 
4291
void CheckNumIF()
4292
 
4293
{
4294
 
4295
	if(endifcount>=NUMIFDEF)preerror("#ifdef/#ifndef - too large enclosure");
4296
 
4297
}
4298
 
4299
 
4300
 
4301
static int firstincl=FALSE;
4302
 
4303
 
4304
 
4305
void IncludeFile(char *fileincl,int tfind)
4306
 
4307
{
4308
 
4309
unsigned char *holdinput;
4310
 
4311
unsigned int holdinptr,holdendinptr,holdlinenum;
4312
 
4313
unsigned char holdwarning;
4314
 
4315
unsigned char holdcha,holdendoffile;
4316
 
4317
int ofileinfo;
4318
 
4319
char *ostartline;
4320
 
4321
int oscanlexmode=scanlexmode;
4322
 
4323
int opostnumflag;
4324
 
4325
COM_MOD *ocurmod=cur_mod;
4326
 
4327
 
4328
 
4329
int oendifcount;
4330
 
4331
 
4332
 
4333
	oendifcount=endifcount;
4334
 
4335
	cur_mod=NULL;
4336
 
4337
	if(!firstincl){
4338
 
4339
		firstincl=TRUE;
4340
 
4341
		if((dbg&1)&&am32==FALSE){
4342
 
4343
			holdcha=dbgact;
4344
 
4345
			dbgact=0;
4346
 
4347
			AddLine();
4348
 
4349
			dbgact=holdcha;
4350
 
4351
		}
4352
 
4353
	}
4354
 
4355
	scanlexmode=STDLEX;
4356
 
4357
	opostnumflag=postnumflag;
4358
 
4359
	holdinput=input;	//сохр некотор переменые
4360
 
4361
	holdinptr=inptr2;
4362
 
4363
	holdcha=cha2;
4364
 
4365
	holdlinenum=linenum2;
4366
 
4367
	holdendinptr=endinptr;
4368
 
4369
	holdendoffile=endoffile;
4370
 
4371
	holdwarning=warning;
4372
 
4373
	ostartline=startline;
4374
 
4375
	ofileinfo=currentfileinfo;
4376
 
4377
	(startfileinfo+currentfileinfo)->stlist=staticlist;
4378
 
4379
	compilefile(fileincl,tfind);//откомпилировать
4380
 
4381
	if(endifcount!=oendifcount){
4382
 
4383
		sprintf((char *)string2,"num if prior %d after %d",oendifcount,endifcount);
4384
 
4385
		preerror((char *)string2);
4386
 
4387
	}
4388
 
4389
//	(startfileinfo+currentfileinfo)->staticlist=staticlist;
4390
 
4391
	currentfileinfo=ofileinfo;
4392
 
4393
	staticlist=(startfileinfo+currentfileinfo)->stlist;
4394
 
4395
	warning=holdwarning;
4396
 
4397
	endoffile=holdendoffile;//востановить переменые
4398
 
4399
	endinptr=holdendinptr;
4400
 
4401
	input=holdinput;
4402
 
4403
	inptr2=holdinptr;
4404
 
4405
	cha2=holdcha;
4406
 
4407
	linenumber=linenum2=holdlinenum;
4408
 
4409
	startline=ostartline;
4410
 
4411
//	retoldscanmode(oscanlexmode);
4412
 
4413
	scanlexmode=oscanlexmode;
4414
 
4415
	postnumflag=opostnumflag;
4416
 
4417
	cur_mod=ocurmod;
4418
 
4419
}
4420
 
4421
 
4422
 
4423
/*-----------------31.05.99 21:39-------------------
4424
 
4425
 поддержка startup
4426
 
4427
 --------------------------------------------------*/
4428
 
4429
 
4430
 
4431
int startlabl(char *namelab)
4432
 
4433
{
4434
 
4435
//ITOK btok;
4436
 
4437
//int bb;
4438
 
4439
//	if(searchtree(&btok,&bb,(unsigned char *)namelab)==FALSE)thisundefined(namelab);
4440
 
4441
	searchvar(namelab);
4442
 
4443
	return itok.number;
4444
 
4445
}
4446
 
4447
 
4448
 
4449
void searchvar(char *name,int err)
4450
 
4451
{
4452
 
4453
	strcpy((char *)string,name);
4454
 
4455
	if(searchtree(&itok,&tok,string)==FALSE&&err)thisundefined(name);
4456
 
4457
}
4458
 
4459
 
4460
 
4461
void doprestuff()  //инициализация начального кода, like resize mem, jump to main...
4462
 
4463
{
4464
 
4465
ITOK oitok;
4466
 
4467
int otok,otok2;
4468
 
4469
unsigned int addresshold;
4470
 
4471
unsigned char ojmp;
4472
 
4473
char *bstring;
4474
 
4475
int odbg=dbg;
4476
 
4477
//сохранить параметры
4478
 
4479
//	if(FixUp==TRUE||comfile==file_w32)optnumber=FALSE;
4480
 
4481
	oitok=itok;
4482
 
4483
	bstring=BackString((char *)string);
4484
 
4485
	otok=tok;
4486
 
4487
	ojmp=0xff;
4488
 
4489
	otok2=tok2;
4490
 
4491
//	printf("tok=%d inptr=%d\n",tok,inptr);
4492
 
4493
	if(notdoneprestuff==TRUE){
4494
 
4495
		if(splitdata)startptrdata=0;
4496
 
4497
		if(comfile!=file_w32||(dbg&2))dbgact=0;
4498
 
4499
	}
4500
 
4501
	if(startuptomain==TRUE&&comfile==file_com){
4502
 
4503
		if(notdoneprestuff==TRUE){
4504
 
4505
			outptr=startptr;
4506
 
4507
			outptrdata=startptrdata;
4508
 
4509
			if(jumptomain!=CALL_NONE){
4510
 
4511
				tok=tk_ID;
4512
 
4513
				strcpy(itok.name,mesmain);
4514
 
4515
				tobedefined(jumptomain==CALL_NEAR?JMP_NEAR:CALL_SHORT,tk_void);	/* put main on the to be defined stack */
4516
 
4517
				if(jumptomain==CALL_NEAR )jumploc0();
4518
 
4519
				else outword(0x00EB);	// JMP short
4520
 
4521
			}
4522
 
4523
			endStartup=outptr;
4524
 
4525
			notdoneprestuff=FALSE;
4526
 
4527
			goto endp;
4528
 
4529
		}
4530
 
4531
		else{
4532
 
4533
			header=0;	//чтоб не было повторной надписи sphinx
4534
 
4535
			ojmp=jumptomain;
4536
 
4537
			jumptomain=CALL_NONE;
4538
 
4539
			startuptomain=FALSE;
4540
 
4541
		}
4542
 
4543
	}
4544
 
4545
	else if(comsymbios==FALSE){
4546
 
4547
		outptr=startptr;
4548
 
4549
		outptrdata=startptrdata;
4550
 
4551
	}
4552
 
4553
	notdoneprestuff=FALSE;
4554
 
4555
	if(comfile==file_meos)outptrdata=outptr=startptr+sizeof(MEOSheader);
4556
 
4557
	if(sobj){
4558
 
4559
		outptrdata=outptr=startptrdata=startptr=0;
4560
 
4561
		goto endp;
4562
 
4563
	}
4564
 
4565
	itok.post=1;
4566
 
4567
	itok.segm=DS;
4568
 
4569
	itok.number=0;
4570
 
4571
	itok.flag=0;
4572
 
4573
	itok.size=0;
4574
 
4575
	itok.rm=(am32==FALSE?rm_d16:rm_d32);
4576
 
4577
	tok=(am32==0?tk_wordvar:tk_dwordvar);
4578
 
4579
	string[0]=0;
4580
 
4581
	addtotree("__startpostvar");
4582
 
4583
	itok.rec->count=1;
4584
 
4585
	if(comfile==file_bin)goto endp;
4586
 
4587
	else ImageBase=Align(ImageBase,0x10000);
4588
 
4589
	if(jumptomain==CALL_NONE){
4590
 
4591
		if(comfile==file_w32||comfile==file_exe||comfile==file_meos)goto endp;
4592
 
4593
		if(comfile==file_com&&fargc==0&&parsecommandline==0&&atex==0&&use_env==0
4594
 
4595
				&&clearpost==0&&resizemem==0&&killctrlc==0)goto endp;
4596
 
4597
	}
4598
 
4599
	if(comfile==file_sys){
4600
 
4601
		addconsttotree("__SYSATRIB",sysatr);
4602
 
4603
		tok=tk_string;
4604
 
4605
		itok.number=8;
4606
 
4607
		itok.flag=zero_term;
4608
 
4609
		strncpy((char *)string,sysname,8);
4610
 
4611
		addtotree("__SYSNAME");
4612
 
4613
		if(sysstack!=0){
4614
 
4615
			addconsttotree("__SYSSTACK",sysstack);
4616
 
4617
		}
4618
 
4619
		if(sysnumcom==0)preerror("list command expected");
4620
 
4621
		else addconsttotree("__SYSNUMCOM",sysnumcom);
4622
 
4623
	}
4624
 
4625
	else if(comfile==file_rom){
4626
 
4627
		resizemem=0;
4628
 
4629
		addconsttotree("__ROMSIZE",romsize);
4630
 
4631
		addconsttotree("__DATASEG",dataseg);
4632
 
4633
		if(modelmem!=SMALL){
4634
 
4635
			free(outputdata);
4636
 
4637
			outputdata=output;
4638
 
4639
		}
4640
 
4641
	}
4642
 
4643
	else if(comsymbios==TRUE){
4644
 
4645
		addresshold=outptr;
4646
 
4647
		addconsttotree("__STARTPTR",startptr);
4648
 
4649
		addconsttotree("__STARTVALW",*(unsigned short *)&output[startptr]);
4650
 
4651
		addconsttotree("__STARTVALB",output[startptr+2]);
4652
 
4653
	}
4654
 
4655
	if(comfile==file_w32&&wbss)clearpost=FALSE;
4656
 
4657
	if(resizemem)addconsttotree("__resizemem",TRUE);
4658
 
4659
	if(killctrlc)addconsttotree("__ctrl_c",TRUE);
4660
 
4661
	if(parsecommandline)addconsttotree("__parsecommandline",TRUE);
4662
 
4663
	if(atex)addconsttotree("__atexit",TRUE);
4664
 
4665
	if(fargc)addconsttotree("__argc",TRUE);
4666
 
4667
	if(use_env)addconsttotree("__environ",TRUE);
4668
 
4669
	if(clearpost)addconsttotree("__clearpost",TRUE);
4670
 
4671
	if(comfile==file_d32){
4672
 
4673
		if(useDOS4GW)addconsttotree("__useDOS4GW",TRUE);
4674
 
4675
		if(dpmistub&&(!usestub)){
4676
 
4677
			addconsttotree("__DPMIonly",TRUE);
4678
 
4679
			resizemem=TRUE;
4680
 
4681
			jumptomain=CALL_NEAR;
4682
 
4683
		}
4684
 
4685
	}
4686
 
4687
	if(jumptomain==CALL_SHORT)addconsttotree("__shortjmp",TRUE);
4688
 
4689
	else if(jumptomain==CALL_NONE)addconsttotree("__nonejmptomain",TRUE);
4690
 
4691
 
4692
 
4693
	if(dbg){
4694
 
4695
		if(am32==FALSE){
4696
 
4697
			if(firstincl==FALSE){
4698
 
4699
				firstincl=TRUE;
4700
 
4701
				AddLine();
4702
 
4703
			}
4704
 
4705
			dbg=0;
4706
 
4707
		}
4708
 
4709
	}
4710
 
4711
	IncludeFile(namestartupfile,0);
4712
 
4713
	dbg=odbg;
4714
 
4715
 
4716
 
4717
	if((dbg&1)&&outptr==startptr)KillLastLine();
4718
 
4719
 
4720
 
4721
	if(atex||(comfile==file_w32&&(!dllflag))){
4722
 
4723
		startexit=startlabl("__startexit");
4724
 
4725
		if(ojmp==0xff)endStartup=startexit;
4726
 
4727
	}
4728
 
4729
	else if(ojmp==0xff)endStartup=outptr;
4730
 
4731
	if(sobj==FALSE&&fobj==FALSE&&	//new 18.04.07 23:52
4732
 
4733
			comfile==file_com){
4734
 
4735
		if(resizemem){
4736
 
4737
			resizesizeaddress=startlabl("__stackseg");
4738
 
4739
			stackstartaddress=startlabl("__stackval");
4740
 
4741
		}
4742
 
4743
	}
4744
 
4745
	else if(comfile==file_sys){
4746
 
4747
		syscom=startlabl("__listcom");
4748
 
4749
	}
4750
 
4751
	else if(comfile==file_rom){
4752
 
4753
		if(modelmem==SMALL){
4754
 
4755
			stackstartaddress=startlabl("__stackstart");
4756
 
4757
			dataromstart=startlabl("__startdata");
4758
 
4759
			dataromsize=startlabl("__sizedata");
4760
 
4761
		}
4762
 
4763
		else{
4764
 
4765
			useStartup=TRUE;
4766
 
4767
			endStartup=0xfff0;
4768
 
4769
			startStartup=0;
4770
 
4771
		}
4772
 
4773
	}
4774
 
4775
	if(comsymbios==TRUE){
4776
 
4777
		output[startptr]=0xE9;
4778
 
4779
		addresshold=addresshold-(startptr+3); /* inital  */
4780
 
4781
		*(unsigned short *)&output[startptr+1]=(unsigned short)addresshold;
4782
 
4783
	}
4784
 
4785
	if(ojmp!=0xff)jumptomain=ojmp;
4786
 
4787
endp:
4788
 
4789
	if(header){
4790
 
4791
		outprocedure(aabaner,MMBANER);
4792
 
4793
		alignersize+=MMBANER;
4794
 
4795
	}
4796
 
4797
	itok=oitok;
4798
 
4799
	tok=otok;
4800
 
4801
	tok2=otok2;
4802
 
4803
	strcpy((char *)string,bstring);
4804
 
4805
	free(bstring);
4806
 
4807
	if(strcmp(itok.name,mesmain)==0)searchtree(&itok,&tok,(unsigned char *)&string);
4808
 
4809
	if((comfile!=file_d32||dpmistub)&&stubfile!=NULL){
4810
 
4811
		free(stubfile);
4812
 
4813
		stubfile=NULL;
4814
 
4815
	}
4816
 
4817
	dbgact=0;
4818
 
4819
}
4820
 
4821
 
4822
 
4823
void KillVarOfTree(idrec **treestart)
4824
 
4825
{
4826
 
4827
struct idrec *ptr,*leftptr,*rightptr,*prev;
4828
 
4829
int cmpresult,ocmpresult=0;
4830
 
4831
	ptr=*treestart;	//поиск
4832
 
4833
	while(ptr!=NULL&&(cmpresult=strcmp(ptr->recid,itok.name))!=0){
4834
 
4835
		prev=ptr;	//родитель
4836
 
4837
		ocmpresult=cmpresult;	//результат пред сравнения - опр в левой или правой ветви
4838
 
4839
		if(cmpresult<0)ptr=ptr->left;
4840
 
4841
		else ptr=ptr->right;
4842
 
4843
	}
4844
 
4845
	if(ptr!=NULL){	//найден объект удаления
4846
 
9714 Coldy 4847
		if(ptr->newid){
4848
			free(ptr->newid);	//удалить доп информ.
4849
			// Fixed by Coldy, thx turbocat (double free error)
4850
			ptr->newid = NULL;
4851
		}
6446 GerdtR 4852
 
4853
		leftptr=ptr->left;	//дите
4854
 
4855
		rightptr=ptr->right;//другое дите
4856
 
4857
		if(leftptr==NULL&&rightptr==NULL){	//если нет дитей
4858
 
4859
			if(ocmpresult<0)prev->left=NULL;  //то родитель остался сиротой
4860
 
4861
			else if(ocmpresult>0)prev->right=NULL;
4862
 
4863
			else *treestart=NULL;	//удален корень без ветвей
4864
 
4865
		}
4866
 
4867
		else if(leftptr==NULL){	//одно дите справа
4868
 
4869
			if(ocmpresult<0)prev->left=rightptr;	//передать внуков родителю
4870
 
4871
			else if(ocmpresult>0)prev->right=rightptr;
4872
 
4873
			else *treestart=rightptr;	//удален корень с одной правой веткой
4874
 
4875
		}
4876
 
4877
		else if(rightptr==NULL){	//тоже если дите слева
4878
 
4879
			if(ocmpresult<0)prev->left=leftptr;
4880
 
4881
			else if(ocmpresult>0)prev->right=leftptr;
4882
 
4883
			else *treestart=leftptr;	//удален корень с одной левой веткой
4884
 
4885
		}
4886
 
4887
		else{	//если есть оба ребенка
4888
 
4889
			struct idrec *ostptr,*ptrf;
4890
 
4891
			if(ocmpresult<0){	//если мы дите слева
4892
 
4893
				prev->left=leftptr;	//передать левого ребенка
4894
 
4895
				ostptr=rightptr;    //правого к поиску места
4896
 
4897
			}
4898
 
4899
			else if(ocmpresult>0){	//если же мы дите справа
4900
 
4901
				prev->right=rightptr; //передать правого ребенка
4902
 
4903
				ostptr=leftptr;       //левого к поиску
4904
 
4905
			}
4906
 
4907
			else{                   //если у нас нет родителя
4908
 
4909
				*treestart=rightptr;   //один наугад становится главным
4910
 
4911
				ostptr=leftptr;       //другого к поиску
4912
 
4913
			}
4914
 
4915
			ptrf=*treestart;	//начало дерева
4916
 
4917
			while(((cmpresult=strcmp(ptrf->recid,ostptr->recid))<0&&ptrf->left!=NULL)||
4918
 
4919
	       (cmpresult>0&&ptrf->right!=NULL)){
4920
 
4921
				if(cmpresult<0)ptrf=ptrf->left;
4922
 
4923
				else ptrf=ptrf->right;
4924
 
4925
			}
4926
 
4927
			if(cmpresult<0)ptrf->left=ostptr;	//строка меньше
4928
 
4929
			else ptrf->right=ostptr;
4930
 
4931
		}
4932
 
4933
		if(ptr->newid)free(ptr->newid);
4934
 
4935
		if(ptr->sbuf)free(ptr->sbuf);
4936
 
4937
		free(ptr);
4938
 
4939
	}
4940
 
4941
}
4942
 
4943
/* end of TOKE.C */
4944