📄 semantic.cpp
字号:
/*
* File: semantic.cc
* -----------------
* Implementation for the semantic processing routines.
* This is the place to define routines called by the parser
* to verify the semantic integrity of the program being parsed.
*/
#include "semantic.h"
#include "utility.h"
#include "errors.h"
#include "scope.h"
#include "declaration.h"
#include "type.h"
#include "parser.h"
#include "codegen.h"
extern ScopeStack *scopes;
extern CodeGenerator *cg;
//记录被调用的函数调用的declaration
extern DeclList *FunUsedList;
Declaration *BuildVarDecl(const char *varName, Type *varType, int lineNum)
{
return new Declaration(Declaration::Variable, varName, varType, lineNum);
}
Declaration *BuildClassDecl(const char *className, Type *super, int lineNum)
{
Type *type = Type::NewClassType(className, super); // make new class type
return new Declaration(Declaration::Class, className, type, lineNum);
}
Declaration *BuildFnDecl(const char *fnName, Type *returnType,
DeclList *formals, DeclOrDefn kind, struct yyltype *loc)
{
Type *fnType = Type::NewFunctionType(returnType, formals);
Declaration *decl = new Declaration(Declaration::Function,
fnName, fnType, loc->first_line);
return decl;
}
Type *TypeForClassName(const char *className)
{
return scopes->Lookup(className)->GetType();
}
//处理Call的全局函数
Declaration *DealWithCall(Declaration *OptReceiver, char *id, DeclList * actuals)
{
Scope *tScope;
Declaration *rtDecl;
tScope=scopes->GetClassScope();
if(OptReceiver==NULL)
{
Declaration *dec1, *dec2, *dec3, *dec4, *dec5, *dec7;
//不在类中的函数调用
if(tScope==NULL)
{
dec1=scopes->Lookup(id);
FunUsedList->Append(dec1);
int numPara=actuals->NumElements();
for(int i=numPara-1; i>=0; i--)
{
Declaration *temp;
temp=actuals->Nth(i);
// if(temp->GetType()->IsArrayType())
// temp->ValidateAddr();
cg->GenPushParam(temp);
}
rtDecl=cg->GenLCall(dec1->GetFunctionLabel(), numPara*VarSize, dec1->GetType()->GetFnReturnType());
return rtDecl;
}
//在类中的函数调用
else
{
dec2=tScope->Lookup(id);
//调用的是全局函数
if(dec2==NULL)
{
dec2=scopes->Lookup(id);
FunUsedList->Append(dec2);
int numPara=actuals->NumElements();
for(int i=numPara-1; i>=0; i--)
{
Declaration *temp;
temp=actuals->Nth(i);
// if(temp->GetType()->IsArrayType())
// temp->ValidateAddr();
cg->GenPushParam(temp);
}
rtDecl=cg->GenLCall(dec2->GetFunctionLabel(), numPara*VarSize, dec2->GetType()->GetFnReturnType());
return rtDecl;
}
//类中的函数
else
{
FunUsedList->Append(dec2);
int numPara=actuals->NumElements();
for(int i=numPara-1; i>=0; i--)
{
Declaration *temp;
temp=actuals->Nth(i);
// if(temp->GetType()->IsArrayType())
// temp->ValidateAddr();
cg->GenPushParam(temp);
}
dec1=scopes->Lookup("this");
cg->GenPushParam(dec1);
dec7=cg->GenLoad(dec1, Type::intType);
dec3=cg->GenLoadConstant(dec2->GetOffset(), Type::intType);
dec4=cg->GenBinaryOp("+", dec7, dec3,Type::intType);
dec5=cg->GenLoad(dec4, Type::intType);
//dec6=cg->GenLoad(dec5, Type::intType);
rtDecl=cg->GenACall(dec5, numPara*VarSize, dec2->GetType()->GetFnReturnType());
return rtDecl;
}
}
}
else if(OptReceiver->GetType()->IsArrayType())
{
Declaration *dec1;
if(strcmp(id, "length")==0)
{
dec1=cg->GenLoad(OptReceiver, Type::intType);
return dec1;
}
else
{
return NULL;
}
}
else if(OptReceiver->GetType()->IsClassType())
{
Scope *tScope=OptReceiver->GetType()->GetClassScope();
Declaration *funDecl=tScope->Lookup(id);
Declaration *dec1, *dec2, *dec3;
FunUsedList->Append(funDecl);
int numPara=actuals->NumElements();
for(int i=numPara-1; i>=0; i--)
{
Declaration *temp;
temp=actuals->Nth(i);
cg->GenPushParam(temp);
}
cg->GenPushParam(OptReceiver);
dec1=cg->GenLoad(OptReceiver, Type::intType);
dec2=cg->GenLoadConstant(funDecl->GetOffset(), Type::intType);
dec3=cg->GenLoad(cg->GenBinaryOp("+", dec1, dec2, Type::intType),Type::intType);
rtDecl=cg->GenACall(dec3, numPara*VarSize, funDecl->GetType()->GetFnReturnType());
if(funDecl->GetType()->GetFnReturnType()->IsArrayType())
rtDecl->ValidateAddr();
return rtDecl;
}
return NULL;
}
//处理LValue : Expr '[' Expr ']'时的语义动作
Declaration *DealWithArray(Declaration *expr1, Declaration *index)
{
Declaration *dec1, *dec2, *dec3, *dec4, *dec5, *dec6, *dec7, *dec8, *dec9, *dec10, *dec11, *dec12;
Declaration *temp;
char *label;
label=cg->NewLabel();
if(index->IsAddr())
{
temp=cg->GenLoad(index, Type::intType);
}
else
temp=index;
dec1=cg->GenLoad(expr1, Type::intType);
dec2=cg->GenBinaryOp("<", temp, dec1, Type::boolType);
dec3=cg->GenLoadConstant(0, Type::boolType);
dec4=cg->GenBinaryOp("==", dec3, dec2, Type::boolType);
dec5=cg->GenLoadConstant(0, Type::intType);
dec6=cg->GenBinaryOp("<", temp, dec5, Type::boolType);
dec7=cg->GenBinaryOp("||", dec6, dec4, Type::intType);
cg->GenIfZ(dec7, label);
dec8=cg->GenLoadConstant(err_arr_out_of_bounds);
cg->GenPushParam(dec8);
cg->GenLCall("_PrintString",VarSize,Type::voidType);
cg->GenLCall("_Halt", 0, Type::voidType);
cg->GenLabel(label);
dec9=cg->GenLoadConstant(VarSize, Type::intType);
dec10=cg->GenBinaryOp("*", dec9, temp, Type::intType);
dec11=cg->GenBinaryOp("+", dec9, dec10, Type::intType);
dec12=cg->GenBinaryOp("+", expr1, dec11, expr1->GetType()->GetArrayElemType());
dec12->ValidateAddr();
return dec12;
}
//处理LValue : OptReceiver T_Identifier
Declaration *DealWithLValue(Declaration *OptReceiver, char *id)
{
Declaration *dec1,*dec2, *dec3, *dec4;
if(OptReceiver==NULL)
{
dec1=scopes->Lookup(id);
if(dec1->GetScope()->IsClassScope())
{
dec2=cg->GenLoadConstant(dec1->GetOffset(), Type::intType);
dec3=scopes->Lookup("this");
dec4=cg->GenBinaryOp("+", dec3, dec2, dec1->GetType());
dec4->ValidateAddr();
return dec4;
}
//if(dec1->GetType()->IsArrayType())
// dec1->ValidateAddr();
return dec1;
}
else
{
Scope *tScope;
tScope=scopes->GetClassScope();
//不在类的作用域中
if(tScope==NULL)
{
tScope=OptReceiver->GetScope();
dec1=tScope->Lookup(id);
return dec1;
}
//在类的作用域中
else
{
if(strcmp(OptReceiver->GetName(),"this")==0)
{
dec1=tScope->Lookup(id);
dec2=cg->GenLoadConstant(dec1->GetOffset(), Type::intType);
dec3=scopes->Lookup("this");
dec4=cg->GenBinaryOp("+", dec3, dec2, dec1->GetType());
dec4->ValidateAddr();
return dec4;
}
else
{
tScope=OptReceiver->GetType()->GetClassScope();
dec1=tScope->Lookup(id);
dec2=cg->GenLoadConstant(dec1->GetOffset(), Type::intType);
dec4=cg->GenBinaryOp("+", OptReceiver, dec2, dec1->GetType());
dec4->ValidateAddr();
return dec4;
}
}
/*if(strcmp(OptReceiver->GetName(),"this")==0)
{
if(tScope==NULL)
{
}
else
{
}
Declaration *dec1=scopes->Lookup(id);
dec2=cg->GenLoadConstant(dec1->GetOffset(), Type::intType);
dec3=cg->GenBinaryOp("+", OptReceiver, dec2, OptReceiver->GetType());
//dec3->ValidateAddr();
return dec3;
}
else
{
tScope=OptReceiver->GetScope();
}
dec5=tScope->Lookup(id);
return dec5;*/
}
return NULL;
}
//处理Print的函数
void DealWithPrint(DeclList *exprList)
{
int i, declNum;
DeclList *dList=exprList;
Declaration *dec1, *dec2;
declNum=dList->NumElements();
for(i=0; i<declNum; i++)
{
dec1=dList->Nth(i);
if(dec1->IsAddr())
{
dec2=cg->GenLoad(dec1, dec1->GetType());
}
else
dec2=dec1;
cg->GenPushParam(dec2);
if(dec2->GetType()->IsEquivalentTo(Type::intType))
{
cg->GenLCall("_PrintInt",VarSize,Type::voidType);
}
else if(dec2->GetType()->IsEquivalentTo(Type::stringType))
{
cg->GenLCall("_PrintString",VarSize,Type::voidType);
}
else if(dec2->GetType()->IsEquivalentTo(Type::boolType))
{
cg->GenLCall("_PrintBool", VarSize, Type::voidType);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -