Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1846 yogev_ezra 1
// ---- Генерация выражения
2
DoExpr(dword var,vtok,vtype,mnem)
3
byte varName[2*IDLENGTH];
4
{
5
	IF(tok2notstopper()){
6
		IF(vtok==tk_var)Expression("eax",tk_reg,tk_dword);
7
		ELSE{
8
			Expression(var,vtok,vtype);
9
			return;
10
		}
11
	}
12
	else{ // Один операнд
13
		tok=GetVarname(#varName);
14
		IF(tok==tk_reg)wsprintfA(#mapstr,"%s %s,%s",mnem,var,#varName);
15
		else IF(tok==tk_var){
16
			IF(vtok==tk_var)Expression("eax",tk_reg,tk_dword);
17
			ELSE wsprintfA(#mapstr,"%s %s,%s",mnem,var,#varName);
18
		}
19
		else IF(tok==tk_number)wsprintfA(#mapstr,"%s %s,%d",mnem,var,DoConstMath());
20
		ELSE IF(tok==tk_postnumber)wsprintfA(#mapstr,"%s %s#%s",mnem,var,#varName);
21
		ELSE IF(tok==tk_locnumber){
22
			wsprintfA(#mapstr,"lea ebx,%s",#varName);
23
			wsprintfA(#mapstr,"%s %s,ebx",mnem,var);
24
			return;
25
		}
26
		Asm(#mapstr);
27
		RETURN;
28
	}
29
	IF(vtype==tk_byte)||(vtype==tk_char)wsprintfA(#mapstr,"%s %s,al",mnem,var);
30
	ELSE IF(vtype==tk_word)||(vtype==tk_short)wsprintfA(#mapstr,"%s %s,ax",mnem,var);
31
	ELSE IF(vtype==tk_dword)||(vtype==tk_int)wsprintfA(#mapstr,"%s %s,eax",mnem,var);
32
	Asm(#mapstr);
33
}
34
 
35
// ---- Разборка и трансляция выражений
36
dword Expression(dword dest,dtok,dtype)
37
byte s[IDLENGTH];
38
{
39
	GetInto(dest,dtok,dtype);
40
	for(;;){
41
		Term(#s,dtype);
42
		IF(tok==tk_plus){
43
			Term(#s,dtype);
44
			wsprintfA(#mapstr,"add %s,%s",dest,#s);
45
			Asm(#mapstr);
46
		}
47
		else IF(tok==tk_minus){
48
			Term(#s,dtype);
49
			wsprintfA(#mapstr,"sub %s,%s",dest,#s);
50
			Asm(#mapstr);
51
		}
52
		else IF(tok==tk_or){
53
			Term(#s,dtype);
54
			wsprintfA(#mapstr,"or %s,%s",dest,#s);
55
			Asm(#mapstr);
56
		}
57
		else IF(tok==tk_xor){
58
			Term(#s,dtype);
59
			wsprintfA(#mapstr,"xor %s,%s",dest,#s);
60
			Asm(#mapstr);
61
		}
62
		else IF(tok==tk_assign)||(tok==tk_equalto){
63
			Term(#s,dtype);
64
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
65
			Asm(#mapstr);
66
			Asm("sete al");
67
SE:
68
			wsprintfA(#mapstr,"movzx %s,al",dest);
69
			Asm(#mapstr);
70
		}
71
		else IF(tok==tk_notequal){
72
			Term(#s,dtype);
73
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
74
			Asm(#mapstr);
75
			Asm("setne al");
76
			GOTO SE;
77
		}
78
		else IF(tok==tk_greater){
79
			Term(#s,dtype);
80
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
81
			Asm(#mapstr);
82
			Asm("setg al");
83
			$JMP SE;
84
		}
85
		else IF(tok==tk_greaterequal){
86
			Term(#s,dtype);
87
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
88
			Asm(#mapstr);
89
			Asm("setge al");
90
			$JMP SE;
91
		}
92
		else IF(tok==tk_less){
93
			Term(#s,dtype);
94
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
95
			Asm(#mapstr);
96
			Asm("setl al");
97
			$JMP SE;
98
		}
99
		ELSE IF(tok==tk_lessequal){
100
			Term(#s,dtype);
101
			wsprintfA(#mapstr,"cmp %s,%s",dest,#s);
102
			Asm(#mapstr);
103
			Asm("setle al");
104
			$JMP SE;
105
		}
106
		ELSE BREAK;
107
	}
108
	return(relation);
109
}
110
 
111
// ---- Чтение очередного элемента выражения
112
Factor(dword f,ftype)
113
{
114
	NextTok();
115
	IF(tok==tk_openbracket){
116
		NextTok();
117
		PushEAX();
118
		Expression("eax",tk_reg,ftype);
119
		Asm("pop ebx; xchg eax,ebx");
120
		wsprintfA(f,"%s","ebx");
121
	}
122
	else IF(tok==tk_number)wsprintfA(f,"%#x",DoConstMath());
123
	else IF(tok==tk_postnumber)wsprintfA(f,"#%s",#string);
124
	else IF(tok==tk_proc){
125
		PushEAX();
126
		DoAnyProc();
127
		Asm("pop ebx; xchg eax,ebx");
128
		wsprintfA(f,"%s","ebx");
129
	}
130
	ELSE IF(tok==tk_API){
131
		PushEAX();
132
		doAPI();
133
		Asm("pop ebx; xchg eax,ebx");
134
		wsprintfA(f,"%s","ebx");
135
	}
136
	ELSE IF(tok==tk_var)||(tok==tk_param)||(tok==tk_local)||(tok==tk_openblock)||
137
		(tok==tk_reg)GetVarname(f);
138
}
139
 
140
// ----
141
GetInto(dword dest,dtok,dtype)
142
dword tk;
143
{
144
	tk=0;
145
DOCASE:
146
	IF(tok==tk_minus){
147
F_0:
148
		tk=tok;
149
		NextTok();
150
		GOTO DOCASE;
151
	 }
152
	else IF(tok==tk_not){
153
		relation^=1;
154
		GOTO F_0;
155
	}
156
	else IF(tok==tk_openbracket){
157
		NextTok();
158
		Expression(dest,dtok,dtype);
159
	}
160
	else IF(tok==tk_number){
161
		IF(tk)wsprintfA(#mapstr,"mov %s,-%#x",dest,DoConstMath());
162
		ELSE wsprintfA(#mapstr,"mov %s,%#x",dest,DoConstMath());
163
		Asm(#mapstr);
164
		tk=0;
165
	}
166
	else IF(tok==tk_postnumber){
167
		wsprintfA(#mapstr,"mov %s,#%s",dest,#string);
168
		Asm(#mapstr);
169
	}
170
	else IF(tok==tk_locnumber){
171
		wsprintfA(#mapstr,"lea ebx,%s",#string);
172
		Asm(#mapstr);
173
		wsprintfA(#mapstr,"mov %s,ebx",dest);
174
		Asm(#mapstr);
175
	}
176
	ELSE IF(tok==tk_proc)DoAnyProc();
177
	ELSE IF(tok==tk_API)doAPI();
178
	ELSE IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param)||(tok==tk_reg)||
179
		(tok==tk_openblock)GetIntoVar(dest,dtok,dtype);
180
	ELSE preerror("Wrong expression member");
181
//		wsprintfA(#string,dest,"mov %s,%s",#mapstr);
182
//		ESP+=16; Asm(#mapstr);
183
	IF(tk==tk_minus){
184
		wsprintfA(#mapstr,"neg %s",dest);
185
		Asm(#mapstr);
186
	}
187
	IF(tk==tk_not){
188
		wsprintfA(#mapstr,"not %s",dest);
189
		Asm(#mapstr);
190
	}
191
}
192
 
193
// ----
194
GetIntoVar(dword dName,dTok,dType)
195
byte varName[2*IDLENGTH];
196
dword vtype,vtok;
197
{
198
	if(dTok==tk_reg){
199
		if(tok==tk_reg){	// Reg = Reg
200
			IF(dType==tk_dword){// Reg32=Reg
201
				IF(type==tk_dword){
202
					wsprintfA(#mapstr,"mov %s,%s",dName,#string);
203
					Asm(#mapstr);
204
				}
205
				ELSE IF(type==tk_word)||(type==tk_byte){
206
RDW:
207
					wsprintfA(#mapstr,"movzx %s,%s",dName,#string);
208
					Asm(#mapstr);
209
				}
210
			}
211
			else IF(dType==tk_word){	// Reg=Reg
212
				IF(type==tk_dword){
213
GERR:
214
					warning("Not same size\n");
215
				}
216
				ELSE IF(type==tk_word){
217
					wsprintfA(#mapstr,"mov %s,%s",dName,#string);
218
					Asm(#mapstr);
219
				}
220
				ELSE IF(type==tk_byte)GOTO RDW;
221
			}
222
			ELSE IF(dType==tk_byte){	// Reg=Reg
223
				IF(type==tk_dword)||(type==tk_word)GOTO GERR;
224
				IF(type==tk_byte){
225
					wsprintfA(#mapstr,"mov %s,%s",dName,#string);
226
					Asm(#mapstr);
227
				}
228
			}
229
		}
230
		else if(tok==tk_var)||(tok==tk_param)||(tok==tk_local)||(tok==tk_openblock){	// Reg = Var
231
			vtype=type; vtok=GetVarname(#varName);
232
			IF(vtype==tk_dword)||(vtype==tk_int)||(dType==vtype){
233
				wsprintfA(#mapstr,"mov %s,%s",dName,#varName);
234
			}
235
			ELSE IF(vtype==tk_word)||(vtype==tk_byte){
236
				wsprintfA(#mapstr,"movzx %s,%s",dName,#varName);
237
			}
238
			ELSE IF(vtype==tk_short)||(vtype==tk_char){
239
				wsprintfA(#mapstr,"movsx %s,%s",dName,#varName);
240
			}
241
			Asm(#mapstr);
242
		}
243
		else IF(tok==tk_number){	// Reg = Const
244
			wsprintfA(#mapstr,"mov %s,%d",dName,DoConstMath());
245
			Asm(#mapstr);
246
		}
247
		else IF(tok==tk_postnumber){	// Reg = #Var
248
			GetVarname(#varName);
249
			wsprintfA(#mapstr,"mov %s,#%s",dName,#varName);
250
			Asm(#mapstr);
251
		}
252
		ELSE IF(tok==tk_locnumber){ // Reg = #locVar
253
			vtype=type; vtok=GetVarname(#varName);
254
			wsprintfA(#mapstr,"lea %s,%s",dName,#varName);
255
			Asm(#mapstr);
256
		}
257
	}
258
	else if(dTok==tk_var){
259
		if(tok==tk_reg){	// Var = Reg;
260
			IF(type==tk_dword){
261
				wsprintfA(#mapstr,"mov dword %s,%s",dName,#string);
262
				Asm(#mapstr);
263
			}
264
			ELSE IF(type==tk_word){
265
				wsprintfA(#mapstr,"mov word %s,%s",dName,#string);
266
				Asm(#mapstr);
267
			}
268
			ELSE IF(type==tk_byte){
269
				wsprintfA(#mapstr,"mov byte %s,%s",dName,#string);
270
				Asm(#mapstr);
271
			}
272
		}
273
		else if(tok==tk_var){ // Var = Var;
274
			vtype=type;
275
			vtok=GetVarname(#varName);
276
			IF(dType==tk_byte)||(dType==tk_char){
277
				wsprintfA(#mapstr,"mov al,%s",#varName);
278
				Asm(#mapstr);
279
				wsprintfA(#mapstr,"mov %s,al",dName);
280
				Asm(#mapstr);
281
				}
282
			else if(dType==tk_word)||(dType==tk_short){
283
				IF(vtype==tk_byte){
284
					wsprintfA(#mapstr,"movzx ax,%s",#varName);
285
					Asm(#mapstr);
286
				}
287
				else IF(vtype==tk_char){
288
					wsprintfA(#mapstr,"movsx ax,%s",#varName);
289
					Asm(#mapstr);
290
				}
291
				ELSE IF(vtype==tk_word)||(vtype==tk_short){
292
					wsprintfA(#mapstr,"mov ax,%s",#varName);
293
					Asm(#mapstr);
294
				}
295
				ELSE IF(vtype==tk_dword)||(vtype==tk_int){
296
					wsprintfA(#mapstr,"mov ax,word %s",#varName);
297
					Asm(#mapstr);
298
				}
299
				wsprintfA(#mapstr,"mov %s,ax",dName);
300
				Asm(#mapstr);
301
			}
302
			else if(dType==tk_dword)||(dType==tk_int){
303
				IF(vtype==tk_byte)||(vtype==tk_word){
304
					wsprintfA(#mapstr,"movzx eax,%s",#varName);
305
					Asm(#mapstr);
306
				}
307
				ELSE IF(vtype==tk_char)||(vtype==tk_short){
308
					wsprintfA(#mapstr,"movsx eax,%s",#varName);
309
					Asm(#mapstr);
310
				}
311
				ELSE IF(vtype==tk_dword)||(vtype==tk_int){
312
					wsprintfA(#mapstr,"mov eax,%s",#varName);
313
					Asm(#mapstr);
314
				}
315
				wsprintfA(#mapstr,"mov %s,eax",dName);
316
				Asm(#mapstr);
317
			}
318
		}
319
		else IF(tok==tk_number){	// Var = Const;
320
			wsprintfA(#mapstr,"mov %s,%d",dName,DoConstMath());
321
			Asm(#mapstr);
322
		}
323
		else IF(tok==tk_postnumber){	// Var = #Var;
324
			vtype=type; vtok=GetVarname(#varName);
325
			wsprintfA(#mapstr,"mov %s,#%s",dName,#varName);
326
			Asm(#mapstr);
327
		}
328
		ELSE IF(tok==tk_locnumber){ // Var = #locVar;
329
			vtype=type; vtok=GetVarname(#varName);
330
			wsprintfA(#mapstr,"lea ebx,%s",#varName);
331
			Asm(#mapstr);
332
			wsprintfA(#mapstr,"mov %s,ebx",dName);
333
			Asm(#mapstr);
334
		}
335
	}
336
}
337
 
338
// ---- Чтение переменной: VarName[reg+reg*Scale+disp]
339
dword GetVarname(dword varName)
340
dword vtok;
341
{
342
	IF(tok==tk_openblock)GOTO G0;
343
	lstrcpyA(varName,#string);
344
	vtok=tok;
345
	IF(vtok==tk_local)vtok=tk_var;
346
	ELSE IF(vtok==tk_param)vtok=tk_var;
347
	if(tok2==tk_openblock){
348
		NextTok();
349
G0:
350
		vtok=tk_var;
351
		lstrcatA(varName,"[");
352
		for(;;){
353
			NextTok();
354
			IF(tok==tk_reg)lstrcatA(varName,#string);
355
			else IF(tok==tk_plus)lstrcatA(varName,"+");
356
			else IF(tok==tk_mult)lstrcatA(varName,"*");
357
			ELSE IF(tok==tk_number){
358
				wsprintfA(#mapstr,"%d",DoConstMath());
359
				lstrcatA(varName,#mapstr);
360
			}
361
			ELSE IF(tok==tk_postnumber){
362
				lstrcatA(varName,"#");
363
				lstrcatA(varName,#string);
364
			}
365
			ELSE IF(tok==tk_closeblock){
366
				lstrcatA(varName,"]");
367
				BREAK;
368
			}
369
			ELSE preerror("Illegal index expression in []");
370
		}
371
	}
372
	return(vtok);
373
}
374
 
375
// ----
376
Term(dword t,ttype)
377
{
378
	for(;;){
379
		Factor(t,ttype);
380
		IF(tok==tk_mult){
381
			Factor(t,ttype);
382
			IF(tok==tk_number){
383
				wsprintfA(#mapstr,"mov ebx,%d",DoConstMath());
384
				Asm(#mapstr);
385
				wsprintfA(#mapstr,"mul %s","ebx");
386
			}
387
			ELSE wsprintfA(#mapstr,"mul %s",t);
388
			Asm(#mapstr);
389
		}
390
		else IF(tok==tk_div){
391
			Factor(t,ttype);
392
			IF(tok==tk_number){
393
				wsprintfA(#mapstr,"mov ebx,%d",DoConstMath());
394
				Asm(#mapstr);
395
				wsprintfA(#mapstr,"div %s","ebx");
396
			}
397
			ELSE wsprintfA(#mapstr,"div %s",t);
398
			Asm(#mapstr);
399
		}
400
		else IF(tok==tk_mod){
401
			Factor(t,ttype);
402
			IF(tok==tk_number){
403
				wsprintfA(#mapstr,"mov ebx,%d",DoConstMath());
404
				Asm(#mapstr);
405
				wsprintfA(#mapstr,"div %s","ebx");
406
			}
407
			ELSE wsprintfA(#mapstr,"div %s",t);
408
			Asm(#mapstr);
409
			Asm("xchg eax,edx");
410
		}
411
		ELSE IF(tok==tk_and){
412
			Factor(t,ttype);
413
			IF(tok==tk_number)wsprintfA(#mapstr,"and ebx,%d",DoConstMath());
414
			ELSE wsprintfA(#mapstr,"and eax,%s",t);
415
			Asm(#mapstr);
416
		}
417
		ELSE IF(tok==tk_not)Asm("not eax");
418
		ELSE BREAK;
419
	}
420
}
421
 
422
// ---- Сохранение EAX в стеке
423
PushEAX()
424
{
425
	Asm("push eax");
426
}
427
 
428
// ---- Сохранение EAX в стеке
429
/*PopEAX()
430
{
431
	Asm("pop eax");
432
} */
433
 
434
// ---- Обработка строки-параметра: proc("string")
435
dword AddPoststring()
436
dword returnvalue;
437
{
438
	IF(posts >= MAXPOSTS){
439
		preerror("cannot add post string, post queue full");
440
		ExitProcess(-1);
441
	}
442
	EBX=posts<<2+posttype;
443
	DSDWORD[EBX] = POST_STR;
444
	EBX=posts<<2+postloc;
445
	DSDWORD[EBX] = outptr;
446
	posts++;
447
	returnvalue = MAXDATA-1-poststrptr;
448
	ESI=#string;
449
	EBX>
450
	do{
451
		$LODSB;
452
		EDI=output+EBX;
453
		DSBYTE[EDI]=AL;
454
		EBX--;
455
	}while(AL!=0);
456
	EBX>
457
	EAX=returnvalue;
458
}
459
 
460
// ---- Обработка post-строк и ссылок на них
461
DoPoststrings()
462
dword addvalue,addhold,i;
463
{
464
	IF(poststrptr==MAXDATA-1)return;
465
	addvalue = OptImageBase + OptBaseOfCode+outptr-output ;
466
	EDI>
467
	EBX=MAXDATA-1;
468
D0:
469
	ESI=output+EBX;
470
	AL=DSBYTE[ESI];
471
	$STOSB
472
	EBX--;
473
	$CMP EBX,poststrptr;
474
	$JA D0;
475
	EDI>
476
	i=0;
477
	while(i
478
		EBX=i<<2+posttype;
479
		if(DSDWORD[EBX]==POST_STR){
480
			EBX=i<<2+postloc;
481
			addhold = GetDword(DSDWORD[EBX])+addvalue;
482
			SetDword(DSDWORD[EBX],addhold);
483
			posts--;
484
			EBX=i<<2+postloc;
485
			ECX=posts<<2+postloc;
486
			DSDWORD[EBX]=DSDWORD[ECX];
487
			EBX=i<<2+posttype;
488
			ECX=posts<<2+posttype;
489
			DSDWORD[EBX]=DSDWORD[ECX];
490
			EBX=i<<2+postnum;
491
			ECX=posts<<2+postnum;
492
			DSDWORD[EBX]=DSDWORD[ECX];
493
			i--;
494
		}
495
		i++;
496
	}
497
	poststrptr = MAXDATA-1;
498
}
499
 
500
// ---- Чтение одного параметра при вызове процедуры
501
GetParam(dword p)
502
dword count;		// счетчик скобок в параметре
503
{
504
	count=0;
505
	for(;;){
506
		EAX=0;
507
		ESI>
508
		$LODSB;
509
		ESI>
510
		cha2=AL;
511
		EDI>
512
		$STOSB EDI>
513
		IF(AL==0)BREAK;
514
		IF(AL==')'){
515
			IF(count==0){
516
				EDI>
517
				AL=0;
518
				EDI--;
519
				$STOSB;
520
				EDI>
521
				BREAK;
522
			}
523
			count--;
524
		}
525
		ELSE IF(AL==','){
526
			IF(count==0){
527
				EDI>
528
				EDI--;
529
				AL=0;
530
				$STOSB;
531
				EDI>
532
				DoParam();
533
				BREAK;
534
			}
535
		}
536
		ELSE IF(AL=='(')count++;
537
	}
538
}
539
 
540
// ---- Обработка одного параметра при вызове процедуры
541
DoParam()
542
dword vtok;
543
byte p[250];		// место под копию параметра
544
byte holdcha;
545
byte s[STRLEN],s2[STRLEN];
546
byte varName[2*IDLENGTH];
547
{
548
	GetParam(#p);
549
	holdcha=cha2;
550
	$PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod,linenumber,
551
		endoffile,displaytokerrors;
552
	lstrcpyA(#s,#string); lstrcpyA(#s2,#string2);
553
	input=#p;
554
	inptr = input;
555
	inptr2 =	input;
556
	endoffile = 0;	// На начале файла
557
	NextChar();
558
	cha2 = cha;
559
	inptr2=inptr;
560
	linenum2 = 1;
561
	NextTok();
562
	for(;;){
563
		IF(tok==tk_eof)||(tok==tk_closebracket)break;
564
		IF(tok==tk_comma)NextTok();
565
		else IF(tok==tk_string){
566
			OP(byte 0x68);
567
			OUTDWORD(AddPoststring());
568
			IF(list){
569
				wsprintfA(#mapstr,"\t//\tpush #\"%s\"\n",#string);
570
				fprint(mapfile,#mapstr);
571
			}
572
			NextTok();
573
		}
574
		else IF(tok2isopperand()){
575
			Expression("eax",tk_reg,tk_dword);
576
			PushEAX();
577
		}
578
		else{ // не выражение
579
			IF(tok==tk_number){
580
				wsprintfA(#mapstr,"push %#x",DoConstMath());
581
				Asm(#mapstr);
582
				NextTok();
583
			}
584
			else IF(tok==tk_postnumber){
585
				wsprintfA(#mapstr,"push #%s",#string);
586
				Asm(#mapstr);
587
				NextTok();
588
			}
589
			else if(tok==tk_reg){
590
				IF(type==tk_dword){
591
					wsprintfA(#mapstr,"push %s",#string);
592
					Asm(#mapstr);
593
					NextTok();
594
				}
595
				ELSE IF(type==tk_word){
596
					wsprintfA(#mapstr,"movsx e%s,%s;push e%s",#string,#string,#string);
597
					Asm(#mapstr);
598
					NextTok();
599
				}
600
				ELSE IF(tok==tk_byte){
601
					wsprintfA(#mapstr,"movsx e%cx,%s;push e%cx",string[0],#string,string[0]);
602
					Asm(#mapstr);
603
					NextTok();
604
				}
605
			}
606
			else IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param){
607
				vtok=GetVarname(#varName);
608
				IF(type==tk_dword){
609
D0: 			wsprintfA(#mapstr,"push %s",#varName);
610
					Asm(#mapstr);
611
					NextTok();
612
				}
613
				ELSE GOTO D1;
614
				IF(type==tk_int){ //????
615
					vtok=GetVarname(#varName);
616
					GOTO D0;
617
				}
618
			}
619
			ELSE{
620
D1: 		Expression("eax",tk_reg,tk_dword);
621
				PushEAX();
622
			}
623
		}
624
	}
625
	lstrcpyA(#string,#s);
626
	lstrcpyA(#string2,#s2);
627
	$POP displaytokerrors,endoffile,linenumber,currmod,inptr,input,tok,tok2;
628
	$POP number,inptr2,linenum2;
629
	cha2=holdcha;
630
}