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
1849 yogev_ezra 1
#define STRING_ERROR	"string found in tree when trying to add to	it"
1846 yogev_ezra 2
// ---- Занесение поименованной константы в список
3
AddConstToTree(dword keystring,constvalue)
4
dword ptr,newptr; // idrec structure
5
{
6
	newptr=LocalAlloc(0x40,recsize);
7
	IF(EAX==NULL){
8
		preerror("Compiler out of memory for identifier tree");
9
		ExitProcess(e_outofmemory);
10
	}
11
	ptr=treestart;
12
	IF(EAX == NULL ) // Пустой список?
13
	treestart = newptr;
14
	ELSE{
15
		for(;;){
16
// Поиск свободной ссылки
17
			ESI=ptr;
18
			EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
19
			ESI=ptr;
20
			IF(long EAX<0){
21
			// ptr.left
22
				IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим
23
					DSDWORD[ESI+left]=newptr;
24
					BREAK;	// ptr.left=newptr
25
				}
26
				ptr=DSDWORD[ESI+left];
27
			}
28
			ELSE IF(EAX!=0){
29
			// ptr.right
30
				IF(DSDWORD[ESI+right]==0){	// Нашли пустой правый - добавим
31
					DSDWORD[ESI+right]=newptr;
32
					BREAK;
33
				}
34
				ptr=DSDWORD[ESI+right];
35
			}
1849 yogev_ezra 36
			ELSE internalerror(STRING_ERROR);
1846 yogev_ezra 37
		}
38
	}
39
// Формируем новую запись в списке
40
	ESI=newptr;
41
	DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
42
	lstrcpyA(DSDWORD[ESI+recid],keystring);
43
	ESI=newptr;
44
	DSDWORD[ESI+newid]= NULL;
45
	DSDWORD[ESI+rectok]=tk_number;
46
	DSDWORD[ESI+recnumber]=constvalue;
47
	DSDWORD[ESI+recpost]=0;
48
	DSDWORD[ESI+left]=NULL;
49
	DSDWORD[ESI+right]=NULL;
50
	DSDWORD[ESI+recmodline] = currmod<<16+linenumber;
51
}
52
 
53
// ---- Добавить локальную переменную в список
54
AddLocalvar(dword str,tk,ltype,num)
55
dword newptr;
56
{
57
	newptr=LocalAlloc(0x40,local_size);
58
	IF(EAX==NULL){
59
		preerror("Compiler out of memory for local symbol linked list");
60
		ExitProcess(e_outofmemory);
61
	}
62
	IF(locallist==NULL)locallist = newptr;
63
	ELSE{
64
		EAX=locallist;
65
		EBX>
66
		for(;;){
67
			EAX=DSDWORD[EBX+localnext];
68
			IF(EAX==0)BREAK;
69
			EBX>
70
		}
71
		DSDWORD[EBX+localnext]=newptr;
72
	}
73
	EBX=newptr;
74
	lstrcpyA(EBX+localid,str);
75
	EBX=newptr;
76
	DSDWORD[EBX+localtok] = tk;
77
	DSDWORD[EBX+localtype] = ltype;
78
	DSDWORD[EBX+localnumber] = num;
79
	DSDWORD[EBX+localnext] = NULL;
80
	localptr=EBX;
81
}
82
 
83
// ---- Добавить идентификатор в список
84
AddToTree(dword keystring)
85
dword ptr,newptr;
86
{
87
	newptr=LocalAlloc(0x40,recsize);
88
	IF(EAX==NULL)outofmemory();
89
	ptr = treestart;
90
//WRITESTR(keystring);WRITESTR("\n");
91
	IF(EAX==NULL)treestart = newptr;
92
	ELSE{
93
		for(;;){
94
// Поиск свободной ссылки
95
			ESI=ptr;
96
			EAX=lstrcmpA(DSDWORD[ESI+recid],keystring);
97
			ESI=ptr;
98
			IF(long EAX<0){
99
			// ptr.left
100
				IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим
101
					DSDWORD[ESI+left]=newptr;
102
					BREAK;	// ptr.left=newptr
103
				}
104
				ptr=DSDWORD[ESI+left];
105
			}
106
			ELSE IF(EAX!=0){
107
				// ptr.right
108
				IF(DSDWORD[ESI+right]==0){	// Нашли пустой правый - добавим
109
					DSDWORD[ESI+right]=newptr;
110
					BREAK;
111
				}
112
				ptr=DSDWORD[ESI+right];
113
			}
1849 yogev_ezra 114
			ELSE internalerror(STRING_ERROR);
1846 yogev_ezra 115
		}
116
	}
