📄 gencode.h
字号:
#ifndef GENCODE_H_
#define GENCODE_H_
#include <string>
#include "global.h"
#include "symtable.h"
#include "code.h"
using namespace std;
extern int nestlevel;
int tmpOffset=0;
void genCode(TreeNode *t);
void cGen(TreeNode *t,int);
#define stack 8
//emit code for temp result
//result is pre-saved in ac
void emitTemp(int tmpR)
{
if(tmpR>=1 && tmpR<=6){
emitRM("LDA",tmpR,0,ac);
}
else if(tmpR==stack){
emitRM("ST",ac,0,mp);
emitRM("LDA",mp,1,mp);
}
return;
}
//emit code for io of variable
//loc(fp): variable replacement
//bAddr: get address OR get value
// 1: get address
// 0: get value
//Address or value is saved in ac
void emitRefer(int location,int bAddr)
{
if(bAddr){
emitRM("LDA",ac,location,fp);
}
else{
emitRM("LD",ac,location,fp);
}
}
// tempR: Register for temp result
// 0-6: R0-R6
// 8: On stack
// -1: Abandon
void cGen(TreeNode *t,int tempR)
{
TreeNode *ttemp;
SymbolRecord *s;
int saveLoc1,saveLoc2,currentLoc;
int i;
if (t != NULL)
{
switch(t->kind)
{
case DECLAR:
if(t->childkind.declarK==FUNC_DECLAR)
{
FuncName=t->name;
s=st_lookup(t->name);
emitComment("Enter function");
s->location=emitSkip(0);
emitRM("ST",fp,0,mp);//save ofp
emitRM("LDA",fp,1,mp);//update fp
emitRM("LDA",mp,s->localAlloc+1,mp);//update mp,+1 for ofp
cGen(t->pChild[1],-1);
emitComment("Leave function");
emitRM("LDC",ac,0,0);//return 0 by default
//emitRM("LDA",mp,-(s->localAlloc+1),mp); //restore mp
emitRM("LDA",mp,-1,fp); //restore mp
emitRM("LD",temp,-2,fp);//temp=ret
emitRM("LD",fp,-1,fp);//fp=ofp
emitRM("LDA",pc,0,temp);//pc=ret(jump back)
FuncName="";
nestlevel=0;
}
break;
case CSTMT:
emitComment("Compound statement start");
st_addon(t->pBucketList);
cGen(t->pChild[1],-1);
st_takeoff();
emitComment("Compound statement end");
break;
case OP:
cGen(t->pChild[0],stack);
cGen(t->pChild[1],ac1);
emitRM("LD",ac,-1,mp);
emitRM("LDA",mp,-1,mp);
switch(t->tokenT)
{
case PLUS:
emitRO("ADD",ac,ac,ac1);
break;
case MINUS:
emitRO("SUB",ac,ac,ac1);
break;
case MUL:
emitRO("MUL",ac,ac,ac1);
break;
case DIV:
emitRO("DIV",ac,ac,ac1);
break;
}
emitTemp(tempR);
break;
case RELOP:
cGen(t->pChild[0],stack);
cGen(t->pChild[1],ac1);
emitRM("LD",ac,-1,mp);
emitRM("LDA",mp,-1,mp);
emitRO("SUB",ac,ac,ac1);
switch(t->tokenT)
{
case LT:
emitRM("JLT",ac,2,pc);
break;
case LTEQ:
emitRM("JLE",ac,2,pc);
break;
case GT:
emitRM("JGT",ac,2,pc);
break;
case GTEQ:
emitRM("JGE",ac,2,pc);
break;
case EQ:
emitRM("JEQ",ac,2,pc);
break;
case NEQ:
emitRM("JNE",ac,2,pc);
break;
}
emitRM("LDC",ac,0,0);
emitRM("LDA",pc,1,pc);
emitRM("LDC",ac,1,0);
emitTemp(tempR);
break;
case STMT:
switch(t->childkind.stmtK)
{
case IF_STMT:
emitComment("If statement start");
cGen(t->pChild[0],ac);
saveLoc1=emitSkip(1); //jump to else when false(ac=0)
cGen(t->pChild[1],-1);
saveLoc2=emitSkip(1); //jump to end
currentLoc=emitSkip(0);
emitBackup(saveLoc1);
emitRM("JEQ",ac,currentLoc-saveLoc1-1,pc);
emitRestore();
cGen(t->pChild[2],-1);
currentLoc=emitSkip(0);
emitBackup(saveLoc2);
emitRM_Abs("LDA",pc,currentLoc);
emitRestore();
emitComment("If statement end");
break;
case WHILE_STMT:
emitComment("While statement start");
currentLoc=emitSkip(0);
cGen(t->pChild[0],ac);
saveLoc1=emitSkip(1); //jump out
cGen(t->pChild[1],-1);
emitRM_Abs("LDA",pc,currentLoc);
currentLoc=emitSkip(0);
emitBackup(saveLoc1);
emitRM("JEQ",ac,currentLoc-saveLoc1-1,pc);
emitRestore();
emitComment("While statement end");
break;
case RETURN_STMT:
emitComment("Return statement start");
s=st_lookup(FuncName);
cGen(t->pChild[0],stack);
if(t->pChild[0]!=NULL){
emitRM("LD",ac,-1,mp);
}
emitRM("LDA",mp,-1,fp);//restore mp, -1 for ofp
emitRM("LD",temp,-2,fp);//temp=ret
emitRM("LD",fp,-1,fp); //fp=ofp
emitRM("LDA",pc,0,temp);//pc=ret(jump back)
emitComment("Return statement end");
break;
}
break;
case REFER:
emitComment(string("Reference of ")+t->name);
s=st_lookup(t->name);
i=s->nestlevel;
cGen(t->pChild[0],ac1);
if(t->pChild[0]!=NULL){
if(s->symboltype==ARRAYADDR_SYMBOL)
emitRM("LD",ac,s->location,i?fp:gp);
else emitRM("LDA",ac,s->location,i?fp:gp);
emitRO("ADD",ac,ac,ac1);
emitRM("LD",ac,0,ac);
}
else{
if(s->symboltype==ARRAY_SYMBOL){
emitRM("LDA",ac,s->location,i?fp:gp);
}
else
emitRM("LD",ac,s->location,i?fp:gp);
}
emitTemp(tempR);
break;
case CALL:
emitComment(string("Call ")+t->name);
if(t->name=="output") {
cGen(t->pChild[0],ac);
emitRO("OUT",ac,0,0);
}
else if(t->name=="input") {
emitRO("IN",ac,0,0);
emitTemp(tempR);
}
else{
s=st_lookup(t->name);
ttemp=t->pChild[0];
while(ttemp!=NULL){
if(ttemp->pNext==NULL)
break;
ttemp=ttemp->pNext;
}
t->pChild[0]=ttemp;
while(ttemp!=NULL)
{
ttemp->pNext=ttemp->pPrev;
ttemp=ttemp->pPrev;
}
cGen(t->pChild[0],stack);
emitRM("LDA",ac,3,pc);
emitRM("ST",ac,0,mp);
emitRM("LDA",mp,1,mp);
emitRM_Abs("LDA",pc,s->location);
emitRM("LDA",mp,-(s->paramAlloc+1),mp); //+1 for ret
emitTemp(tempR);
}
break;
case EXP:
switch(t->childkind.expK)
{
case ASSIGN_EXP:
emitComment("Assignment start: "+t->name);
s=st_lookup(t->name);
i=s->nestlevel;
cGen(t->pChild[1],stack);
cGen(t->pChild[0],ac);
if(t->pChild[0]!=NULL){
if(s->symboltype==ARRAYADDR_SYMBOL)
emitRM("LD",ac1,s->location,i?fp:gp);
else emitRM("LDA",ac1,s->location,i?fp:gp);
emitRO("ADD",ac1,ac,ac1);
emitRM("LD",ac,-1,mp);
emitRM("LDA",mp,-1,mp);
emitRM("ST",ac,0,ac1);
}
else{
emitRM("LD",ac,-1,mp);
emitRM("LDA",mp,-1,mp);
emitRM("ST",ac,s->location,i?fp:gp);
}
emitTemp(tempR);
break;
}
break;
case NUM:
emitComment(string("Literal number: ")+t->name);
emitRM("LDC",ac,atoi(t->name.c_str()),0);
emitTemp(tempR);
break;
}
cGen(t->pNext,tempR);
}
}
void genCode(TreeNode *t)
{
int jmainLoc;
SymbolRecord *s=st_lookup(string("main"));
if(s==NULL)
GenError("Entrypoint 'main' not found");
emitRM("LDA",mp,globalAlloc+1,mp); //+1 for ret
emitRM("LDA",ac,2,pc);
emitRM("ST",ac,-1,mp);
jmainLoc=emitSkip(1);
emitRM("LDA",mp,-(globalAlloc+1),mp); //+1 for ret
emitRO("HALT",0,0,0);
cGen(t->pNext->pNext,-1); //ignore input&output
emitBackup(jmainLoc);
emitRM_Abs("LDA",pc,s->location);
emitRestore();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -