Subversion Repositories Kolibri OS

Rev

Rev 1846 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1846 yogev_ezra 1
byte Directives={
2
	"IF","ELSE","ENDIF",	// Условная компиляция
3
	"INCLUDE","DEFINE", // Включение файла/Определение константы
4
	"IMPORT", 	// Импорт из DLL по имени API
5
	"IMPORTN",		// Импорт из DLL по номеру API
6
	"MAP",			// Генерация MAP-файла
7
	"DEBUG",		// Генерация отладочной информации
8
	"LIST", 		// Выдача ASM-листинга
9
	"DLL",			// Генерация DLL-файла
10
	"DB","DW","DD", 	// Типы переменных
11
	"BYTE","CHAR","WORD","SHORT","DWORD","INT",
12
	"ENUM", 		// Нумерованные константы
13
	"STRUC",		// Определение структуры
14
	"CYCLE","RETURN",
15
	"WHILE","DO","INLINE",
16
	"CONTINUE","BREAK",
17
	"DOCASE","CASE","DEFAULT",
18
	"CARRYFLAG","EXTRACT","FROM",
19
	"NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW",
20
	"ZEROFLAG","NOTZEROFLAG",_END};
21
// ----- Для tokens, НЕ обрабатываемых через таблицу переключателей
22
EMPTY()
23
{
24
	WRITESTR(#string);
25
	WRITESTR("-ToDo\n");
26
	NextTok();
27
}
28
 
29
// ---- Возвращает адрес из Jmp_....
30
dword GetDirAddr(dword table,num)
31
{
32
	EAX=num<<2+table;
33
	EAX=DSDWORD[EAX];
34
}
35
 
36
// ----- Директива #define
37
DirDefine()
38
byte holdid[IDLENGTH];
39
dword next;
40
{
41
	next=1;
42
	NextTok();
43
	if(tok==tk_id){
44
		lstrcpyA(#holdid,#string);	// Имя константы
45
		NextTok();
46
		IF(tok==tk_eof)  unexpectedeof();
47
		ELSE IF(tok==tk_number){
48
			AddConstToTree(#holdid,DoConstLongMath()); next = 0;
49
		}
50
		ELSE IF(tok==tk_minus){
51
			IF(tok2==tk_number) {
52
				AddConstToTree(#holdid,DoConstLongMath());
53
				next = 0;
54
			}
55
		}
56
		ELSE IF(tok==tk_undefproc){
57
			tok = tk_id; AddToTree(#holdid);
58
		}
59
		ELSE	AddToTree(#holdid);
60
	}
61
	ELSE idexpected();
62
	IF(next)NextTok();
63
}
64
 
65
// -- #enum
66
DirEnum()
67
dword counter;
68
byte holdid[IDLENGTH];
69
{
70
	counter=0;
71
	NextTok();
72
	IF(tok!=tk_openbrace)expected('{');
73
	for(;;){
74
		NextTok();
75
		IF(tok==tk_id){
76
			lstrcpyA(#holdid,#string);
77
			IF( tok2 == tk_assign ){
78
				NextTok(); NextTok();
79
				IF(tok==tk_number)counter=DoConstLongMath();
80
				ELSE numexpected();
81
			}
82
			AddConstToTree(#holdid,counter);
83
			counter++;
84
			CONTINUE;
85
		}
86
		IF(tok==tk_comma)CONTINUE;
87
		IF(tok==tk_semicolon)BREAK;
88
	}
89
	NextTok();
90
}
91
 
92
// Директива #import
93
DirImport()
94
{
95
	NextTok();
96
	IF(tok==tk_string)GetImport(1); 	// import по имени API-функций
97
	ELSE stringexpected();
98
	NextTok();
99
}
100
 
101
// Директива #importN
102
DirImportN()
103
{
104
	NextTok();
105
	IF(tok==tk_string)GetImport(0); 	// import по имени API-функций
106
	ELSE stringexpected();
107
	NextTok();
108
}
109
 
110
// ---- Импорт из DLL
111
GetImport(dword byName)
112
dword dll;
113
dword dllpos,base,export,fptr,i,nexports,nsect,delta;
114
byte path[80],name[120];
115
dword tok0,type0,src0,post0;
116
dword number0;
117
dword ord;
118
dword pname1,pname2,j;
119
{
120
	pname1 = 0; ord=0; importFlag=1;
121
	IF(DLLcount>=MAXDLLS)outofmemory2();
122
	IF(SearchTree(#tok0,#type0,#src0,#post0,#string,#number0))return; // DLL уже импортирован
123
	wsprintfA(#name,"%s",#string);
124
	dll=_lopen(#name,0);
125
	IF(dll== -1){
126
		GetSystemDirectoryA(#path,80);
127
		wsprintfA(#name,"%s\\%s",#path,#string);
128
		dll=_lopen(#name,0);
129
		IF(dll==-1) {
130
			unabletoopen(#string);
131
			return;
132
		}
133
	}
134
	nsect=0;
135
	_llseek(dll,0x3c,0); _lread(dll,#fptr,4);
136
	_llseek(dll,fptr+120,0); _lread(dll,#export,4); // Get export address
137
	IF(export==0) {
138
		wsprintfA(#mapstr,"ERROR: No export directory in file %s.\n",#string);
139
		preerror(#mapstr); return;
140
	}
141
	_llseek(dll,fptr+6,0); _lread(dll,#nsect,2);			 // Number of sections
142
	delta=export;
143
	i=1;
144
	while(i<=nsect){
145
		EAX=i; EAX--; EAX=EAX*40; EAX+=260; EAX+=fptr;	// fptr+260+40*(i-1)
146
		_llseek(dll,EAX,0); _lread(dll,#base,4); // RVA of section
147
		IF(base<=export){
148
			EAX=export-base;
149
			IF(EAX
150
				delta=export-base;
151
				EAX=i; EAX--; EAX=EAX*40; EAX+=268; EAX+=fptr;	// fptr+268+40*(i-1)
152
				_llseek(dll,EAX,0); _lread(dll,#dllpos,4);
153
			}
154
		}
155
		i++;
156
	}
157
	dllpos = dllpos + delta;	 // filepos for export directory table
158
	delta = dllpos - export;
159
	_llseek(dll,dllpos+24,0); _lread(dll,#nexports,4);		// number of entries for export
160
	_llseek(dll,dllpos+32,0); _lread(dll,#base,4);		// address of export name pointer table
161
	_llseek(dll,dllpos+36,0); _lread(dll,#fptr,4);// address of Ordinal Table
162
	base=base+delta; fptr=fptr+delta;
163
	tok0=tok; number0=number;src0=src;type0=type;post0=post;
164
	tok=tk_DLL; number=nexports;src=NULL; type=byName; post=0; modline=0;
165
	AddToTree(#string);
166
	EBX=DLLcount; EBX<<=2;
167
	DLLlist[EBX] = treeptr; 	// save ptr in tree
168
	tok=tk_API; type=treeptr;
169
	i=0;
170
	while(nexports-1>i){
171
		EAX=i; EAX<<=1; EAX+=fptr;	// fptr+2*i
172
		_llseek(dll,EAX,0); _lread(dll,#ord,2);// Ordinal number
173
		EAX=i; EAX<<=2; EAX+=base;	// base+4*i
174
		_llseek(dll,EAX,0); _lread(dll,#pname1,8);	// address of name
175
		_llseek(dll,pname1+delta,0); _lread(dll,#string,pname2-pname1);// address of Ordinal Table
176
		 number=ord+1;	// при загрузке используется номер на 1 больше экспортируемого из DLL
177
		 AddToTree(#string);
178
//	 SHOW(#string);SHOW("\n");
179
		 i++;
180
	}
181
	EAX=i; EAX<<=1; EAX+=fptr;	// fptr+2*i
182
	_llseek(dll,EAX,0); _lread(dll,#ord,2); // Ordinal number
183
	j=0;
184
	for(;;){
185
		_llseek(dll,pname2+delta+j,0); EAX=j;
186
		_lread(dll,#string[EAX],1); EAX=j;
187
		IF(string[EAX]==0)BREAK;
188
		j++;
189
	}
190
	number=ord+1;
191
	AddToTree(#string);
192
	tok=tok0; number=number0;src=src0;type=type0;post=post0;
193
	_lclose(dll);
194
	DLLcount++; importFlag=0;
195
}
196
 
197
// ----- Директива #include
198
DirInclude()
199
byte s[STRLEN],s2[STRLEN];
200
{
201
	NextTok();
202
	if(tok==tk_string) {
203
		AL=cha2;
204
		$PUSH EAX,linenum2,inptr2,number,tok2,tok,input,inptr,endoffile,
205
				displaytokerrors,currmod;
206
		lstrcpyA(#s,#string); lstrcpyA(#s2,#string2);
207
		Preview(#s);
208
		lstrcpyA(#string,#s); lstrcpyA(#string2,#s2);
209
		$POP currmod,displaytokerrors,endoffile,inptr,input,tok,tok2,number,inptr2,
210
			linenum2,EAX;
211
		cha2=AL;
212
		NextTok();
213
	}
214
	ELSE stringexpected();
215
}
216
 
217
// ----- Директива list
218
DirList()
219
{
220
	IF(mapfile==0){
221
		makemapfile=1;
222
		StartMapfile();
223
	}
224
	list^=1;		// Переключение вывода листинга
225
	NextTok();
226
}
227
 
228
// ----- Директива map
229
DirMap()
230
{
231
	makemapfile = 1; StartMapfile();
232
	NextTok();
233
}
234
 
235
// ---- Обработка глобальной переменной или процедуры с типом
236
GetProc(dword vartype)
237
dword src0,beg,count;
238
byte var_name[IDLENGTH];
239
{
240
	lstrcpyA(#var_name,#string);	// Имя процедуры
241
	beg=inptr2; 	// отметим начало описания
242
	count=0; EAX=0; 	// ищем начало блока процедуры
243
	modline=currmod<<16+linenum2;
244
	for(;;){
245
		ESI>
246
		$LODSB;
247
		ESI>
248
		cha2=AL;
249
		IF(AL==0){
250
			unexpectedeof();
251
			return;
252
		}
253
		IF(AL==13){ 	// CR
254
			linenum2++; // Обнаружен конец строки
255
			totallines++;
256
			CONTINUE;
257
		}
258
		IF(AL=='{'){	// список инициализации
259
			count++;
260
			BREAK;
261
		}
262
	}
263
	for(;;){
264
		ESI>
265
		$LODSB;
266
		ESI>
267
		cha2=AL;
268
		IF(AL==0){
269
			unexpectedeof();
270
			break;
271
		}
272
		IF(AL==13){ 	// CR
273
			linenum2++; // Обнаружен конец строки
274
			totallines++;
275
		}
276
		else if(AL=='}'){	// блок закрыт
277
			count--;
278
			IF(count==0){ // конец процедуры
279
				ESI>
280
				$LODSB;
281
				ESI>
282
				cha2=AL;	// замыкающая }
283
				src0=LocalAlloc(0x40,inptr2-beg+2); // копируем исх.текст
284
				EAX=src0;
285
				DSBYTE[EAX]='(';
286
				lstrcpynA(src0+1,beg,inptr2-beg);
287
				tok=tk_proc;
288
				type=vartype;
289
				src=src0;
290
				number=0;
291
				post=1;
292
				AddToTree(#var_name);
293
				BREAK;
294
			}
295
		}
296
		ELSE IF(AL=='{'){	// список инициализации
297
			count++;
298
		}
299
	}
300
	NextTok();
301
}
302
 
303
// ---- Обработка глобальной переменной или процедуры с типом
304
GetVar(dword vartype)
305
dword src0,beg,end,count,size;
306
byte var_name[IDLENGTH];
307
{
308
	beg=inptr;
309
	modline=0;		// отметим начало описания
310
	NextTok();
311
	IF(tok2==tk_openbracket){ // Объявление функции: type FunctionName(...)
312
		GetProc(vartype);
313
		return;
314
	}
315
	for(;;){		// Объявление переменной
316
		IF(tok==tk_semicolon){	// Конец определения переменной
317
			tok=tk_var;
318
			type=vartype;
319
			src=src0;
320
			number=0;
321
			post=1;
322
			AddToTree(#var_name);
323
			break;
324
		}
325
		IF(tok==tk_comma){		// список переменных
326
			tok=tk_var;
327
			type=vartype;
328
			src=src0;
329
			number=0;
330
			post=1;
331
			AddToTree(#var_name);
332
			NextTok();
333
		}
334
		else IF(tok==tk_id){ 			//	tk_id
335
			src0=NULL;
336
			beg=inptr2;
337
			size=0;
338
			lstrcpyA(#var_name,#string);	// Имя переменной
339
			number=0;
340
			tok=tk_var;
341
			type=vartype;
342
			post=1;
343
			NextTok();
344
		}
345
		else if(tok==tk_assign)||(tok==tk_openblock){
346
			inptr2--;
347
			count=0;
348
			EAX=0;
349
			for(;;){
350
				ESI>
351
				$LODSB;
352
				ESI>
353
				cha2=AL;
354
				IF(AL==0){
355
					unexpectedeof();
356
					break;
357
				}
358
				IF(AL=='"'){
359
					ESI>
360
					do{
361
						$LODSB;
362
					}while(AL!='"');
363
					ESI>
364
					cha2=AL;
365
				}
366
				else IF(AL==',')||(AL==';'){
367
					IF(count==0){
368
						end=inptr2;
369
						src0 = LocalAlloc(0x40,end-beg+2);
370
						IF(size){
371
							EAX=src0;
372
							DSBYTE[EAX]='[';
373
							lstrcpynA(src0+1,beg,end-beg);
374
						}
375
						ELSE lstrcpynA(src0,beg,end-beg);
376
						modline=currmod<<16+linenumber;
377
						BREAK;
378
					}
379
				}
380
				ELSE IF(AL=='}'){	// список закончен
381
					count--;
382
				}
383
				ELSE IF(AL=='{'){	// список инициализации
384
					count++;
385
				}
386
				IF(AL==']'){	// размерность
387
					size++;
388
				}
389
			}
390
			NextTok();
391
		}
392
	}
393
	NextTok();
394
}
395
 
396
// ---- Объявление типа данных
397
CmdByte()
398
{
399
	GetVar(tk_byte);
400
}
401
 
402
CmdChar()
403
{
404
	GetVar(tk_char);
405
}
406
 
407
CmdWord()
408
{
409
	GetVar(tk_word);
410
}
411
 
412
CmdShort()
413
{
414
	GetVar(tk_short);
415
}
416
 
417
CmdDword()
418
{
419
	GetVar(tk_dword);
420
}
421
 
422
CmdInt()
423
{
424
	GetVar(tk_int);
425
}
426
 
427
// ----  break;
428
CmdBreak()
429
{
430
	wsprintfA(#mapstr,"jmp @L%d",endlabel);
431
	Asm(#mapstr);
432
	NextSemiNext();
433
}
434
 
435
// ---- case(Cond) ...
436
CmdCase()
437
dword loclabel;
438
{
439
	NextTok();
440
	expecting(tk_openbracket);
441
	loclabel=label;
442
	label++;
443
	relation=0;
444
	if(tok==tk_command){
445
		GetDirAddr(#Jmp_Commands,number);
446
		IF(EAX==#CmdCarryFlag)wsprintfA(#mapstr,"jnc @L%d",loclabel);
447
		else IF(EAX==#CmdNotCarryFlag)wsprintfA(#mapstr,"jc @L%d",loclabel);
448
		ELSE IF(EAX==#CmdZeroFlag)wsprintfA(#mapstr,"jnz @L%d",loclabel);
449
		ELSE IF(EAX==#CmdNotZeroFlag)wsprintfA(#mapstr,"jz @L%d",loclabel);
450
		ELSE IF(EAX==#CmdOverflow)wsprintfA(#mapstr,"jno @L%d",loclabel);
451
		ELSE IF(EAX==#CmdNotOverflow)wsprintfA(#mapstr,"jo @L%d",loclabel);
452
		NextTok();
453
	}
454
	ELSE{
455
		IF(Expression("eax",tk_reg,tk_dword))wsprintfA(loclabel,"test eax,eax;jnz @L%d",#mapstr);
456
		ELSE wsprintfA(#mapstr,"test eax,eax;jz @L%d",loclabel);
457
	}
458
	Asm(#mapstr);
459
	expecting(tk_closebracket);
460
	DoCommand();
461
	wsprintfA(#mapstr,"jmp @L%d",endlabel);
462
	Asm(#mapstr);
463
	wsprintfA(#mapstr,"@L%d:",loclabel);
464
	Asm(#mapstr);
465
}
466
 
467
// ---- continue;
468
CmdContinue()
469
{
470
	wsprintfA(#mapstr,"jmp @L%d",startlabel);
471
	Asm(#mapstr); NextSemiNext();
472
}
473
 
474
// ---- cycle(Var) ...
475
CmdCycle()
476
byte varName[2*IDLENGTH];
477
{
478
	NextTok();
479
	expecting(tk_openbracket);
480
	$PUSH startlabel,endlabel;
481
	startlabel=label;
482
	label++;
483
	endlabel=label;
484
	label++;
485
	relation=0;
486
	wsprintfA(#mapstr,"@L%d:",startlabel);
487
	Asm(#mapstr);
488
	GetVarname(#varName);
489
	NextTok();
490
	expecting(tk_closebracket);
491
	DoCommand();
492
	IF(varName[0]==0){	// Счетчик цикла отсутствует - бесконечный цикл
493
		wsprintfA(#mapstr,"jmp @L%d",startlabel);
494
	}
495
	 ELSE{
496
		wsprintfA(#mapstr,"dec %s;jnz @L%d",#varName,startlabel);
497
	}
498
	Asm(#mapstr);
499
	wsprintfA(#mapstr,"@L%d:",endlabel);
500
	Asm(#mapstr);
501
	$POP endlabel,startlabel;
502
}
503
 
504
// ---- Флаги условий в if
505
CmdCarryFlag()
506
{
507
	CmdNotCarryFlag:
508
	CmdZeroFlag:
509
	CmdNotZeroFlag:
510
	CmdOverflow:
511
	CmdNotOverflow:
512
}
513
// ---- ... else ...
514
CmdElse()
515
{
516
}
517
 
518
// ---- Объявление нумерованных констант
519
CmdEnum()
520
dword counter;
521
byte holdid[IDLENGTH];
522
{
523
	counter=0;
524
	NextTok();
525
	expecting(tk_openbrace);
526
	for(;;){
527
		IF(tok==tk_eof)unexpectedeof();
528
		ELSE IF(tok==tk_comma)NextTok();
529
		ELSE IF(tok==tk_closebrace)BREAK;
530
		ELSE IF(tok==tk_id){
531
			lstrcpyA(#holdid,#string);
532
			IF(tok2==tk_assign ){
533
				NextTok();
534
				NextTok();
535
				IF(tok==tk_number)counter=DoConstLongMath();
536
				ELSE numexpected();
537
			}
538
			AddConstToTree(#holdid,counter);
539
			counter++;
540
			NextTok();
541
		}
542
		ELSE{
543
			idexpected();
544
			NextTok();
545
		}
546
	}
547
	expecting(tk_closebrace);
548
	SemiNext();
549
}
550
 
551
// ---- while(Cond) ...
552
CmdWhile()
553
{
554
	NextTok();
555
	expecting(tk_openbracket);
556
	$PUSH startlabel,endlabel;
557
	startlabel=label;
558
	label++;
559
	endlabel=label;
560
	label++;
561
	relation=0;
562
	wsprintfA(#mapstr,"@L%d:",startlabel);
563
	Asm(#mapstr);
564
	if(tok==tk_command){
565
		GetDirAddr(#Jmp_Commands,number);
566
		IF(EAX==#CmdCarryFlag)wsprintfA(#mapstr,"jnc @L%d",endlabel);
567
		else IF(EAX==#CmdNotCarryFlag)wsprintfA(#mapstr,"jc @L%d",endlabel);
568
		else IF(EAX==#CmdZeroFlag)wsprintfA(#mapstr,"jnz @L%d",endlabel);
569
		ELSE IF(EAX==#CmdNotZeroFlag)wsprintfA(#mapstr,"jz @L%d",endlabel);
570
		ELSE IF(EAX==#CmdOverflow)wsprintfA(#mapstr,"jno @L%d",endlabel);
571
		ELSE IF(EAX==#CmdNotOverflow)wsprintfA(#mapstr,"jo @L%d",endlabel);
572
		NextTok();
573
	}
574
	ELSE{
575
		IF(Expression("eax",tk_reg,tk_dword))wsprintfA(#mapstr,"test eax,eax;jnz @L%d",endlabel);
576
		ELSE wsprintfA(#mapstr,"test eax,eax;jz @L%d",endlabel);
577
	}
578
	Asm(#mapstr);
579
	expecting(tk_closebracket);
580
	DoCommand();
581
	wsprintfA(#mapstr,"jmp @L%d",startlabel);
582
	Asm(#mapstr);
583
	wsprintfA(#mapstr,"@L%d:",endlabel);
584
	Asm(#mapstr);
585
	$POP endlabel,startlabel;
586
}
587
 
588
// ---- default
589
CmdDefault()
590
{
591
	NextTok();
592
	DoCommand();
593
}
594
 
595
CmdDb()
596
{
597
	NextTok();
598
	for(;;){
599
		IF(tok==tk_number)OP(byte DoConstLongMath());
600
		ELSE IF(tok==tk_string ){
601
			ECX=number;
602
			EDX=#string;
603
			loop(ECX){
604
				OP(byte DSBYTE[EDX]);
605
				EDX++;
606
			}
607
			NextTok();
608
		}
609
		ELSE IF(tok==tk_comma)NextTok();
610
		ELSE IF(tok==tk_semicolon)BREAK;
611
		ELSE{
612
			numexpected();
613
			NextTok();
614
		}
615
	}
616
}
617
 
618
CmdDd()
619
{
620
	NextTok();
621
	for(;;){
622
		IF(tok==tk_number)OUTDWORD(DoConstDwordMath());
623
		ELSE IF(tok==tk_comma)NextTok();
624
		ELSE IF(tok==tk_semicolon)BREAK;
625
		ELSE{
626
			numexpected();
627
			NextTok();
628
		}
629
	}
630
}
631
 
632
CmdDw()
633
{
634
	NextTok();
635
	for(;;){
636
		IF(tok==tk_number)OUTWORD(DoConstDwordMath());
637
		ELSE IF(tok==tk_comma)NextTok();
638
		ELSE IF(tok==tk_semicolon)BREAK;
639
		ELSE{
640
			numexpected();
641
			NextTok();
642
		}
643
	}
644
}
645
 
646
// ---- do ... while(Cond)
647
CmdDo()
648
{
649
	NextTok();
650
	$PUSH startlabel,endlabel;
651
	startlabel=label;
652
	label++;
653
	endlabel=label;
654
	label++;
655
	relation=0;
656
	wsprintfA(#mapstr,"@L%d:",startlabel);
657
	Asm(#mapstr);
658
	DoCommand();
659
	if(tok==tk_command){
660
		if(GetDirAddr(#Jmp_Commands,number)==#CmdWhile){
661
			NextTok();
662
			expecting(tk_openbracket);
663
			if(tok==tk_command){
664
				GetDirAddr(#Jmp_Commands,number);
665
				IF(EAX==#CmdCarryFlag)wsprintfA(#mapstr,"jc @L%d",startlabel);
666
				else IF(EAX==#CmdNotCarryFlag)wsprintfA(#mapstr,"jnc @L%d",startlabel);
667
				else IF(EAX==#CmdZeroFlag)wsprintfA(#mapstr,"jz @L%d",startlabel);
668
				ELSE IF(EAX==#CmdNotZeroFlag)wsprintfA(#mapstr,"jnz @L%d",startlabel);
669
				ELSE IF(EAX==#CmdOverflow)wsprintfA(#mapstr,"jo @L%d",startlabel);
670
				ELSE IF(EAX==#CmdNotOverflow)wsprintfA(#mapstr,"jno @L%d",startlabel);
671
				NextTok();
672
			}
673
			ELSE{
674
				IF(Expression("eax",tk_reg,tk_dword))wsprintfA(#mapstr,"test eax,eax;jz @L%d",startlabel);
675
				ELSE wsprintfA(#mapstr,"test eax,eax;jnz @L%d",startlabel);
676
			}
677
			Asm(#mapstr);
678
			expecting(tk_closebracket);
679
		}
680
		ELSE{
681
ER:
682
			preerror("'while' expected following 'do'");
683
		}
684
	}
685
	ELSE GOTO ER;
686
	wsprintfA(#mapstr,"@L%d:",endlabel);
687
	Asm(#mapstr);
688
	$POP endlabel,startlabel;
689
}
690
 
691
// ---- docase ...
692
CmdDoCase()
693
{
694
	NextTok();
695
	$PUSH startlabel,endlabel;
696
	startlabel=label;
697
	label++;
698
	endlabel=label;
699
	label++;
700
	wsprintfA(#mapstr,"@L%d:",startlabel);
701
	Asm(#mapstr);
702
	DoCommand();
703
	wsprintfA(#mapstr,"@L%d:",endlabel);
704
	Asm(#mapstr);
705
	$POP endlabel,startlabel;
706
}
707
 
708
// ---- if(Cond) ...
709
CmdIf()
710
dword loclabel;
711
{
712
	NextTok();
713
	expecting(tk_openbracket);
714
	loclabel=label;
715
	label++;
716
	relation=0;
717
	if(tok==tk_command){
718
		GetDirAddr(#Jmp_Commands,number);
719
		IF(EAX==#CmdCarryFlag)wsprintfA(#mapstr,"jnc @L%d",loclabel);
720
		else IF(EAX==#CmdNotCarryFlag)wsprintfA(#mapstr,"jc @L%d",loclabel);
721
		ELSE IF(EAX==#CmdZeroFlag)wsprintfA(#mapstr,"jnz @L%d",loclabel);
722
		ELSE IF(EAX==#CmdNotZeroFlag)wsprintfA(#mapstr,"jz @L%d",loclabel);
723
		ELSE IF(EAX==#CmdOverflow)wsprintfA(#mapstr,"jno @L%d",loclabel);
724
		ELSE IF(EAX==#CmdNotOverflow)wsprintfA(#mapstr,"jo @L%d",loclabel);
725
		NextTok();
726
	}
727
	ELSE{
728
		IF(Expression("eax",tk_reg,tk_dword))wsprintfA(#mapstr,"test eax,eax;jnz @L%d",loclabel);
729
		ELSE wsprintfA(#mapstr,"test eax,eax;jz @L%d",loclabel);
730
	}
731
	Asm(#mapstr);
732
	expecting(tk_closebracket);
733
	DoCommand();
734
	IF(tok==tk_command){
735
		IF(GetDirAddr(#Jmp_Commands,number)==#CmdElse){
736
			wsprintfA(#mapstr,"jmp @L%d;\n@L%d:",label,loclabel);
737
			Asm(#mapstr);
738
			loclabel=label;
739
			label++;
740
			NextTok();
741
			DoCommand();
742
		}
743
	}
744
	wsprintfA(#mapstr,"@L%d:",loclabel);
745
	Asm(#mapstr);
746
}
747
 
748
// ---- return(Expr)
749
CmdReturn()
750
{
751
	NextTok();
752
	IF(tok==tk_openbracket){
753
		NextTok();
754
		IF(tok!=tk_closebracket){
755
			IF(returntype!=tk_void)Expression("eax",tk_reg,returntype);
756
		}
757
		expecting(tk_closebracket);
758
	}
759
	LeaveProc();
760
	SemiNext();
761
}
762
 
763
// ---- Объявление глобальной переменной
764
GlobalVar(dword vartype)	// both initialized and unitialized combined
765
dword size,elements,ptr;
766
long i,count;
767
{
768
	ptr=treeptr;
769
	elements=1;
770
	size = TypeSize(vartype);
771
	NextTok();
772
	for(;;){
773
		IF(tok==tk_eof)goto G04;	//break;
774
		ELSE IF(tok==tk_semicolon)NextTok();
775
		else IF(tok==tk_assign)NextTok();
776
		else IF(tok==tk_plus)NextTok();
777
		else IF(tok==tk_openblock){ 	// type VarName[...]
778
			NextTok();
779
			elements = DoConstLongMath();
780
			expecting(tk_closeblock);
781
		}
782
		else if(tok==tk_number){	// type VarName=initvalue
783
			ESI=ptr;	// Откорректируем ранее сделанную запись
784
			DSDWORD[ESI+recnumber] = outptr-output+OptImageBase+OptBaseOfCode;
785
			DSDWORD[ESI+recpost] = 0;
786
G01:
787
			IF(vartype==tk_byte)i=DoConstDwordMath();
788
			ELSE IF(vartype==tk_word)i=DoConstDwordMath();
789
			ELSE IF(vartype==tk_dword)i=DoConstDwordMath();
790
			ELSE i=DoConstLongMath();
791
			count=elements;
792
			loop(count){
793
				IF(size==1)OP(byte i);
794
				ELSE IF(size==2)OUTWORD(i);
795
				ELSE IF(size==4)OUTDWORD(i);
796
			}
797
		}
798
		else IF(tok==tk_minus){
799
			NextTok();
800
			number=-number;
801
			goto G01;
802
		}
803
		else IF(tok==tk_string){
804
			ESI=ptr;	// Откорректируем ранее сделанную запись
805
			DSDWORD[ESI+recnumber] = outptr-output+OptImageBase+OptBaseOfCode;
806
			DSDWORD[ESI+recpost] = 0;
807
			count = 1;
808
			do{
809
				i=number;
810
				EDX=#string;
811
				loop(i){
812
					OP(byte DSBYTE[EDX]);
813
					EDX++;
814
					count++;
815
				}
816
				NextTok();
817
			}while(tok==tk_string);
818
			OP(byte 0);// count++;
819
			i=elements;
820
			i-=count;
821
			IF(i>0)loop(i)OP(byte 0);
822
		}
823
		else IF(tok==tk_from){
824
			NextTok();
1848 yogev_ezra 825
			WRITESTR("count = DoFrom(1);\n");
1846 yogev_ezra 826
			i=size*elements;
827
			i-=count;
828
			loop(i)OP(byte 0);
829
			NextTok();
830
		}
831
		else IF(tok==tk_extract){
832
			NextTok();
1848 yogev_ezra 833
			WRITESTR("count = DoExtract(1);\n");
1846 yogev_ezra 834
			i=size*elements;
835
			i-=count;
836
			loop(i)OP(byte 0);
837
		}
838
		else if(tok==tk_openbrace){ // varname={...};
839
			ESI=ptr;	// Откорректируем ранее сделанную запись
840
			DSDWORD[ESI+recnumber] = outptr-output+OptImageBase+OptBaseOfCode;
841
			DSDWORD[ESI+recpost] = 0;
842
			count = 0;
843
			NextTok();
844
			for(;;){
845
				IF(tok==tk_closebrace)break;
846
				ELSE IF(tok==tk_comma)NextTok();
847
				else IF(tok==tk_plus)NextTok();
848
				else IF(tok==tk_string){
849
					i=number;
850
					EDX=#string;
851
					loop(i){
852
						OP(DSBYTE[EDX]);
853
						EDX++;
854
						count++;
855
					}
856
					IF(tok2!=tk_plus){
857
						OP(byte 0);
858
						count++;
859
					}
860
					NextTok();
861
				}
862
				else IF(tok==tk_postnumber){
863
					SetPost(treeptr,POST_DATA);
864
					OUTDWORD(number);
865
					NextTok();
866
				}
867
				else IF(tok==tk_number){
868
G02:
869
					IF(vartype==tk_byte)OP(byte DoConstDwordMath());
870
					ELSE IF(vartype==tk_word)OUTWORD(DoConstDwordMath());
871
					ELSE IF(vartype==tk_char)OP(byte DoConstLongMath());
872
					ELSE IF(vartype==tk_short) OUTWORD(DoConstLongMath());
873
					ELSE IF(vartype==tk_dword) OUTDWORD(DoConstDwordMath());
874
					ELSE IF(vartype==tk_int) OUTDWORD(DoConstLongMath());
875
					count++;
876
				}
877
				ELSE IF(tok==tk_minus){
878
					NextTok();
879
					number=-number;
880
					goto G02;
881
				}
882
				ELSE{
883
					numexpected();
884
					NextTok();
885
				}
886
			}
887
			count=elements-count;
888
			IF(count>0){
889
				loop(count){
890
					IF(size==1)OP(byte 0);
891
					ELSE IF(size==2)OUTWORD(0);
892
					ELSE IF(size==4)OUTDWORD(0);
893
				}
894
			}
895
		}
896
		ELSE{
897
G04:
898
			ESI=ptr;
899
			DSDWORD[ESI+recnumber] = postsize;
900
			DSDWORD[ESI+recpost] = 1;
901
			postsize = elements * size + postsize;
902
			BREAK;
903
		}
904
	}
905
}
906
 
907
//===== Таблица переключателей директив
908
dword Jmp_Directives={
909
//	"if","else","endif",	// Условная компиляция
910
	#EMPTY,#EMPTY,#EMPTY,
911
//	"include","define", // Включение фа ла
912
	#DirInclude,#DirDefine,
913
//	"import", 	// Импорт из DLL
914
	#DirImport,
915
//	"importN",		// Импорт из DLL
916
	#DirImportN,
917
//	"map",			// Генерация MAP-файла
918
	#DirMap,
919
//	"debug",		// Генерация отладочной информации
920
	#EMPTY,
921
//	"list", 		// Выдача ASM-листинга
922
	#DirList,
923
//	"dll",			// Генерация DLL-файла
924
	#EMPTY,
925
//	"db","dw","dd", 	// Типы переменных
926
	#EMPTY,#EMPTY,#EMPTY,
927
//	"byte","char","word","short","dword","int",
928
	#EMPTY,#EMPTY,#EMPTY,#EMPTY,#EMPTY,#EMPTY,
929
//	"enum", 		// Нумерованные константы
930
	#DirEnum,
931
//	"struc",		// Определение структуры
932
	#EMPTY,
933
//	"cycle","return",
934
	#EMPTY,#EMPTY,
935
//	"while","do","inline",
936
	#EMPTY,#EMPTY,#EMPTY,
937
//	"continue","break",
938
	#EMPTY,#EMPTY,
939
//	"docase","case","default",
940
	#EMPTY,#EMPTY,#EMPTY,
941
//	"CARRYFLAG","extract","from",
942
	#EMPTY,#EMPTY,#EMPTY,
943
//	"NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW",
944
	#EMPTY,#EMPTY,#EMPTY,
945
//	"ZEROFLAG","NOTZEROFLAG"
946
	#EMPTY,#EMPTY
947
};
948
//===== Таблица переключателей команд
949
dword Jmp_Commands={
950
//	"if","else","endif",	// Условная компиляция
951
	#CmdIf,#CmdElse,#EMPTY,
952
//	"include","define", // Включение фа ла
953
	#EMPTY,#EMPTY,
954
//	"import","importN", // Импорт из DLL
955
	#EMPTY,#EMPTY,
956
//	"map",			// Генерация MAP-файла
957
	#EMPTY,
958
//	"debug",		// Генерация отладочно	информации
959
	#EMPTY,
960
//	"list", 		// Выдача ASM-л стинга
961
	#EMPTY,
962
//	"dll",			// Генерация DLL-файла
963
	#EMPTY,
964
//	"db","dw","dd", 	// Типы переменных
965
	#CmdDb,#CmdDw,#CmdDd,
966
//	"byte","char","word","short","dword","int",
967
	#CmdByte,#CmdChar,#CmdWord,#CmdShort,#CmdDword,#CmdInt,
968
//	"enum", 		// Нумерованные константы
969
	#CmdEnum,
970
//	"struc",		// Определение структуры
971
	#EMPTY,
972
//	"cycle","return",
973
	#CmdCycle,#CmdReturn,
974
//	"while","do","inline",
975
	#CmdWhile,#CmdDo,#EMPTY,
976
//	"continue","break",
977
	#CmdContinue,#CmdBreak,
978
//	"docase","case","default",
979
	#CmdDoCase,#CmdCase,#CmdDefault,
980
//	"CARRYFLAG","extract","from",
981
	#CmdCarryFlag,#EMPTY,#EMPTY,
982
//	"NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW",
983
	#CmdNotCarryFlag,#CmdNotOverflow,#CmdOverflow,
984
//	"ZEROFLAG","NOTZEROFLAG"
985
	#CmdZeroFlag,#CmdNotZeroFlag
986
};