117
	ESI=newptr;
118
	DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1);
119
	lstrcpyA(EAX,keystring);
120
	IF(tok == tk_string){
121
		ESI=newptr;
122
		DSDWORD[ESI+newid] = LocalAlloc(0x40,number+1);
123
		IF( EAX == NULL )outofmemory();
124
		ECX=number;
125
		EDI=EAX;
126
		ESI=#string;
127
		$REP $MOVSB
128
	}
129
	ELSE{
130
		IF( lstrlenA(#string) == 0 ){
131
			ESI=newptr;
132
			DSDWORD[ESI+newid]=NULL;
133
		}
134
		ELSE{
135
			ESI=newptr;
136
			DSDWORD[ESI+newid]=LocalAlloc(0x40,lstrlenA(#string)+1);
137
			IF( EAX == NULL )outofmemory();
138
			lstrcpyA(EAX,#string);
139
		}
140
	}
141
	ESI=newptr;
142
	DSDWORD[ESI+rectok] = tok;
143
	DSDWORD[ESI+recnumber] = number;
144
	DSDWORD[ESI+rectype] = type;
145
	DSDWORD[ESI+recsrc] = src;
146
	DSDWORD[ESI+recpost] = post;
147
	DSDWORD[ESI+left] = NULL;
148
	DSDWORD[ESI+right] = NULL;
149
	DSDWORD[ESI+recmodline] = modline;
150
	treeptr = newptr;
151
}
152
 
153
// ---- Вывод всех идентификаторов
154
void DisplayTree ()
155
{ 	// dump all identifiers to MAP file
156
	fprint(mapfile,"ALL GLOBAL IDENTIFIERS LIST:\n");
157
	fprint(mapfile,"tok    type      number    post\tIDENTIFIER\n");
158
	numberofids = 0;
159
	DisplayTreeAll(treestart);
160
	wsprintfA(#mapstr,"\n    %u Unique Global Identifiers.\n\n",numberofids);
161
	fprint(mapfile,#mapstr);
162
	fprint(mapfile,"GLOBAL CONSTANT IDENTIFIER LIST:\n");
163
	numberofids = 0;
164
	DisplayTreeConstants(treestart);
165
	wsprintfA(#mapstr,"\n    %u Unique Global Constant Value Identifiers.\n\n",numberofids);
166
	fprint(mapfile,#mapstr);
167
}
168
 
169
// ---- Вывод всего списка идентифиакторов
170
DisplayTreeAll(dword ptr)
171
{
172
if( ptr != NULL ){
173
	ESI=ptr;
174
	DisplayTreeAll(DSDWORD[ESI+right]);
175
	ESI=ptr;
176
	if(DSDWORD[ESI+rectok]-DSDWORD[ESI+recpost]!=tk_API){
177
		wsprintfA(#mapstr,"%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok],
178
			DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost],
179
			DSDWORD[ESI+recid]);
180
		fprint(mapfile,#mapstr);
181
		EAX=DSDWORD[ESI+newid];
182
		IF(EAX!=0){
183
			IF(lstrcmpA(DSDWORD[ESI+recid],EAX) != 0 ){
184
				ESI=ptr;
185
				wsprintfA(#mapstr,"Alias=%s\n",DSDWORD[ESI+newid]);
186
				fprint(mapfile,#mapstr);
187
			}
188
		}
189
		IF(list){
190
			ESI=ptr;
191
			EAX=DSDWORD[ESI+recsrc];
192
			IF(EAX!=0){
193
				EBX=DSDWORD[ESI+recmodline]>>16;
194
				EAX=FILENAMESIZE*EBX+#modules;
195
				EBX=EAX;
196
				wsprintfA(#mapstr,"File:%s, line=%-d:\n%s\n",EBX,
197
					DSDWORD[ESI+recmodline]&0xFFFF,DSDWORD[ESI+recsrc]);
198
				fprint(mapfile,#mapstr);
199
				ESI=ptr; LocalFree(DSDWORD[ESI+recsrc]);	// Освободим память
200
				DSDWORD[ESI+recsrc]=0;
201
			}
202
		}
203
		numberofids++;
204
	}
205
	ESI=ptr;
206
	DisplayTreeAll(DSDWORD[ESI+left]);
207
}
208
}
209
 
210
// ---- Вывод списка глобальных констант
211
DisplayTreeConstants(dword ptr)
212
{
213
	IF( ptr != NULL ){
214
		ESI=ptr;
215
		DisplayTreeConstants(DSDWORD[ESI+right]);
216
		ESI=ptr;
217
		EAX=DSDWORD[ESI+rectok];
218
		IF(EAX == tk_number){
219
			wsprintfA(#mapstr,"#define %10ld /* %8lX hex */ %s\n",
220
				DSDWORD[ESI+recnumber],DSDWORD[ESI+recnumber],DSDWORD[ESI+recid]);
221
			fprint(mapfile,#mapstr);
222
			numberofids++;
223
		}
224
		ESI=ptr;
225
		DisplayTreeConstants(DSDWORD[ESI+left]);
226
	}
227
}
228
 
229
// ---- Вычисление значения беззнаково	константы
230
dword DoConstDwordMath()
231
dword value;
232
{
233
	IF(tok == tk_minus){
234
		NextTok();
235
		IF(tok != tk_number){
236
			numexpected();
237
			return(0);
238
		}
239
		number = -number;
240
	}
241
	IF(tok != tk_number){
242
		numexpected();
243
		return(0);
244
	}
245
	value = number;
246
	while(tok2isopperand()){
247
		NextTok();
248
		IF(tok2!=tk_number)return(value);
249
		switch(tok){
250
			case tk_minus:	 value -= number2; break;
251
			case tk_plus:  value += number2;	 break;
252
			case tk_xor:		value ^= number2;  break;
253
			case tk_and:		value &= number2;  break;
254
			case tk_or: 	value |= number2; 	 break;
255
			case tk_mod:		value = value % number2; BREAK;
256
			case tk_div:		value = value / number2; BREAK;
257
			case tk_mult: 	value = value * number2; BREAK;
258
			case tk_rr: 	value >>= number2;				 BREAK;
259
			case tk_ll: 	value <<= number2;				 BREAK;
260
			case tk_xorminus:  value ^= -number2; 	 BREAK;
261
			case tk_andminus:  value &= -number2; 	 BREAK;
262
			case tk_orminus:	 value |= -number2; 	 BREAK;
263
/*		case(tok==tk_modminus)	value %= -number2;
264
		case(tok==tk_divminus)	value /= -number2;
265
		case(tok==tk_multminus) value *= -number2; */
266
			case tk_rrminus:	 value >>= -number2;	 BREAK;
267
			case tk_llminus:	 value <<= -number2;	 BREAK;
268
		}
269
		NextTok();
270
	}
271
	return(value);
272
}
273
 
274
// ---- Вычисление значения знаковой константы
275
long DoConstMath()
276
long value;
277
{
278
	IF(tok == tk_minus){
279
		NextTok();
280
		IF(tok != tk_number){
281
			numexpected();
282
			return(0);
283
		}
284
		number = -number;
285
	}
286
	IF(tok != tk_number){
287
		numexpected();
288
		return(0);
289
	}
290
	value = number;
291
	while(tok2isopperand()){
292
		NextTok();
293
		IF(tok2 != tk_number) return(value);
294
		switch(tok){
295
			case tk_minus:	 value -= number2; break;
296
			case tk_plus:  value += number2;	 break;
297
			case tk_xor:		value ^= number2;  break;
298
			case tk_and:		value &= number2;  break;
299
			case tk_or: 	value |= number2; 	 break;
300
			case tk_mod:		value = value % number2; BREAK;
301
			case tk_div:		value = value / number2; BREAK;
302
			case tk_mult: 	value = value * number2; BREAK;
303
			case tk_rr: 	value >>= number2;				 BREAK;
304
			case tk_ll: 	value <<= number2;				 BREAK;
305
			case tk_xorminus:  value ^= -number2; 	 BREAK;
306
			case tk_andminus:  value &= -number2; 	 BREAK;
307
			case tk_orminus:	 value |= -number2; 	 BREAK;
308
/*		case(tok==tk_modminus)	value %= -number2;
309
		case(tok==tk_divminus)	value /= -number2;
310
		case(tok==tk_multminus) value *= -number2; */
311
			case tk_rrminus:	 value >>= -number2;	 BREAK;
312
			case tk_llminus:	 value <<= -number2;	 BREAK;
313
		}
314
		NextTok();
315
	}
316
	return(value);
317
}
318
 
319
// ---- Вычисление значения знаковой константы
320
long DoConstLongMath()
321
long value;
322
{
323
	value=DoConstMath();
324
	NextTok();
325
	return(value);
326
}
327
 
328
// ---- Следующий token - операция?
329
dword tok2isopperand()
330
{
331
	EAX=tok2;
332
	IF(EAX==tk_plus)||(EAX==tk_minus)||(EAX==tk_mult)||(EAX==tk_div)||(EAX==tk_mod)||
333
	(EAX==tk_rr)||(EAX==tk_ll)||(EAX==tk_or)||(EAX==tk_and)||(EAX==tk_xor)||
334
	(EAX==tk_divminus)||(EAX==tk_modminus)||(EAX==tk_multminus)||(EAX==tk_xorminus)||
335
	(EAX==tk_orminus)||(EAX==tk_andminus)||(EAX==tk_llminus)||(EAX==tk_rrminus)return(1);
336
	return(0);
337
}
338
 
339
// ---- Следующий token закрывает выражение?
340
dword tok2notstopper ()
341
{
342
	EAX=tok2;
343
	IF(EAX==tk_semicolon)||(EAX==tk_comma)||(EAX==tk_closebracket)||
344
	(EAX==tk_openblock)EAX=0;
345
	ELSE EAX=1;
346
}
347
 
348
// ---- Поиск в списке локальных переменных
349
SearchLocals(dword tok4,type4,string4,number4)
350
{
351
	if( locallist != NULL ){
352
		localptr = locallist;
353
S00:
354
		ESI=EAX;	//localptr;
355
		lstrcmpA(string4,ESI+localid);
356
		ESI=localptr;
357
		IF(EAX==0){ 	// Переменная найдена
358
			EBX=number4;
359
			DSDWORD[EBX]=DSDWORD[ESI+localnumber];
360
			EBX=type4;
361
			DSDWORD[EBX]=DSDWORD[ESI+localtype];
362
			EBX=tok4;
363
			EAX=DSDWORD[ESI+localtok];
364
			DSDWORD[EBX]=EAX;
365
			IF(EAX==tk_local){
366
				EBX=number4;
367
				DSDWORD[EBX]-=localsize;
368
			}
369
			ELSE IF(EAX==tk_param){
370
				EBX=number4;
371
				EAX=DSDWORD[EBX]+4;
372
				DSDWORD[EBX]=EAX;
373
				IF(current_proc_type==cpt_far)DSDWORD[EBX]+=4;	// move over seg on stack
374
			}
375
			ELSE IF(EAX!=tk_locallabel)&&(EAX!=tk_number)internalerror("Bad *tok4 value in SearchLocals");
376
		}
377
		ELSE{
378
			IF(DSDWORD[ESI+localnext]!=NULL){
379
				localptr=DSDWORD[ESI+localnext];
380
				$JMP S00
381
			}
382
		}
383
	}
384
}
385
 
386
// ---- Поиск в списке глобальных идентификаторов
387
dword SearchTree(dword tok4,type4,src4,post4,string4,number4)
388
dword ptr;
389
long cmpresult;
390
{
391
	cmpresult=123;
392
	ptr = treestart;
393
// Поиск свободной ссылки
394
	for(;;){
395
		ESI=EAX;
396
		IF(ESI==0){
397
			treeptr=NULL;
398
			return(0);	// Not found
399
		}
400
		cmpresult = lstrcmpA(DSDWORD[ESI+recid],string4);
401
		ESI=ptr;
402
		IF(cmpresult<0)ptr=DSDWORD[ESI+left];
403
		ELSE IF(cmpresult>0)ptr=DSDWORD[ESI+right];
404
		ELSE BREAK;
405
	}
406
	EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+recnumber];
407
	EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+rectype];
408
	EBX=src4; DSDWORD[EBX]=DSDWORD[ESI+recsrc];
409
	EBX=post4; DSDWORD[EBX]=DSDWORD[ESI+recpost];
410
	EBX=tok4; EAX=DSDWORD[ESI+rectok]; DSDWORD[EBX]=EAX;
411
	IF(EAX==tk_string ){
412
		EBX=number4; ECX=DSDWORD[EBX]; EDI=string4;
413
		ESI=DSDWORD[ESI+newid]; $REP $MOVSB
414
	}
415
	ELSE{
416
		IF(DSDWORD[ESI+newid])lstrcpyA(string4,DSDWORD[ESI+newid]);
417
	}
418
	ESI=ptr;
419
	IF(lstrcmpA(DSDWORD[ESI+recid],string4)!=0) // Проверим: менялось ли имя идентификатора
420
		SearchTree(tok4,type4,src4,post4,string4,number4);	// Да - повторим поиск
421
	treeptr = ptr;
422
	return(1);
423
}
424
 
425
// ---- Поиск неоткомпилированных еще ссылок
426
dword SeekToDo(dword ptr)
427
{
428
	IF(ptr!=NULL){
429
		ESI=ptr;
430
		IF(SeekToDo(DSDWORD[ESI+right]))RETURN(1);
431
		ESI=ptr; EAX=DSDWORD[ESI+recpost];
432
		IF(EAX>1){
433
			treeptr=ptr; ESI=ptr;
434
			number=DSDWORD[ESI+recnumber];
435
			type=DSDWORD[ESI+rectype]; modline=DSDWORD[ESI+recmodline];
436
			src=DSDWORD[ESI+recsrc];
437
			post=DSDWORD[ESI+recpost];
438
			tok=DSDWORD[ESI+rectok]; RETURN(1);
439
		}
440
		ESI=ptr;
441
		IF(SeekToDo(DSDWORD[ESI+left]))RETURN(1);
442
	}
443
	return(0);
444
}
445
 
446
// ---- Поиск незакрытых ссылок
447
SeekUndefined(dword ptr)
448
{
449
	IF( ptr != NULL ){
450
		ESI=ptr;
451
		SeekUndefined(DSDWORD[ESI+right]);
452
		ESI=ptr; EAX=DSDWORD[ESI+rectok];
453
		IF(EAX==tk_undefproc){
454
			wsprintfA(#mapstr,"'%s' undefined\n",DSDWORD[ESI+recid]);
455
			IF( makemapfile )fprint(mapfile,#mapstr);
456
			WRITESTR(#mapstr);
457
		}
458
		ESI=ptr;
459
		SeekUndefined(DSDWORD[ESI+left]);
460
	}
461
}
462