Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1846 yogev_ezra 1
// ---- Преобразование текущего символа для констукций типа: \n, \x00,	 т.п.
2
byte ConvertChar()
3
dword hold;
4
{
5
	IF(cha!='\\')return(cha);
6
	NextChar(); // Обработка следующего за \
7
	IF(AL>='0')&&(AL<='9'){
8
// Десятичная константа
9
		EDX=0;
10
		AL-='0';
11
		EAX=AL;
12
		EDX+=EAX;
13
		ECX=2;
14
		loop(ECX){
15
			EBX=EDX;
16
			EDX<<=1;
17
			EBX<<=3;
18
			EDX+=EBX;
19
			NextChar();
20
			EAX=AL;
21
			IF(AL<'0')||(AL>'9')GOTO ERR;
22
			AL-='0';
23
			EDX+=EAX;
24
		}
25
		return(DL);
26
ERR:
27
		expectederror("decimal digit");
28
		return(0);
29
	}
30
	IF(cha=='a')return('\a');
31
	IF(cha=='b')	return('\b');
32
	IF(cha=='f')	return('\f');
33
	IF(cha=='l')	return(10);
34
	IF(cha=='n')	return(13);
35
	IF(cha=='p')	return('_');
36
	IF(cha=='r')	return(13);
37
	IF(cha=='t')	return('\t');
38
	IF(cha=='v')	return('\v');
39
	IF(cha=='x'){ // HEX константа
40
		ECX=2;
41
		hold=0;
42
		loop(ECX){
43
			$PUSH ECX;
44
			NextChar();
45
			CharUpperA(AL);
46
			EBX=AL;
47
			IF(AL>='0')&&(AL<='9')GOTO LX1;
48
			IF(AL<'A')&&(AL>'F')GOTO ERR1;
49
LX1:
50
			EDX=hold;
51
			EDX<<=4;
52
			IF(BL>='A')BL-='A'-10-'0';
53
			BL-='0';
54
			EDX+=EBX;
55
			hold=EDX;
56
			$POP ECX;
57
		}
58
		return(hold);
59
ERR1:
60
		$POP ECX;
61
		expectederror("hexdecimal digit");
62
		return(0);
63
	}
64
	return(cha);
65
}
66
 
