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

📄 codegenerator.java

📁 SkipOOMiniJOOL教学语言的编译器前端
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			codes.add("andl	$-16, %esp");
			codes.add("movl	$0, %eax");
			codes.add("movl	%eax, -16(%ebp)");
			codes.add("movl	-16(%ebp), %eax");
			codes.add("call	__alloca");
			codes.add("call	___main");*/
		}
		else
		{
			/*codes.add(".global _"+m.getName().getIdentifier());
			codes.add(".def	_"+m.getName().getIdentifier()+";	.scl	2;	.type	32;	.endef");
			codes.add("_"+m.getName().getIdentifier()+":");
			codes.add("pushl %ebp");
			codes.add("movl	%esp, %ebp");*/
		}
		List para = m.parameters();
		/*
		 * 确定参数的存储位置
		 */
		paraNum = 8;
		for(Iterator iter = para.iterator();iter.hasNext();)
			((SingleVariableDeclaration)iter.next()).accept(this);
		Statement st = (Statement)m.getBody().statements().get(m.getBody().statements().size()-1);
		/*
		 * 检查函数定义是否以return语句结束
		 */
		if(!(st.getClass().toString().equals("class org.eclipse.jdt.core.dom.ReturnStatement"))){
			SemanticError.error_13_ReturnEnd(null,m.getName().getIdentifier());
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		m.getBody().accept(this);
		
		
		return false;
	}

	public boolean visit(MethodInvocation m) {
		List para = m.arguments();
		
		int i = 0;
		/*
		 * print 单独处理
		 */
		if(m.getName().getIdentifier().equals("print")){
			//assert m.arguments().size()==1;
			//codes.add("subl	$8, %esp");
			
			if(m.arguments().get(0).getClass().toString().equals("class org.eclipse.jdt.core.dom.SimpleName")&&
					type.get(((SimpleName)m.arguments().get(0)).getIdentifier()).toString().equals("String")||
					m.arguments().get(0).getClass().toString().equals("class org.eclipse.jdt.core.dom.StringLiteral"))
				codes.add("movl	$LC0, (%esp)");
			else
				codes.add("movl	$LC1, (%esp)");
			i++;
			((Expression)para.get(0)).accept(this);
			codes.add("movl	%eax, 4(%esp)");
			codes.add("call	_printf");
		}
		else{
			MethodDeclaration md = (MethodDeclaration)methods.get(m.getName().getIdentifier());
			/*
			 * 检查调用的函数是否被定义
			 */
			if(md==null){
				SemanticError.error_2_NoDeclaration(null,md.getName().getIdentifier());
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			/*
			 * 检查函数调用的实参数目是否相符
			 */
			if(md.parameters().size()!=para.size()){
				SemanticError.error_4_CallArguments(null,m.getName().getIdentifier());
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			codes.add("subl	$"+(4*para.size())+ ", %esp");
			for(Iterator iter = para.iterator();iter.hasNext();){
				Expression p = (Expression)iter.next();
				p.accept(this);
				/*
				 * 检查函数调用的实参类型是否匹配
				 */
				if(!(((SingleVariableDeclaration)md.parameters().get(i)).getType().toString().equals(p.getProperty("type")))){
					SemanticError.error_4_CallArguments(null,m.getName().getIdentifier());
					//System.err.println("Code generation halted");
					System.exit(0);
				}
				if(i==0)
					codes.add("movl	%eax, (%esp)");
				else
					codes.add("movl	%eax, "+(i*4)+"(%esp)");
				i++;
			}
			codes.add("call	_"+m.getName().getIdentifier());
			m.setProperty("type",md.getReturnType2().toString());
			/*
			 * 部分检查void函数调用是否被用作表达式值引用
			 */
			if((m.getParent().getClass().toString().equals("class org.eclipse.jdt.core.dom.Expression")
					||m.getParent().getClass().toString().equals("class org.eclipse.jdt.core.dom.InfixExpression")
					||m.getParent().getClass().toString().equals("class org.eclipse.jdt.core.dom.PrefixExpression")
					)&&md.getReturnType2().toString().equals("void")){
				SemanticError.error_5_MethodResult(null,md.getName().getIdentifier());
				//System.err.println("Code generation halted");
				System.exit(0);
			}
				
		}
		
		
		return false;
	}

	public boolean visit(NumberLiteral e) {
		e.setProperty("type","int");//type
		
		codes.add("movl	$"+e.getToken()+", %eax");
		
		return false;
	}

	public boolean visit(NullLiteral e) {
		//TODO:Lab5
		return false;
	}

	public boolean visit(PrefixExpression e) {
		if(e.getOperator()==PrefixExpression.Operator.MINUS){
			e.getOperand().accept(this);
			codes.add("negl	%eax");
			/*
			 * 检查前缀操作符-的操作数的类型是否为int
			 */
			if(e.getOperand().getProperty("type")!="int"){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","int");
		}
		else if(e.getOperator()==PrefixExpression.Operator.NOT){
			e.getOperand().accept(this);
			codes.add("xor	$0x00000001, %eax");
			/*
			 * 检查!操作符的操作数的类型是否为boolean
			 */
			if(e.getOperand().getProperty("type")!="boolean"){
				SemanticError.error_11_CondTypes(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		}
		/*else if(e.getOperator()==PrefixExpression.Operator.DECREMENT){
			codes.add("leal	"+(String)posTable.get(((SimpleName)e.getOperand()).getIdentifier())+", %eax");
			codes.add("decl	(%eax)");
		}
		else if(e.getOperator()==PrefixExpression.Operator.INCREMENT){
			codes.add("leal	"+(String)posTable.get(((SimpleName)e.getOperand()).getIdentifier())+", %eax");
			codes.add("incl	(%eax)");
		}*/
		
		
		return false;
	
	}

	public boolean visit(ReturnStatement s) {
		
		if(s.getExpression()!=null){
			/*
			 * 检查void函数是否返回值
			 */
			if(now.getReturnType2().toString().equals("void")){
				SemanticError.error_6_VoidReturn(null,now.getName().getIdentifier());
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			s.getExpression().accept(this);//返回值保存在eax中返回
			/*
			 * 检查返回值类型与函数声明返回的类型是否匹配
			 */
			if(!(now.getReturnType2().toString().equals(s.getExpression().getProperty("type")))){
				SemanticError.error_7_NonVoidReturn(null,now.getName().getIdentifier());
				//System.err.println("Code generation halted");
				System.exit(0);
			}
		}
		/*
		 * 检查非void类型函数是否返回了值
		 */
		else if(!(now.getReturnType2().toString().equals("void"))){
			SemanticError.error_7_NonVoidReturn(null,now.getName().getIdentifier());
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		codes.add("movl	%ebp, %esp");
		codes.add("popl	%ebp");
		codes.add("ret");
		
		return false;
	}

	public boolean visit(SimpleName n) {
		/*
		 * 能进入此点的必然是对该标识符的引用,因为定义处不会访问该ASTNode
		 */
		if(posTable.containsKey(n.getIdentifier()))
			codes.add("movl	"+posTable.get(n.getIdentifier())+", %eax");
		/*
		 * 检查标识符是否定义
		 */
		else{
			SemanticError.error_2_NoDeclaration(null,n.getIdentifier());
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		n.setProperty("type",type.get(n.getIdentifier()));
	
		return false;
	}

	public boolean visit(SingleVariableDeclaration s) {
		type.put(s.getName().getIdentifier(),s.getType().toString());
		posTable.put(s.getName().getIdentifier(),(new Integer(paraNum)).toString()+"(%ebp)");
		paraNum+=4;
		
		return false;
	}

	public boolean visit(StringLiteral e) {
		int index = -1;
		int i=0;
		for(Iterator iter=strs.iterator();iter.hasNext();){
			if(((String)iter.next()).equals(e.getLiteralValue())){
				index=i;
				break;
			}
			i++;
		}
		/*
		 * 查看字符串表中是否已经有了该字符串
		 */
		if(index==-1){
			strs.add(e.getLiteralValue());
			index=strIndex;
			strIndex++;
		}
		/*
		 * 将地址移动到寄存器eax
		 */
		codes.add("movl	$LC"+index+", %eax");
		e.setProperty("type","String");
		
		return false;
	}

	public boolean visit(ThisExpression e) {
		//TODO:Lab5
		return false;
	}

	public boolean visit(TypeDeclaration t) {
		classNum++;
		/*
		 * 检查类定义是否唯一,并且类名是否为Program
		 */
		if(classNum>1||!(t.getName().getIdentifier().equals("Program"))){
			SemanticError.error_3_ProgramClassError(null);
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		
		List l = t.bodyDeclarations();
		for(Iterator iter = l.iterator();iter.hasNext();){
			ASTNode method = (ASTNode)iter.next();
			if(method.getClass().toString().equals("class org.eclipse.jdt.core.dom.MethodDeclaration"))
				methods.put(((MethodDeclaration)method).getName().getIdentifier(),method);
		}
		
		for(Iterator iter = l.iterator();iter.hasNext();)
			((ASTNode)iter.next()).accept(this);
		/*
		 * 检查主类是否定义
		 */
		if(mainNum==0){
			SemanticError.error_3_ProgramClassError(null);
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		
		return false;
	}

	public boolean visit(VariableDeclarationFragment f) {
		
		/*
		 * 检查变量是否重定义
		 */
		if(posTable.containsKey(f.getName().getIdentifier())){
			SemanticError.error_1_DoubleDeclaration(null,f.getName().getIdentifier());
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		/*
		 * 记录变量在栈中位置
		 */
		posTable.put(f.getName().getIdentifier(),(new Integer(stackPos)).toString()+"(%ebp)");
		
		stackPos-=4;
		
		/*
		 * 为变量赋初值,因为MiniJool不支持赋初值,所以这步一般到不了
		 */
		if(f.getInitializer()!=null){
			
			f.getInitializer().accept(this);
			codes.add("movl	%eax, "+posTable.get(f.getName().getIdentifier()));
		}
		
		return false;
	}

	public boolean visit(VariableDeclarationStatement s) {
		/*
		 * 处理静态数据
		 */
		if(s.getModifiers()==Modifier.STATIC){
			List l =s.fragments();
			for(Iterator iter = l.iterator();iter.hasNext();){
				VariableDeclarationFragment f = (VariableDeclarationFragment)iter.next();
				/*
				 * 检查变量是否重定义
				 */
				if(posTable.containsKey(f.getName().getIdentifier())){
					SemanticError.error_1_DoubleDeclaration(null,f.getName().getIdentifier());
					//System.err.println("Code generation halted");
					System.exit(0);
				}
				staticdata.add(".lcomm	_"+f.getName().getIdentifier()+", 32");
				sposTable.put(f.getName().getIdentifier(),"_"+f.getName().getIdentifier());
				posTable.put(f.getName().getIdentifier(),"_"+f.getName().getIdentifier());
				stype.put(f.getName().getIdentifier(),s.getType().toString());
				type.put(f.getName().getIdentifier(),s.getType().toString());
			}
			return false;
		}
		
		for(Iterator iter = s.fragments().iterator();iter.hasNext();){
			
			VariableDeclarationFragment frag = (VariableDeclarationFragment)iter.next();
			type.put(frag.getName().getIdentifier(),s.getType().toString());

			codes.add("subl	$4, %esp");
			if(s.getType().toString()=="String"){
				/*
				 * 记录变量在栈中位置
				 */
				posTable.put(frag.getName().getIdentifier(),(new Integer(stackPos)).toString()+"(%ebp)");
				stackPos-=4;
				StringLiteral str=(StringLiteral)frag.getInitializer();
				if(str!=null){
					int index = -1;
					int i=0;
					for(Iterator iter1=strs.iterator();iter1.hasNext();){
						if(((String)iter1.next()).equals(str.getLiteralValue())){
							index=i;
							break;
						}
						i++;
					}
					if(index==-1){
						strs.add(str.getLiteralValue());
						/*
						 * 栈中记录的是字符串保存的地址
						 */
							 
						//codes.add("movl	$LC"+strIndex+", "+(stackPos+4)+"(%ebp)");
						strIndex++;
					}
					else
						codes.add("movl	$LC"+index+", "+(stackPos+4)+"(%ebp)");	
				}
						
					
			}
			else
				frag.accept(this);
			
			
			
		}
		return false;
	}

	public boolean visit(WhileStatement s) {
		codes.add("L"+(jumpNum++)+":");
		s.getExpression().accept(this);
		/*
		 * 检查while语句的判断表达式是否类型为boolean
		 */
		if(!(s.getExpression().getProperty("type").equals("boolean"))){
			SemanticError.error_8_BooleanExpression(null);
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		codes.add("cmpl	$0, %eax");
		codes.add("jne	L"+(jumpNum+1));
		codes.add("jmp	L"+(jumpNum));
		codes.add("L"+(jumpNum+1)+":");
		s.getBody().accept(this);
		codes.add("jmp	L"+(jumpNum-1));
		codes.add("L"+(jumpNum)+":");
		jumpNum+=2;

		return false;
	}
}

⌨️ 快捷键说明

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