⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tac.cpp

📁 一个面向对像语言的编译器
💻 CPP
字号:
/* File: tac.cc
 * -----------
 * Implementation of Tac class and subclasses.
 */
  
#include "tac.h"
#include "declaration.h"
#include "type.h"
#include "mips.h"
#include "Ex86asm.h"


const char *Tac::opName[Tac::NumOps];
Tac::TacToWhat Tac::toWhat; 
 
void Tac::InitOpNames() {
  if (!opName[Add]) {
    opName[Add] = "+";    // we're lazy and only fill in the ones we use
    opName[Sub] = "-";
    opName[Mul] = "*";
    opName[Div] = "/";
    opName[Mod] = "%";
    opName[Eq] = "==";
    opName[Less] = "<";
    opName[And] = "&&";
    opName[Or] = "||";
  }
}
 
Tac::Tac(OpCode c) : code(c) { InitOpNames();}
  
Tac::OpCode Tac::OpCodeForName(const char *name) {
  InitOpNames();
  for (int i = 0; i < NumOps; i++) 
    if (opName[i] && !strcmp(opName[i], name))
	return (OpCode)i;
  Assert(0);
  return Add; // can't get here, but compiler doesn't know that
}

const char *Tac::NameForOpCode(OpCode c) {
  InitOpNames();
  Assert(opName[c] != NULL);
  return opName[c];
}

void Tac::Print() {
  printf("\t%s ;\n", printed);
}

void Tac::Emit(Mips *mips) {
  if (*printed)
    mips->Emit("# %s", printed);   // emit TAC as comment into assembly
  EmitSpecific(mips);
} 
void Tac::Emit(Ex86asm *x86) {
  if (*printed)
    x86->Emit("; %s", printed);   // emit TAC as comment into assembly
  EmitSpecific(x86);
} 

LoadConstant::LoadConstant(Declaration *d, int v)
  : Tac(Tac::LoadConstant), dst(d), val(v) {
  sprintf(printed, "%s = %d", dst->GetName(), val);
}
void LoadConstant::EmitSpecific(Mips *mips) {
  mips->EmitLoadConstant(dst, val);
}
void LoadConstant::EmitSpecific(Ex86asm *x86) {
  x86->EmitLoadConstant(dst, val);
}


////////////////////////////////////////

LoadStringConstant::LoadStringConstant(Declaration *d, const char *s)
  : Tac(Tac::LoadStringConstant), dst(d) {
  const char *quote = (*s == '"') ? "" : "\"";
  str = new char[strlen(s) + 2*strlen(quote) + 1];
  sprintf(str, "%s%s%s", quote, s, quote);
  quote = (strlen(str) > 50) ? "...\"" : "";
  sprintf(printed, "%s = %.50s%s", dst->GetName(), str, quote);
}
void LoadStringConstant::EmitSpecific(Mips *mips) {
  mips->EmitLoadStringConstant(dst, str);
}
void LoadStringConstant::EmitSpecific(Ex86asm *x86) {
  x86->EmitLoadStringConstant(dst, str);
}

//////////////////////////////////////
     

LoadLabel::LoadLabel(Declaration *d, const char *l)
  : Tac(Tac::LoadLabel), dst(d), label(strdup(l)) {
  sprintf(printed, "%s = %s", dst->GetName(), label);
}
void LoadLabel::EmitSpecific(Mips *mips) {
  mips->EmitLoadLabel(dst, label);
}

void LoadLabel::EmitSpecific(Ex86asm *x86) {
  x86->EmitLoadLabel(dst, label);
}

///////////////////////////////////////

Assign::Assign(Declaration *d, Declaration *s)
  : Tac(Tac::Assign), dst(d), src(s) {
  sprintf(printed, "%s = %s", dst->GetName(), src->GetName());
}
void Assign::EmitSpecific(Mips *mips) {
  mips->EmitCopy(dst, src);
}

void Assign::EmitSpecific(Ex86asm *x86) {
  x86->EmitCopy(dst, src);
}

//////////////////////////
Load::Load(Declaration *d, Declaration *s, int off )
  : Tac(Tac::Load), dst(d), src(s), offset(off) {
  if (offset) 
    sprintf(printed, "%s = *(%s + %d)", dst->GetName(), src->GetName(), offset);
  else
    sprintf(printed, "%s = *(%s)", dst->GetName(), src->GetName());
}
void Load::EmitSpecific(Mips *mips) {
  mips->EmitLoad(dst, src, offset);
}
void Load::EmitSpecific(Ex86asm *x86) {
  x86->EmitLoad(dst, src, offset);
}
/////////////////////////////////////

Store::Store(Declaration *d, Declaration *s, int off )
  : Tac(Tac::Store), dst(d), src(s), offset(off) {
  if (offset)
    sprintf(printed, "*(%s + %d) = %s", dst->GetName(), offset, src->GetName());
  else
    sprintf(printed, "*(%s) = %s", dst->GetName(), src->GetName());
}
void Store::EmitSpecific(Mips *mips) {
  mips->EmitStore(dst, src, offset);
}

void Store::EmitSpecific(Ex86asm *x86) {
  x86->EmitStore(dst, src, offset);
}
 
/////////////////////////
 