67
// ---- Разделители
68
byte Delim1={'#','\"','\'','-','+','*','/','%','|','&','!','^','=','>','<','@',0};
69
byte Delim2={':',';','(',')','{','}','[',']',',','.','$','?','~',0};
70
// ---- Определение типа token
71
TokScan(dword tok4,type4,src4,post4,string4,number4)
72
dword useme,strptr;
73
dword next;
74
dword dirPrefix,locPrefix;// Флаги обнаружения #directive или @LocalLabel
75
{
76
	dirPrefix=0;
77
	locPrefix=0;
78
SC_0:
79
	strptr=string4;
80
	next=1;
81
	EAX=number4;
82
	DSDWORD[EAX] = 0;
83
	EAX=type4;
84
	DSDWORD[EAX] = 0;
85
	EAX=src4;
86
	DSDWORD[EAX] = 0;
87
	EAX=post4;
88
	DSDWORD[EAX] = 0;
89
	WhiteSpaces();
90
	ESI=string4;
91
	DSBYTE[ESI]=0;
92
	ECX=17;
93
	EDI=#Delim1;
94
	AL=cha;
95
	$REPNZ $SCASB;
96
	$JCXZ SC00	// Не первая группа разделителе
97
	EDI=EDI-#Delim1-1<<2+#Jmp_Delim1;
98
	$JMP NEAR DSDWORD[EDI];
99
SC00:
100
	ECX=14;
101
	EDI=#Delim2;
102
	AL=cha;
103
	$REPNZ $SCASB;
104
	$JCXZ SC01	// Не вторая группа разделителе
105
	EDI=EDI-#Delim2-1+#tk_delim2;
106
	EAX=DSBYTE[EDI];
107
	EBX=tok4;
108
	DSDWORD[EBX]=EAX;
109
	$JMP ScEx
110
SC01:
111
	IF(locPrefix){
112
		EDI>
113
		AL='@';
114
		$STOSB;
115
		strptr>
116
	}
117
	IF(cha==0){ 	// Конец входного буфера
118
		EAX=tok4;
119
		DSDWORD[EAX]=tk_eof;
120
		next=0;
121
	}
122
	else if(IsCharAlphaA(cha))||(cha=='_'){ // Идентификатор начинается с буквы
123
		do{
124
			do{ // Копируем идентификатор в string4
125
UP:
126
				EDI>
127
				AL=cha;
128
				$STOSB;
129
				strptr>
130
				NextChar();
131
			}while(IsCharAlphaNumericA(cha));
132
		}while(cha=='_');
133
		EAX=strptr-string4;
134
		IF(EAX>=IDLENGTH){
135
			preerror("Maximum length for an identifier exceeded");
136
			strptr = string4 + IDLENGTH - 1;
137
		}
138
		EDI=strptr;
139
		AL=0;
140
		$STOSB
141
		EBX=tok4;
142
		DSDWORD[EBX]=tk_id;
143
		IF(locPrefix)goto FL;
144
		FastSearch(string4,#St_Directives); // Это зарезервированное слово?
145
		IF(CARRYFLAG){	// Команда обнаружена в списке
146
			EBX=number4; DSDWORD[EBX]=EAX;	// Запомним порядковый номер
147
			EBX=tok4; 	// Укажем соответствующий token
148
			IF(dirPrefix)DSDWORD[EBX]=tk_directive;
149
			ELSE DSDWORD[EBX]=tk_command;
150
			dirPrefix=0;
151
			next=0;
152
			$JMP ScEx
153
		}
154
		FastSearch(string4,#St_Mnemonics);	// Это мнемоника?
155
		IF(CARRYFLAG){	// Мнемоника ассемблера
156
			EBX=number4;
157
			DSDWORD[EBX]=EAX; // Запомним номер мнемоники
158
			EBX=tok4;
159
			DSDWORD[EBX]=tk_mnemonics;
160
			next=0;
161
			$JMP ScEx
162
		}
163
		FastSearch(string4,#St_Registers);	// Это имя регистра?
164
		IF(CARRYFLAG){	// Регистр
165
			EBX=number4;
166
			DSDWORD[EBX]=EAX; // Запомним номер региста
167
			EAX>>=3;
168
			$CMP EAX,2;
169
			$JG R0		// Управляющие регистры?
170
			EBX=tok4;
171
			DSDWORD[EBX]=tk_reg;
172
			EBX=type4;
173
			EAX<<=1;
174
			DSDWORD[EBX] = EAX + tk_byte;
175
			GOTO R1;
176
R0:
177
			EBX=tok4;
178
			EAX-=3;
179
			DSDWORD[EBX]=EAX+tk_controlreg;
180
R1:
181
			next=0;
182
			$JMP ScEx
183
		}
184
FL:
185
		EAX=tok4;
186
		EAX=DSDWORD[EAX];
187
		IF(AL==tk_id){
188
			SearchLocals(tok4,type4,string4,number4); // Есть в списке локальных?
189
			EAX=tok4;
190
			EAX=DSDWORD[EAX];
191
			IF(AL==tk_id){
192
				IF(locPrefix){	// @label
193
					EBX=tok4;
194
					DSDWORD[EBX]=tk_locallabel;
195
					IF(displaytokerrors)AddLocalvar(#string,tk_locallabel,0,0);
196
					locPrefix=0;
197
					GOTO FL;
198
				}
199
				SearchTree(tok4,type4,src4,post4,string4,number4);
200
			}
201
		}
202
		IF(dirPrefix){	// Конструкция: #ident
203
			dirPrefix=0;
204
			EBX=tok4;
205
			EAX=DSDWORD[EBX];
206
			IF(AL==tk_id){	// Есть в списке?
207
				IF(displaytokerrors){
208
					EAX=post4;
209
					DSDWORD[EAX]	= 1;	// Добавим в список
210
					EBX=tok4;
211
					DSDWORD[EBX]=tk_undefproc;
212
					AddToTree(string4);
213
				}
214
			}
215
				// Идентификатор есть в списке
216
			EAX=post4;
217
			EAX=DSDWORD[EAX];
218
			EBX=tok4;
219
			IF(EAX){	// Еще не обработанный идентификатор?
220
				DSDWORD[EBX] = tk_postnumber;
221
			}
222
			ELSE{
223
				EAX=tok4;
224
				EAX=DSDWORD[EAX];
225
				IF(EAX==tk_param)DSDWORD[EBX] = tk_locnumber;
226
				ELSE IF(EAX==tk_local)DSDWORD[EBX] = tk_locnumber;
227
				ELSE DSDWORD[EBX] = tk_number;
228
			}
229
		}
230
		next=0;
231
		$JMP ScEx
232
	}
233
	else if(IsNumber(cha)){ // Идентификатор начинается с цифры
234
		EAX=tok4;
235
		DSDWORD[EAX]=tokens;	// Пока неизвестный token
236
		if(cha=='0'){
237
			NextChar();
238
			IF(cha=='X')||(cha=='x'){		// hex - число
239
				EAX=tok4;
240
				DSDWORD[EAX]=tk_number;
241
HEX:
242
				NextChar();
243
				CharUpperA(AL);
244
				$CMP AL,'0';
245
				$JL EHEX;
246
				$CMP AL,'9';
247
				$JA HEXAF
248
				AL-='0';
249
				for(;;){
250
					EBX=number4;
251
					ECX=DSDWORD[EBX];
252
					ECX<<=4;
253
					EAX+=ECX;
254
					DSDWORD[EBX]=EAX;
255
					GOTO	HEX;
256
HEXAF:
257
					IF(AL<'A')||(AL>'F')BREAK;
258
					AL-='7';
259
				}
260
EHEX:
261
			}
262
			ELSE IF(cha=='B')||(cha=='b'){		// binary число
263
				EAX=tok4;
264
				DSDWORD[EAX]=tk_number;
265
				for(;;){
266
					NextChar();
267
					IF(AL!='0')||(AL!='1')BREAK;
268
					AL-='0';
269
					EBX=number4;
270
					ECX=DSDWORD[EBX];
271
					ECX<<=1;
272
					EAX+=ECX;
273
					DSDWORD[EBX]=EAX;
274
				}
275
EBIN:
276
			}
277
			ELSE IF(cha=='O')||(cha=='o'){		// octal число
278
				EAX=tok4;
279
				DSDWORD[EAX]=tk_number;
280
				for(;;){
281
					NextChar();
282
					IF(AL<'0')||(AL>'7')BREAK;
283
					AL-='0';
284
					EBX=number4;
285
					ECX=DSDWORD[EBX];
286
					ECX<<=3;
287
					EAX+=ECX;
288
					DSDWORD[EBX]=EAX;
289
				}
290
EOCT:
291
			}
292
		}
293
		EAX=tok4;
294
		EAX=DSDWORD[EAX];
295
		IF(EAX!=tk_number){ 	// decimal число
296
			for(;;){
297
				EAX=cha;
298
				IF(AL<'0')||(AL>'9')BREAK;
299
				AL-='0';
300
				EBX=number4;
301
				EDX=DSDWORD[EBX];
302
				ECX=EDX;
303
				EDX<<=1;
304
				ECX<<=3;
305
				EDX+=ECX;
306
				EAX+=EDX;
307
				DSDWORD[EBX]=EAX;
308
				NextChar();
309
			}
310
			EAX=tok4;
311
			DSDWORD[EAX]=tk_number;
312
		}
313
		next=0;
314
	}
315
	ELSE{
316
		IF(displaytokerrors)preerror("tokenizer: bad character value");
317
		NextChar();
318
		TokScan(tok4,type4,src4,post4,string4,number4);
319
		next=0;
320
	}
321
	$JMP ScEx
322
Jmp_Number: 	// #directive || #identifier
323
	NextChar();
324
	dirPrefix=1;
325
	$JMP SC_0
326
Jmp_Local:		// @LocalLabel
327
	NextChar();
328
	locPrefix=1;
329
	$JMP SC01
330
Jmp_String: 	// Строка символов в ""
331
	do{
332
		NextChar();
333
		IF(cha=='\"') // Закрывающая кавычка
334
			BREAK;
335
		EAX=strptr-string4;
336
		IF(EAX
337
			AL=ConvertChar();
338
			EDI=strptr;
339
			$STOSB;
340
			IF(AL==13)&&(cha=='n'){
341
				AL=10;
342
				$STOSB
343
			} // Добавим char 10 для \n
344
			strptr=EDI;
345
		}
346
		ELSE{
347
			IF(displaytokerrors)preerror("Maximum String Length Exceeded");
348
			WHILE(cha!='\"'){  // Поиск закрывающей кавычки
349
				IF(endoffile)BREAK;
350
				NextChar();
351
			}
352
			BREAK;
353
		}
354
	}while(cha==0);
355
	EDI=strptr;
356
	DSBYTE[EDI]=0;
357
	EDI-=string4;
358
	EAX=tok4;
359
	DSDWORD[EAX]=tk_string;
360
	EAX=number4;
361
	DSDWORD[EAX] =	EDI;	// Запомним длину строк
362
	IF(cha!='\"')expected('\"');
363
	$JMP	ScEx
364
Jmp_Const:			// Символьная константа: 'AbCD'
365
	NextChar();
366
	EAX=tok4;
367
	DSDWORD[EAX]=tk_number;
368
	EAX=number4;
369
	DSDWORD[EAX] =	0;
370
	WHILE(cha != '\''){
371
		IF(endoffile)BREAK;
372
		EAX=ConvertChar();
373
		EBX=number4;
374
		ECX=DSDWORD[EBX];
375
		ECX<<=8;
376
		EAX+=ECX;
377
		DSDWORD[EBX]=EAX;
378
		NextChar();
379
	}
380
	IF(cha != '\''){
381
		IF(displaytokerrors)
382
		expected(0x27/*'\''*/);
383
	}
384
	ELSE NextChar();
385
	next = 0;
386
	$JMP ScEx
387
Jmp_Minus:			// -
388
	NextChar();
389
	EBX=tok4;
390
	IF(cha=='=') DSDWORD[EBX]=tk_minusequals; // -=
391
	ELSE IF(cha=='-') DSDWORD[EBX]=tk_minusminus; // --
392
	ELSE{
393
		DSDWORD[EBX]=tk_minus;
394
		next = 0;
395
	} // -
396
	$JMP	ScEx
397
Jmp_Plus: 		// +
398
	NextChar();
399
	EBX=tok4;
400
	IF(cha=='=')DSDWORD[EBX]=tk_plusequals; // +=
401
	ELSE IF(cha=='+')  DSDWORD[EBX]=tk_plusplus;		// ++
402
	ELSE{
403
		WhiteSpaces();
404
		EBX=tok4; // возможно наличие пробелов
405
		IF(cha=='-')DSDWORD[EBX]=tk_minus;	// оптимизация + -
406
		ELSE{
407
			DSDWORD[EBX]=tk_plus;
408
			next = 0;
409
		}
410
	}
411
	$JMP	ScEx
412
Jmp_Mul:				// *
413
	NextChar();
414
	WhiteSpaces();
415
	EBX=tok4;
416
	IF(cha == '-')DSDWORD[EBX] = tk_multminus;	// *-
417
	ELSE{
418
		DSDWORD[EBX] = tk_mult;
419
		next=0; // *
420
	}
421
	$JMP	ScEx
422
Jmp_Div:				// /
423
	NextChar();
424
	if(cha=='*'){ // Комментарий
425
		NextChar();
426
		useme = 1;	// В useme - счетчик вложенных комментариев
427
		WHILE(useme>0){
428
			WhiteSpaces();
429
			IF( cha == '*' ){
430
				NextChar();
431
				IF(cha == '/' ){	// Закрытие комментария
432
					IF(useme > 0)useme--; // Уменишим счетчик
433
					NextChar();
434
				}
435
			}
436
			ELSE{
437
				IF( cha == '/' ){
438
					NextChar();
439
					IF( cha == '*' ){ // Вложенный комментарий
440
						useme++;
441
						NextChar();
442
					}
443
				}
444
				ELSE	// Не ограничители комментария
445
					NextChar();
446
			}
447
		}
448
		IF(endoffile){
449
			EAX=tok4;
450
			DSDWORD[EAX]=tk_eof;
451
			IF(useme > 0)&&(displaytokerrors)unexpectedeof();
452
		}
453
		ELSE TokScan(tok4,type4,src4,post4,string4,number4);
454
	}
455
	ELSE IF(cha=='/'){	// Комментарий до конца строки //
456
		do{
457
			NextChar();
458
			IF(endoffile)BREAK;
459
		} while(cha!=10 );
460
		IF(endoffile){
461
			EAX=tok4;
462
			DSDWORD[EAX]=tk_eof;
463
		}
464
		ELSE{
465
			WhiteSpaces();
466
			TokScan(tok4,type4,src4,post4,string4,number4);
467
		}
468
	}
469
	ELSE{
470
		WhiteSpaces();
471
		IF(cha=='-'){
472
			EAX=tok4; DSDWORD[EAX]=tk_divminus; // /-
473
			NextChar();
474
		}
475
		ELSE{
476
			EAX=tok4;
477
			DSDWORD[EAX]=tk_div;	// /
478
		}
479
	}
480
	next = 0;
481
	$JMP ScEx
482
Jmp_Mod:				// %
483
	NextChar();
484
	WhiteSpaces();
485
	IF(cha == '-'){
486
		EAX=tok4;
487
		DSDWORD[EAX] = tk_modminus; // %-
488
	}
489
	ELSE{
490
		EAX=tok4;
491
		DSDWORD[EAX]=tk_mod; next=0;
492
	}
493
	$JMP	ScEx
494
Jmp_Or: 				// |
495
	NextChar();
496
	IF(cha=='='){
497
		EAX=tok4;
498
		DSDWORD[EAX]=tk_orequals; // |=
499
	}
500
	ELSE IF(cha=='|'){
501
		EAX=tok4;
502
		DSDWORD[EAX]=tk_oror; 	// ||
503
	}
504
	ELSE{
505
		WhiteSpaces();
506
		IF(cha=='-'){
507
			EAX=tok4;
508
			DSDWORD[EAX]=tk_orminus;	// |-
509
		}
510
		ELSE{
511
			EAX=tok4;
512
			DSDWORD[EAX]=tk_or;
513
			next=0; // |
514
		}
515
	}
516
	$JMP	ScEx
517
Jmp_And:				// &
518
	NextChar();
519
	IF(cha=='='){
520
		EAX=tok4;
521
		DSDWORD[EAX]=tk_andequals;	// &=
522
	}
523
	ELSE IF(cha=='&'){
524
		EAX=tok4;
525
		DSDWORD[EAX]=tk_andand; // &&
526
	}
527
	ELSE{
528
		WhiteSpaces();
529
		IF(cha == '-'){
530
			EAX=tok4;
531
			DSDWORD[EAX]=tk_andminus; // &-
532
		}
533
		ELSE{
534
			EAX=tok4;
535
			DSDWORD[EAX]=tk_and;
536
			next=0;// &
537
		}
538
	}
539
	$JMP	ScEx
540
Jmp_Not:				// !
541
	NextChar();
542
	IF(cha == '='){
543
		EAX=tok4;
544
		DSDWORD[EAX]=tk_notequal; // !=
545
	}
546
	ELSE{
547
		EAX=tok4;
548
		DSDWORD[EAX]=tk_not;
549
		next=0; // !
550
	}
551
	$JMP	ScEx
552
Jmp_Xor:				// ^
553
	NextChar();
554
	IF(cha == '='){
555
		EAX=tok4;
556
		DSDWORD[EAX]=tk_xorequals;	// ^=
557
	}
558
	ELSE{
559
		WhiteSpaces();
560
		IF(cha == '-'){
561
			EAX=tok4;
562
			DSDWORD[EAX]=tk_xorminus; // ^-
563
		}
564
		ELSE{
565
			EAX=tok4;
566
			DSDWORD[EAX]=tk_xor;
567
			next=0; // ^
568
		}
569
	}
570
	$JMP	ScEx
571
Jmp_Equal:				// =
572
	NextChar();
573
	IF(cha == '='){
574
		EAX=tok4;
575
		DSDWORD[EAX]=tk_equalto;	// ==
576
	}
577
	ELSE{
578
		EAX=tok4;
579
		DSDWORD[EAX]=tk_assign;
580
		next=0; // =
581
	}
582
	$JMP	ScEx
583
Jmp_Great:				// >
584
	NextChar();
585
	IF(cha=='>'){
586
		NextChar();
587
		IF( cha == '=' ){
588
			EAX=tok4;
589
			DSDWORD[EAX]=tk_rrequals; // >>=
590
		}
591
		ELSE{
592
			WhiteSpaces();
593
			IF(cha == '-'){
594
				EAX=tok4;
595
				DSDWORD[EAX]=tk_rrminus;	// >>-
596
			}
597
			ELSE{
598
				EAX=tok4;
599
				DSDWORD[EAX]=tk_rr;
600
				next=0;// >>
601
			}
602
		}
603
	}
604
	ELSE IF(cha=='<'){
605
		EAX=tok4;
606
		DSDWORD[EAX]=tk_swap; 	// ><
607
	}
608
	ELSE IF(cha=='='){
609
		EAX=tok4;
610
		DSDWORD[EAX]=tk_greaterequal; // >=
611
	}
612
	ELSE{
613
		EAX=tok4;
614
		DSDWORD[EAX]=tk_greater;
615
		next= 0; // >
616
	}
617
	GOTO ScEx;
618
Jmp_Less: 			// <
619
	NextChar();
620
	IF(cha=='<'){
621
		NextChar();
622
		IF(cha=='='){
623
			EAX=tok4;
624
			DSDWORD[EAX]=tk_llequals; // <<=
625
		}
626
		ELSE{
627
			WhiteSpaces();
628
			IF(cha == '-'){
629
				EAX=tok4;
630
				DSDWORD[EAX]=tk_llminus;	// <<-
631
			}
632
			ELSE{
633
				EAX=tok4;
634
				DSDWORD[EAX]=tk_ll;
635
				next=0;
636
			}
637
		}
638
	}
639
	ELSE IF(cha=='>'){
640
		EAX=tok4;
641
		DSDWORD[EAX]=tk_notequal; // <>
642
	}
643
	ELSE IF(cha=='='){
644
		EAX=tok4;
645
		DSDWORD[EAX]=tk_lessequal;	// <=
646
	}
647
	ELSE{
648
		EAX=tok4;
649
		DSDWORD[EAX]=tk_less;
650
		next=0; // <
651
	}
652
ScEx:
653
	IF(next)NextChar();
654
}
655
 
656
// '#','\"','\'','-','+','*','/','%','|','&','!','^','=','>','<','@'
657
dword Jmp_Delim1={#Jmp_Number,#Jmp_String,#Jmp_Const,#Jmp_Minus,
658
#Jmp_Plus,#Jmp_Mul,#Jmp_Div,#Jmp_Mod,#Jmp_Or,#Jmp_And,
659
#Jmp_Not,#Jmp_Xor,#Jmp_Equal,#Jmp_Great,#Jmp_Less,#Jmp_Local};
660
 
661
//								':',				';',				 '(', 					 ')',
662
byte tk_delim2={tk_colon,tk_semicolon,tk_openbracket,tk_closebracket,
663
//		'{',				 '}', 				'[',					']',			 ',',
664
tk_openbrace,tk_closebrace,tk_openblock,tk_closeblock,tk_comma,
665
//'.',			'$',			'?',			 '~'
666
tk_period,tk_dollar,tk_question,tk_tilda};