-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtopcode.c
624 lines (537 loc) · 12.7 KB
/
topcode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "util.h"
#include "c0error.h"
#include "c0lex.h"
#include "table.h"
#include "symbol.h"
#include "absyn.h"
#include "lev.h"
#include "penv.h"
#include "topcode.h"
#define STRING_SPACE (10)
#define MAX_INT_LEN (2000)
#define OP_RET (0)
#define OP_ADD (2)
#define OP_MINUS (3)
#define OP_TIMES (4)
#define OP_DIV (5)
#define OP_NEQ (9)
#define OP_EQ (8)
#define OP_LT (10)
#define OP_GT (12)
#define OP_LE (13)
#define OP_GE (11)
/*
#define MAX_LEV (100)
#define MAX_TAB (200)
#define MAX_BTAB (50)
tab Tab(char *name,int link,int obj,int typ,int ref,int lev,int normal,int adr){
tab s=checked_malloc(sizeof(*s));
s->name=checked_malloc(strlen(name)+2);
strcpy(s->name,name);
s->lev=lev;
s->link=link;
s->obj=obj;
s->normal=normal;
s->adr=adr;
s->ref=ref;
s->typ=typ;
return s;}
btab Btab(int last,int lastpar,int psize,int vsize){
btab s=checked_malloc(sizeof(*s));
s->last=last;
s->lastpar=lastpar;
s->psize=psize;
s->vsize=vsize;
return s;}
static tab p_Tab[MAX_TAB];
static Tab_top =0;
static btab p_Btab[MAX_BTAB];
static Btab_top=0;
static int display[MAX_LEV]; //分程序索引表
*/
static A_constval _NULL_;
static A_constval constnull(){
return _NULL_;
}
static int ip=0;
static int start_ip=-1;
static pcode intr[MAX_INT_LEN];
static void display(pcode pc){
switch(pc->ptype){
case LIT:printf("LIT ");break;
case OPR:printf("OPR ");break;
case OPRF:printf("OPRF ");break;
case LOD:printf("LOD ");break;
case STO:printf("STO ");break;
case CAL:printf("CAL ");break;
case WRTF:printf("WRTF ");break;
case PINT:printf("INT ");break;
case JMP:printf("JMP ");break;
case JPC:printf("JPC ");break;
case RED:printf("RED ");break;
case WRT:printf("WRT ");break;
case WRTS:printf("WRTS ");break;
case MKS:printf("MKS ");break;
case FLT:printf("FLT ");break;
}
printf("%-5d %-5d\n",*pc->x,*pc->y);
}
void outputpcode(){
printf("starting address is %d\n",start_ip);
for(int i=0;i<ip;i++){
printf("%-5d :",i);
display(intr[i]);
}
}
static void EnterConst(TAB_table env,lev l,A_constDecList ccdl){
for(A_constDecList cdl=ccdl;cdl;cdl=cdl->tail){
A_constval t;
switch(cdl->head->type){
case INT_TY:
t= A_ConstNum(cdl->head->u.intt);break;
case FLOAT_TY:
t= A_ConstFloat(cdl->head->u.floatt);break;
case STRING_TY:
t=A_ConstString(cdl->head->u.stringg);break;
}
P_entry pe=PvarEntry(cdl->head->sym,cdl->head->type,1,t,l->lev,l->offset); //const不分配栈帧空间
S_enter(env,cdl->head->sym,pe);
}
}
static void AllocVar(TAB_table env,lev l,A_type t,symbol sym){
P_entry pe;
switch (t){
case INT_TY:{
pe=PvarEntry(sym,INT_TY,0,constnull(),l->lev,l->offset);
l->offset++;
break;
}
case FLOAT_TY:{
pe=PvarEntry(sym,FLOAT_TY,0,constnull(),l->lev,l->offset);
l->offset++;
break;
}
case STRING_TY:{
pe=PvarEntry(sym,STRING_TY,0,constnull(),l->lev,l->offset);
l->offset+=STRING_SPACE;
break;
}
}
S_enter(env,sym,pe);
}
static pcode outpcode(enum pty pp,int x,int y){
pcode p=Pcode(pp,x,y);
intr[ip]=p;
ip++;
return p;
}
static int NumOfArg(A_argList a){
int count=0;
while(a){
count++;
a=a->tail;
}
return count;
}
void pproc_exp(TAB_table env,A_exp exp,lev l,A_type ty);
pcode Pcode(enum pty pp,int x,int y){
pcode p=checked_malloc(sizeof(*p));
p->x=checked_malloc(sizeof(int));
p->y=checked_malloc(sizeof(int));
*(p->x)=x;
*(p->y)=y;
p->ptype=pp;
return p;
}
void pproc_factor(TAB_table env,A_f f,lev l, A_type ty){//A_syf,A_expf,A_intf,A_floatf,A_callf
switch(f->kind){
case A_syf:{
P_entry pe=S_look(env,f->u.sym);
if(pe->u.var.isconst==1){
if(ty==INT_TY){//常量
int a;
if(pe->u.var.ty==FLOAT_TY) a=(int)(pe->u.var.val.flo);
else if(pe->u.var.ty==INT_TY) a=pe->u.var.val.num;
outpcode(LIT,0,a);
}
else if(ty==FLOAT){
int *a;
if(pe->u.var.ty==FLOAT_TY) a=(int *)&(pe->u.var.val.flo);
else {
float t=(float )pe->u.var.val.num;
if(pe->u.var.ty==INT_TY) a=(int *)&t;
}
outpcode(LIT,0,*a);
}
}
else{// 非常量
int diffl=l->lev-pe->u.var.lev;
int offset=pe->u.var.offset;
outpcode(LOD,diffl,offset);
if(pe->u.var.ty==INT_TY && ty==FLOAT_TY){ // int 2 float
outpcode(FLT,0,0);
}
if(pe->u.var.ty==FLOAT_TY && ty==INT_TY){//float 2 int
outpcode(FLT,0,1);
}
}
break;
}
case A_expf:{
pproc_exp(env,f->u.exp,l,ty);
break;
}
case A_intf:{
float te;
if(ty==FLOAT_TY){
te=f->u.intt;
outpcode(LIT,0,*(int *)&te); // 字面类型的隐式转换
}else{
outpcode(LIT,0,f->u.intt);
}
break;
}
case A_floatf:{
if(ty==INT_TY){
outpcode(LIT,0,(int)f->u.floatt); // float to int
}{
outpcode(LIT,0,*(int *)&(f->u.floatt));
}
break;
}
case A_callf:{
P_entry pe=S_look(env,f->u.call.funname);
int size=NumOfArg(pe->u.fun.arglist);
outpcode(MKS,0,size);
int count=0;
A_argList agls=pe->u.fun.arglist;
for(A_valArgs agl =f->u.call.vals;agl;agl=agl->tail){
l->lev++;
pproc_exp(env,agl->head,l,agls->head->type);//置于栈顶
l->lev--;
outpcode(STO,0,count+4);
count++;
agls=agls->tail;
}
int diffl=pe->u.fun.lev->lev - l->lev;
pcode cal=outpcode(CAL,diffl,*(pe->u.fun.start));
cal->y = pe->u.fun.start;
break;
}
}
}
void pproc_item(TAB_table env,A_t t,lev l,A_type ty){
pproc_factor(env,t->f,l,ty);
A_ftail ft=t->ftail;
A_oper op;
while(ft){
pproc_factor(env,ft->f,l,ty);
int o=-1;
op=ft->oper;
switch(op){
case A_mul:
o=OP_TIMES;break;
case A_div:
o=OP_DIV;break;
default:
assert(0);
}
if(ty==INT_TY){
outpcode(OPR,0,o);
}else if(ty==FLOAT_TY){
outpcode(OPRF,0,o);
}
ft=ft->ftail;
}
}
void pproc_exp(TAB_table env,A_exp exp,lev l,A_type ty){
if(exp->oper==A_minus){
outpcode(LIT,0,0);
}
pproc_item(env,exp->t,l,ty);
if(exp->oper==A_minus){
if(ty==INT_TY){
outpcode(OPR,0,OP_MINUS);
}
if(ty==FLOAT_TY){
outpcode(OPRF,0,OP_MINUS);
}
}
A_ttail tt=exp->ttail;
A_oper op;
while(tt){
pproc_item(env,tt->t,l,ty);
int o=-1;
op=tt->oper;
switch(op){
case A_add:
o=OP_ADD;break;
case A_minus:
o=OP_MINUS;break;
default:
assert(0);
}
if(ty==INT_TY){
outpcode(OPR,0,o);
}else if(ty==FLOAT_TY){
outpcode(OPRF,0,o);
}
tt=tt->ttail;
}
}
void pproc_flag(TAB_table env,A_flag fl,lev l){
A_type lef=find_type(env,fl->left);
A_type rig=find_type(env,fl->right);
A_type t=INT_TY;
if(lef==FLOAT_TY || rig==FLOAT_TY){
t=FLOAT_TY;
}
pproc_exp(env,fl->left,l,t);
pproc_exp(env,fl->right,l,t);
int o=-1;
switch (fl->com){
case A_GE:
o=OP_GE;break;
case A_LE:
o=OP_LE;break;
case A_NE:
o=OP_NEQ;break;
case A_EQ:
o=OP_EQ;break;
case A_L:
o=OP_LT;break;
case A_G:
o=OP_GT;break;
}
if(t==INT_TY){
outpcode(OPR,0,o);
}
if(t==FLOAT_TY){
outpcode(OPRF,0,o);
}
}
void pproc_seq(TAB_table env,A_seq seq,lev l){
switch(seq->kind){
case A_if:{
pproc_flag(env,seq->u.iff.flag,l);// 结果放到栈顶
int *f;
pcode jpc=outpcode(JPC,0,0);
f=jpc->y;
pproc_seq(env,seq->u.iff.thenn,l);
int *t;
if(seq->u.iff.elsee){
pcode jup=outpcode(JMP,0,0);
t=jup->y;
}
*f=ip;//回填技术
if(seq->u.iff.elsee){
pproc_seq(env,seq->u.iff.elsee,l);
*t=ip;
}
break;
}
case A_ass:{
P_entry pe = S_look(env,seq->u.ass.sym);
int diffl = l->lev - pe->u.var.lev;
int offset = pe->u.var.offset;
pproc_exp(env,seq->u.ass.exp,l,pe->u.var.ty);
pcode sto= outpcode(STO,diffl,offset);
break;
}
case A_call:{
P_entry pe=S_look(env,seq->u.call.func);
int size=NumOfArg(pe->u.fun.arglist);
outpcode(MKS,0,size);
int count=0;
A_argList agls =pe->u.fun.arglist;
for(A_valArgs agl = seq->u.call.valargs;agl;agl=agl->tail){
l->lev++;
pproc_exp(env,agl->head,l,agls->head->type);//置于栈顶 // 默认转换类型
l->lev--;
outpcode(STO,0,count+4);
count++;
agls=agls->tail;
}
int diffl=pe->u.fun.lev->lev - l->lev;
pcode cal=outpcode(CAL,diffl,*(pe->u.fun.start));
cal->y = pe->u.fun.start;
break;
}
case A_print:{
if(seq->u.print.stringg){
int len=strlen(seq->u.print.stringg);
for(int i=0;i<len;i++){
outpcode(LIT,0,(int)(seq->u.print.stringg[i]));
outpcode(WRTS,0,0);
}
}
if(seq->u.print.exp){
A_type t=find_type(env,seq->u.print.exp);
pproc_exp(env,seq->u.print.exp,l,t);
if(t==FLOAT_TY){
outpcode(WRTF,0,0);
}else{
outpcode(WRT,0,0);
}
}
break;
}
case A_ret:{
if(seq->u.ret.exp){
A_type t=find_type(env,seq->u.ret.exp);
pproc_exp(env,seq->u.ret.exp,l,t);
// outpcode(STO,0,0);// 这一步由解释器来做
}
outpcode(OPR,0,0);
break;
}
case A_scan:{
P_entry pe=S_look(env,seq->u.scan.sym);
int diffl =l->lev- pe->u.var.lev;
int offset =pe->u.var.offset;
outpcode(RED,diffl,offset);
break;
}
case A_while:{
int *e=checked_malloc(sizeof(int));
int *s=checked_malloc(sizeof(int));
*s= ip;
pproc_flag(env,seq->u.whilee.flag,l);
outpcode(LIT,0,0);
outpcode(OPR,0,OP_NEQ);
pcode jpc =outpcode(JPC,0,*e);
e=jpc->y;
pproc_seq(env,seq->u.whilee.seq,l);
pcode jmp =outpcode(JMP,0,0);
jmp->y=s;
*e=ip;
break;
}
case A_seqss:{
beginScope(env);
A_seqs ss=NULL;
for(A_seqs s=seq->u.sqs;s;s=s->seqs){//reverse
ss=A_Seqs(s->seq,ss);
}
for(;ss;ss=ss->seqs){
pproc_seq(env,ss->seq,l);
}
endScope(env);
break;
}
}
}
void pproc_seqs(TAB_table env,A_seqs seqs,lev l){
A_seqs ss=NULL;
for(A_seqs s=seqs;s;s=s->seqs){//reverse
ss=A_Seqs(s->seq,ss);
}
for(;ss;ss=ss->seqs){
pproc_seq(env,ss->seq,l);
}
}
//
void pproc_func(TAB_table env,A_funcDec fd,lev l){
P_entry pe=PfuncEntry(fd->name,fd->rettype,fd->agrlist,l,-1);
S_enter(env,fd->name,pe); //函数头需要最先处理 是唯一在这个层次外可以访问的东西
beginScope(env);
for(A_argList a=fd->agrlist;a;a=a->tail){
AllocVar(env,l,a->head->type,a->head->argsy);
}
EnterConst(env,l,fd->cseqs->constdeclist);
int oldoffset=l->offset;
A_varDecList nvdl=NULL;
for(A_varDecList vdl=fd->cseqs->vardeclist;vdl;vdl=vdl->tail){ //reverse not necessary
nvdl=A_VarDecList(vdl->head,nvdl);
}
for(;nvdl;nvdl=nvdl->tail){
AllocVar(env,l,nvdl->head->type,nvdl->head->sym);
}
int newoffset=l->offset;
// note 目前不需要考虑静态链信息
// 如果有程序的子函数定义(目前没有) ,那么就应该在这里进行管理
// to do
//之前的函数地址已经确定
*pe->u.fun.start=ip;
if(newoffset-oldoffset!=0)
outpcode(PINT,0,newoffset-oldoffset);
pproc_seqs(env,fd->cseqs->seqs,l);
endScope(env);
outpcode(OPR,0,OP_RET);
}
void getpcode(A_prog prog){
/*
Tab_top=0;
Btab_top=0;
p_Btab[Btab_top]=Btab(1,1,0,0);
Btab_top++;
int lev=1; //当前静态深度
display[0]=1; // 0 是预留层
display[1]=2; // 1 是当前层主函数
*/
TAB_table env=S_empty();
lev l=NewLev();
l->lev=0;
l->offset=4;
EnterConst(env,l,prog->constdeclist);
int oldoffset = l->offset;
A_varDecList nvdl=NULL;
for(A_varDecList vdl=prog->vardeclist;vdl;vdl=vdl->tail){ //reverse not necessary
nvdl=A_VarDecList(vdl->head,nvdl);
}
for(;nvdl;nvdl=nvdl->tail){
AllocVar(env,l,nvdl->head->type,nvdl->head->sym);
}
start_ip =ip;
int newoffset= l->offset;
if(newoffset-oldoffset!=0)
outpcode(PINT,0,newoffset-oldoffset);
outpcode(MKS,0,0);//即使主函数有参数,但是目前不传递他 可以传递 todo
pcode mainjmp = outpcode(CAL,1,0);
outpcode(OPR,0,OP_RET);
A_funcDecList nfdl=NULL;
for(A_funcDecList fdl=prog->fundeclist;fdl;fdl=fdl->tail){ //reverse
nfdl=A_FuncDecList(fdl->head,nfdl);
}
int co=0;
for(;nfdl;nfdl=nfdl->tail){
lev nl=NewLev();
nl->lev=l->lev+1;
nl->offset=4;
pproc_func(env,nfdl->head,nl);
}
// main 函数处理过程
beginScope(env);
lev le=NewLev();
le->lev=l->lev+1;
le->offset=4;
/*
for(A_argList a=prog->mainn->valargs;a;a=a->tail){
AllocVar(env,le,a->head->type,a->head->argsy);
}
*/ //这个参数分配由MKS 完成
symbol mainsym=Symbol("Main");
P_entry pe=PfuncEntry(mainsym,prog->mainn->ret,prog->mainn->valargs,le,-1);
S_enter(env,mainsym,pe);
EnterConst(env,le,prog->mainn->cseqs->constdeclist);
oldoffset=le->offset;
A_varDecList nvdls=NULL;
for(A_varDecList vdl=prog->mainn->cseqs->vardeclist;vdl;vdl=vdl->tail){ //reverse not necessary
nvdls=A_VarDecList(vdl->head,nvdls);
}
for(;nvdls;nvdls=nvdls->tail){
AllocVar(env,le,nvdls->head->type,nvdls->head->sym);
}
newoffset=le->offset;
*mainjmp->y=ip;
*pe->u.fun.start=ip;
if(newoffset!=oldoffset){
outpcode(PINT,0,newoffset-oldoffset);
}
pproc_seqs(env,prog->mainn->cseqs->seqs,le);
endScope(env);
outpcode(OPR,0,OP_RET);
}