📄 codegenerator.java
字号:
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 + -