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

📄 semantic.cpp

📁 一个面向对像语言的编译器
💻 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 + -