summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2014-10-29 20:17:43 +0800
committerIru Cai <mytbk920423@gmail.com>2014-10-29 20:17:43 +0800
commita755d814eec72b76e375bae6b8ba5d90809ab40b (patch)
tree7ebb18f7d64af2623f229f6cb983d886256aac7a
parent029d4cf966c21b2ac8d66de27b5bb8187e6b28b6 (diff)
downloadminijava-a755d814eec72b76e375bae6b8ba5d90809ab40b.tar.xz
resolve the extend class message send bug
-rw-r--r--src/minijava/minijava2piglet/Main.java5
-rw-r--r--src/minijava/symboltable/MClass.java59
-rw-r--r--src/minijava/symboltable/MMethodList.java4
3 files changed, 54 insertions, 14 deletions
diff --git a/src/minijava/minijava2piglet/Main.java b/src/minijava/minijava2piglet/Main.java
index 9e8607a..3af3e26 100644
--- a/src/minijava/minijava2piglet/Main.java
+++ b/src/minijava/minijava2piglet/Main.java
@@ -27,6 +27,11 @@ public class Main {
// 建立类的继承关系,寻找循环继承
my_classes.buildClassRelation();
+ // 对每个类,建立其可用方法列表
+ for (int i=0; i<my_classes.mj_classes.size(); i++) {
+ my_classes.mj_classes.elementAt(i).buildMethodRef();
+ }
+
/*
* TODO: Implement your own Visitors and other classes.
*
diff --git a/src/minijava/symboltable/MClass.java b/src/minijava/symboltable/MClass.java
index 0fbe6ce..ae8016e 100644
--- a/src/minijava/symboltable/MClass.java
+++ b/src/minijava/symboltable/MClass.java
@@ -14,12 +14,14 @@ public class MClass extends MLocalVarType {
public MClass extend_class = null; // 所继承的类,在符号表建立完成后才能求得
public int extend_tag = 0; // 检测循环继承时用,0表示未检测
public MMethodList methods;
+ public MMethodList all_methods; // 该类所有方法,包括其父类,考虑方法覆盖
public MClass(String v_name, MClasses all, int m_line, int m_column) {
super(m_line, m_column);
name = v_name;
all_classes = all;
methods = new MMethodList();
+ all_methods = null;
}
public String insertVar(MVariable var) {
@@ -44,6 +46,34 @@ public class MClass extends MLocalVarType {
return null;
}
+ public void buildMethodRef() {
+ if (all_methods!=null) {
+ return;
+ }
+ if (extend_class==null) {
+ all_methods = methods;
+ return;
+ }
+ // now build the all_methods list
+ if (extend_class.all_methods==null) {
+ extend_class.buildMethodRef();
+ }
+ all_methods = new MMethodList();
+ // first copy the list from parent class
+ for (int i=0; i<extend_class.all_methods.size(); i++) {
+ all_methods.methods.addElement(extend_class.all_methods.At(i));
+ }
+ // then insert my methods
+ for (int i=0; i<methods.size(); i++) {
+ int idx = all_methods.findMethod(methods.At(i).name);
+ if (idx!=-1) {
+ all_methods.methods.setElementAt(methods.At(i), idx);
+ } else {
+ all_methods.methods.addElement(methods.At(i));
+ }
+ }
+ }
+
public MMethod findMethodByName(String m) {
int idx = methods.findMethod(m);
if (idx==-1) {
@@ -89,20 +119,12 @@ public class MClass extends MLocalVarType {
}
public int getMethodBinding(String m_name) {
- int prev_funcs = 0;
- for (MClass c=extend_class; c!=null; c=c.extend_class) {
- prev_funcs += c.methods.size();
- }
- int idx = methods.findMethod(m_name);
+ // return the offset of a method with m_name as name
+ int idx = all_methods.findMethod(m_name);
if (idx!=-1) {
- return (prev_funcs+idx)*4;
+ return idx*4;
} else {
- // no such function, find the parentclass
- if (extend_class!=null) {
- return extend_class.getMethodBinding(m_name);
- } else {
- return -1;
- }
+ return -1;
}
}
@@ -113,12 +135,21 @@ public class MClass extends MLocalVarType {
String t_vars = PigletTemp.newTmp();
for (MClass c=this; c!=null; c=c.extend_class) {
- nMethods += c.methods.size();
nVars += c.vars.size();
}
+ nMethods = all_methods.size();
+
result += "\nBEGIN\nMOVE " + t_methods + " HALLOCATE " + nMethods*4
+ "\nMOVE " + t_vars + " HALLOCATE " + (nVars+1)*4 + "\n";
// store all methods
+ for (int i=0; i<nMethods; i++) {
+ MMethod m_method = all_methods.At(i);
+ result += "HSTORE " + t_methods + " " + i*4 + " "
+ + m_method.method_class.getName() + "_"
+ + m_method.getName()
+ + "\n";
+ }
+ /*
for (MClass c=this; c!=null; c=c.extend_class) {
for (int i=c.methods.size()-1; i>=0; i--) {
--nMethods;
@@ -127,7 +158,7 @@ public class MClass extends MLocalVarType {
+ c.methods.methods.elementAt(i).getName()
+ "\n";
}
- }
+ }*/
result += "HSTORE " + t_vars + " 0 " + t_methods + "\n";
result += "RETURN " + t_vars + "\nEND";
return result;
diff --git a/src/minijava/symboltable/MMethodList.java b/src/minijava/symboltable/MMethodList.java
index 01bef3c..12d97cf 100644
--- a/src/minijava/symboltable/MMethodList.java
+++ b/src/minijava/symboltable/MMethodList.java
@@ -25,4 +25,8 @@ public class MMethodList extends MType {
public int size() {
return methods.size();
}
+
+ public MMethod At(int i) {
+ return methods.elementAt(i);
+ }
}