📄 codegenerator.java
字号:
package edu.ustc.cs.minijool.parser;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
public class CodeGenerator extends GenericVisitor {
private PrintStream out;
private List strs = new ArrayList();
private int strIndex = 2;
private List codes = new ArrayList();
private List staticdata=new ArrayList();
private int jumpNum = 2 ;//为跳转命名之用
private int paraNum;
private int stackPos = -4;//记录当前函数中局部变量在栈中的偏移
private Map posTable=null;//存储变量与他的存储位置(String)之间的对应
private Map type = new HashMap();//记录变量的类型
private Map sposTable = new HashMap();//记录静态数据
private Map stype = new HashMap();
private int classNum = 0;
private int mainNum = 0;
private Map methods = new HashMap();
private MethodDeclaration now;
public CodeGenerator(PrintStream out) {
if(out != null) {
this.out = out;
} else {
this.out = System.out;
}
posTable = new HashMap();
}
public void emitCode() {
//字符串常量数据输出
/*out.println(".text");
out.println(".def ___main; .scl 2; .type 32; .endef");
int i=0;
out.println("LC"+(i++)+":");
out.println("\t.ascii \"%s\\12\\0\"");
out.println("LC"+(i++)+":");
out.println("\t.ascii \"%d\\12\\0\"");
for(Iterator iter=strs.iterator();iter.hasNext();){
out.println("LC"+(i++)+":");
out.println("\t.ascii \""+(String)(iter.next())+"\\0\"");
}
*/
//代码部分输出
for(Iterator iter=codes.iterator();iter.hasNext();)
out.println("\t"+iter.next());
// 静态数据部分输出
for(Iterator iter=staticdata.iterator();iter.hasNext();)
out.println("\t"+iter.next());
}
public boolean visit(Assignment a) {
/*
* 将赋值语句右边的表达式值计算出后放入
*/
/*
* 检查赋值语句的左边的标识符是否已经定义(因为SimpleName中的
* 检查不到这个位置的标识符使用)
*/
if(!posTable.containsKey(((SimpleName)a.getLeftHandSide()).getIdentifier())){
SemanticError.error_2_NoDeclaration(null,((SimpleName)a.getLeftHandSide()).getIdentifier());
//System.err.println("Code generation halted");
System.exit(0);
}
a.getRightHandSide().accept(this);
/*
* 检查赋值语句两边的类型是否相同
*/
if(!(a.getRightHandSide().getProperty("type").equals(type.get(((SimpleName)a.getLeftHandSide()).getIdentifier())))){
SemanticError.error_12_AssignmentType(null);
//System.err.println("Code generation halted");
System.exit(0);
}
/*
* 寻找赋值语句左边变量的存储位置
*/
String position = (String)posTable.get(((SimpleName)a.getLeftHandSide()).getIdentifier());
//codes.add("movl %eax, "+position);
return false;
}
public boolean visit(Block b) {
for(Iterator iter = b.statements().iterator();iter.hasNext();)
((Statement)iter.next()).accept(this);
return false;
}
public boolean visit(BooleanLiteral e) {
int num = 0;
if(e.booleanValue())
num = 1;
//codes.add("movl $"+num+", %eax");
e.setProperty("type","boolean");
return false;
}
public boolean visit(ClassInstanceCreation e) {
//TODO:Lab5
return false;
}
public boolean visit(ExpressionStatement s) {
s.getExpression().accept(this);
return false;
}
public boolean visit(FieldAccess e) {
//TODO:Lab5
return false;
}
public boolean visit(FieldDeclaration d) {
//assert d.getModifiers()==Modifier.STATIC;
List l = d.fragments();
/*for(Iterator iter = l.iterator();iter.hasNext();){
VariableDeclarationFragment f = (VariableDeclarationFragment)iter.next();
staticdata.add(".lcomm _"+f.getName().getIdentifier()+", 32");
sposTable.put(f.getName().getIdentifier(),"_"+f.getName().getIdentifier());
stype.put(f.getName().getIdentifier(),d.getType().toString());
}*/
return false;
}
public boolean visit(IfStatement s) {
s.getExpression().accept(this);
/*
* 检查if语句中的判断表达式的类型是否为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("je L"+jumpNum);
s.getThenStatement().accept(this);
if(s.getElseStatement()!=null)
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
if(s.getElseStatement()!=null){
s.getElseStatement().accept(this);
//codes.add("L"+(jumpNum++)+":");
}
return false;
}
public boolean visit(InfixExpression e) {
e.getLeftOperand().accept(this);//计算左边,值在eax中
codes.add("movl %eax, %ecx");//将左表达式值移到ecx中
e.getRightOperand().accept(this);//计算右边
if (e.getOperator() == InfixExpression.Operator.PLUS) {
//codes.add("addl %ecx, %eax");
/*
* 检查操作符+的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","int");
} else if (e.getOperator() == InfixExpression.Operator.MINUS) {
codes.add("subl %ecx, %eax");
/*
* 检查操作符-的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","int");
} else if (e.getOperator() == InfixExpression.Operator.TIMES) {
codes.add("imull %ecx, %eax");
/*
* 检查操作符×的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","int");
} else if (e.getOperator() == InfixExpression.Operator.DIVIDE) {
//codes.add("movl %eax, %edx");
//codes.add("movl %ecx, %eax");
//codes.add("movl %edx, %ecx");
//codes.add("cltd");
//codes.add("idivl %ecx");
/*
* 检查操作符/的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","int");
} else if (e.getOperator() == InfixExpression.Operator.CONDITIONAL_AND){
codes.add("and %ecx, %eax");
/*
* 检查操作符&&的两边操作数是否为boolean类型
*/
if(!e.getLeftOperand().getProperty("type").equals("boolean")||!e.getRightOperand().getProperty("type").equals("boolean")){
SemanticError.error_11_CondTypes(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.CONDITIONAL_OR){
//codes.add("or %ecx, %eax");
/*
* 检查操作符||的两边操作数是否为boolean类型
*/
if(!e.getLeftOperand().getProperty("type").equals("boolean")||!e.getRightOperand().getProperty("type").equals("boolean")){
SemanticError.error_11_CondTypes(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.EQUALS){
//codes.add("cmpl %ecx, %eax");
//codes.add("je L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符==的两边操作数类型是否相同
*/
if(!e.getLeftOperand().getProperty("type").equals(e.getRightOperand().getProperty("type"))){
SemanticError.error_10_EqConformingTypes(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.GREATER){
//codes.add("cmpl %ecx, %eax");
//codes.add("jg L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符>的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.GREATER_EQUALS){
//codes.add("cmpl %ecx, %eax");
//codes.add("jge L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符>=的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.LESS){
//codes.add("cmpl %ecx, %eax");
//codes.add("jl L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符<的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.LESS_EQUALS){
//codes.add("cmpl %ecx, %eax");
//codes.add("jle L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符<=的两边操作数是否为int类型
*/
if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
SemanticError.error_9_IntExpression(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else if (e.getOperator() == InfixExpression.Operator.NOT_EQUALS){
//codes.add("cmpl %ecx, %eax");
//codes.add("jne L"+jumpNum);
//codes.add("movl $0, %eax");
//codes.add("jmp L"+(jumpNum+1));
//codes.add("L"+(jumpNum++)+":");
//codes.add("movl $1, %eax");
//codes.add("L"+(jumpNum++)+":");
/*
* 检查操作符!=的两边操作数类型是否相同
*/
if(!e.getLeftOperand().getProperty("type").equals(e.getRightOperand().getProperty("type"))){
SemanticError.error_10_EqConformingTypes(null);
//System.err.println("Code generation halted");
System.exit(0);
}
e.setProperty("type","boolean");
} else {
throw new RuntimeException("Unknown Operator: "
+ e.getOperator().toString());
}
return false;
}
public boolean visit(MethodDeclaration m) {
stackPos=-4;//复位
posTable.clear();//将记录临时变量的栈表置空
type.clear();
posTable.putAll(sposTable);
type.putAll(stype);
now = m;
codes.add(".align 2");
/*
* main函数单独处理
*/
if(m.getName().getIdentifier().equals("Main")){
mainNum++;
/*
* 检查Main函数是否被定义了两次或者两次以上
*/
if(mainNum>1){
SemanticError.error_1_DoubleDeclaration(null,"Main");
//System.err.println("Code generation halted");
System.exit(0);
}
/*
* 检查主函数类型是否为static
*/
if(m.getModifiers()!=Modifier.STATIC){
SemanticError.error_3_ProgramClassError(null);
//System.err.println("Code generation halted");
System.exit(0);
}
/*codes.add(".global _main");
codes.add(".def _main; .scl 2; .type 32; .endef");
codes.add("_main:");
codes.add("pushl %ebp");
codes.add("movl %esp, %ebp");
codes.add("subl $24, %esp");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -