summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2014-10-25 16:54:18 +0800
committerIru Cai <mytbk920423@gmail.com>2014-10-25 16:54:18 +0800
commit60710cc10b1be037d3246083c104997d34f75b6a (patch)
tree074838261b3b7b679ce454ed22aba78e9453f09c
parent059478c79945c65a27cc9e45fb3d4244053fbdec (diff)
downloadminijava-60710cc10b1be037d3246083c104997d34f75b6a.tar.xz
Add functions for getting binding
-rw-r--r--src/minijava/symboltable/MClass.java78
-rw-r--r--src/minijava/symboltable/MMethod.java46
2 files changed, 123 insertions, 1 deletions
diff --git a/src/minijava/symboltable/MClass.java b/src/minijava/symboltable/MClass.java
index 10354a8..ec57c19 100644
--- a/src/minijava/symboltable/MClass.java
+++ b/src/minijava/symboltable/MClass.java
@@ -3,6 +3,8 @@
*/
package minijava.symboltable;
+import minijava.minijava2piglet.PigletBinding;
+import minijava.minijava2piglet.PigletTemp;
import minijava.typecheck.PrintError;
public class MClass extends MLocalVarType {
@@ -42,6 +44,82 @@ public class MClass extends MLocalVarType {
return null;
}
+ public MMethod findMethodByName(String m) {
+ int idx = methods.findMethod(m);
+ if (idx==-1) {
+ return null;
+ } else {
+ return methods.methods.elementAt(idx);
+ }
+ }
+
+ public PigletBinding getVarBinding(String v_name) {
+ int prev_vars = 0;
+ for (MClass c=extend_class; c!=null; c=c.extend_class) {
+ prev_vars += c.vars.size();
+ }
+ int idx = vars.findVar(v_name);
+ if (idx!=-1) {
+ String tmp = PigletTemp.newTmp();
+ PigletBinding ret = new PigletBinding(null, null);
+ ret.read = "\nBEGIN\nHLOAD " + tmp + " TEMP 0 " + (prev_vars+idx+1)*4
+ + "\nRETURN " + tmp + "\nEND";
+ ret.write = "TEMP 0 " + (prev_vars+idx+1)*4;
+ return ret;
+ }
+ // no such variable, find the parentclss
+ if (extend_class!=null) {
+ return extend_class.getVarBinding(v_name);
+ } else {
+ return null;
+ }
+ }
+
+ 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);
+ if (idx!=-1) {
+ return (prev_funcs+idx)*4;
+ } else {
+ // no such function, find the parentclass
+ if (extend_class!=null) {
+ return extend_class.getMethodBinding(m_name);
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ public String newString() {
+ int nMethods = 0, nVars = 0;
+ String result = "";
+ String t_methods = PigletTemp.newTmp();
+ String t_vars = PigletTemp.newTmp();
+
+ for (MClass c=this; c!=null; c=c.extend_class) {
+ nMethods += c.methods.size();
+ nVars += c.vars.size();
+ }
+ result += "\nBEGIN\nMOVE " + t_methods + " HALLOCATE " + nMethods*4
+ + "\nMOVE " + t_vars + " HALLOCATE " + (nVars+1)*4 + "\n";
+ // store all methods
+ for (MClass c=this; c!=null; c=c.extend_class) {
+ for (int i=c.methods.size()-1; i>=0; i--) {
+ --nMethods;
+ result += "HSTORE " + t_methods + " " + nMethods*4 + " "
+ + c.getName() + "_"
+ + c.methods.methods.elementAt(i).getName()
+ + "\n";
+ }
+ }
+ result += "HSTORE " + t_vars + " 0 " + t_methods + "\n";
+ result += "RETURN " + t_vars + "\nEND";
+ return result;
+ }
+
// 检测类型名是否有效
public boolean validType(String s_type) {
if (s_type==MIdentifier.intType
diff --git a/src/minijava/symboltable/MMethod.java b/src/minijava/symboltable/MMethod.java
index 9e770a3..fc70bdb 100644
--- a/src/minijava/symboltable/MMethod.java
+++ b/src/minijava/symboltable/MMethod.java
@@ -1,14 +1,20 @@
package minijava.symboltable;
+import java.util.HashMap;
+import java.util.Map;
+
+import minijava.minijava2piglet.PigletBinding;
+import minijava.minijava2piglet.PigletTemp;
import minijava.typecheck.PrintError;
public class MMethod extends MLocalVarType {
MVarList params;
public String ret_type_name;
public MClass method_class;
- MVarList paramList;
+ public MVarList paramList;
public MStatementList statements;
public MExpression ret_expr;
+ public HashMap<String, String> varBinding;
public MMethod(String m_name, String ret_type, int m_line, int m_column) {
super(m_line, m_column);
@@ -109,6 +115,44 @@ public class MMethod extends MLocalVarType {
return null;
}
+ // generate local variable bindings, call it when visitor visits the method
+ public void genLocalVarBindings() {
+ varBinding = new HashMap<String, String>();
+ for (int i=0; i<vars.size(); i++) {
+ varBinding.put(vars.varlist.elementAt(i).getName(), PigletTemp.newTmp());
+ }
+ }
+
+ // get a binding, call it when visitor visits a statement
+ public PigletBinding getBinding(String id) {
+ String result;
+ result = varBinding.get(id);
+ if (result!=null) {
+ return new PigletBinding(result, null);
+ }
+ // not in local variables, then find paramlist
+ for (int i=0; i<paramList.size(); i++) {
+ if (paramList.varlist.elementAt(i).name.equals(id)) {
+ if (i<18 || paramList.size()<20) {
+ result = "TEMP "+(i+1);
+ return new PigletBinding(result, null);
+ } else {
+ // >=20 parameters, the last parameter should be a pointer to
+ // the rest parameters
+ int restidx = i-18;
+ String tmp = PigletTemp.newTmp();
+ PigletBinding ret = new PigletBinding(null, null);
+ ret.read = "BEGIN\nHLOAD " + tmp +
+ " TEMP 19 " + restidx + "RETURN " + tmp + "\nEND";
+ ret.write = "TEMP 19 " + restidx;
+ return ret;
+ }
+ }
+ }
+ // not in paramList either, check for the class
+ return method_class.getVarBinding(id);
+ }
+
public void checkStatements() {
statements.checkStatements(this);
// 检查返回类型是否和返回值匹配