BinaryOp::BinaryOp(OpCode c, Declaration *d, Declaration *o1, Declaration *o2)
  : Tac(c), dst(d), op1(o1), op2(o2) {
  sprintf(printed, "%s = %s %s %s", dst->GetName(), op1->GetName(),
	   NameForOpCode(code), op2->GetName());
}
void BinaryOp::EmitSpecific(Mips *mips) {	  
  mips->EmitBinaryOp(code, dst, op1, op2);
}
void BinaryOp::EmitSpecific(Ex86asm *x86) {	  
  x86->EmitBinaryOp(code, dst, op1, op2);
}
//////////////////////////

Label::Label(const char *l) : Tac(Tac::Label), label(strdup(l)) {
  *printed = '\0';
}
void Label::Print() {
  printf("%s:\n", label);
}
void Label::EmitSpecific(Mips *mips) {
  mips->EmitLabel(label);
}
void Label::EmitSpecific(Ex86asm *x86) {
	if( !isFunLabel)
		x86->EmitLabel(label);

}
/////////////////////////////////////
 
Goto::Goto(const char *l) : Tac(Tac::Goto), label(strdup(l)) {
  sprintf(printed, "Goto %s", label);
}
void Goto::EmitSpecific(Mips *mips) {	  
  mips->EmitGoto(label);
}
void Goto::EmitSpecific(Ex86asm *x86) {	  
  x86->EmitGoto(label);
}
/////////////////////////////

IfZ::IfZ(Declaration *te, const char *l)
   : Tac(Tac::IfZ), test(te), label(strdup(l)) {
  sprintf(printed, "IfZ %s Goto %s", test->GetName(), label);
}
void IfZ::EmitSpecific(Mips *mips) {	  
  mips->EmitIfZ(test, label);
}
void IfZ::EmitSpecific(Ex86asm *x86) {	  
  x86->EmitIfZ(test, label);
}
/////////////////////////////////
BeginFunc::BeginFunc(Declaration *f) : Tac(Tac::BeginFunc), fn(f) {
  sprintf(printed,"BeginFunc");
}
void BeginFunc::EmitSpecific(Mips *mips) {
  Assert(fn->GetStackFrameSize() != Unassigned);
  mips->EmitBeginFunction(fn->GetStackFrameSize());
}
void BeginFunc::EmitSpecific(Ex86asm *x86) {
  Assert(fn->GetStackFrameSize() != Unassigned);
  x86->EmitBeginFunction(fn,fn->GetStackFrameSize());
}
/////////////////////

EndFunc::EndFunc(Declaration *f) : Tac(Tac::EndFunc) ,fn(f){
  sprintf(printed, "EndFunc");
}

void EndFunc::EmitSpecific(Mips *mips) {
  mips->EmitEndFunction();
}
 
void EndFunc::EmitSpecific(Ex86asm *x86) {
  x86->EmitEndFunction(fn);
}

///////////////////////

Return::Return(Declaration *v) : Tac(Tac::Return), val(v) {
  sprintf(printed, "Return %s", val? val->GetName() : "");
}
void Return::EmitSpecific(Mips *mips) {	  
  mips->EmitReturn(val);
}
void Return::EmitSpecific(Ex86asm *x86) {	  
  x86->EmitReturn(val);
}

///////////////////////

PushParam::PushParam(Declaration *p)
  : Tac(Tac::PushParam),  param(p) {
  sprintf(printed, "PushParam %s", param->GetName());
}
void PushParam::EmitSpecific(Mips *mips) {
  mips->EmitArg(param);
} 
void PushParam::EmitSpecific(Ex86asm *x86) {
  x86->EmitArg(param);
} 
////////////////////////
LCall::LCall(const char *l, int paramBytes, Declaration *d)
  : Tac(Tac::LCall),  label(strdup(l)), dst(d), numBytesOfParameters(paramBytes) {
  sprintf(printed, "%s%sLCall %s", dst? dst->GetName(): "", dst?" = ":"", label);
}
void LCall::EmitSpecific(Mips *mips) {
  mips->EmitLCall(dst, label, numBytesOfParameters);
}
void LCall::EmitSpecific(Ex86asm *x86) {
  x86->EmitLCall(dst, label , numBytesOfParameters);
}
////////////////////////
ACall::ACall(Declaration *ma, int paramBytes, Declaration *d)
  : Tac(Tac::ACall), dst(d), methodAddr(ma), numBytesOfParameters(paramBytes) {
  sprintf(printed, "%s%sACall %s", dst? dst->GetName(): "", dst?" = ":"",
	    methodAddr->GetName());
}
void ACall::EmitSpecific(Mips *mips) {
  mips->EmitACall(dst, methodAddr, numBytesOfParameters);
} 
void ACall::EmitSpecific(Ex86asm *x86) {
  x86->EmitACall(dst, methodAddr, numBytesOfParameters);
} 
/////////////////////

VTable::VTable(const char *l, DeclList *m)
  : Tac(Tac::VTable), methods(m), label(strdup(l)) {
  sprintf(printed, "VTable for class %s", l);
}

void VTable::Print() {
  printf("VTable %s =\n", label);
  for (int i = 0; i < methods->NumElements(); i++) 
    printf("\t%s,\n", methods->Nth(i)->GetFunctionLabel());
  printf("; \n");
}
void VTable::EmitSpecific(Mips *mips) {
  mips->EmitVTable(label, methods);
}
void VTable::EmitSpecific(Ex86asm *x86) {
  x86->EmitVTable(label, methods);
}
////////////////////////
void GVar::EmitSpecific(Ex86asm *x86) {
  x86->EmitGVar(decl);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -