diff options
author | Iru Cai <mytbk920423@gmail.com> | 2014-10-25 16:54:18 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2014-10-25 16:54:18 +0800 |
commit | 60710cc10b1be037d3246083c104997d34f75b6a (patch) | |
tree | 074838261b3b7b679ce454ed22aba78e9453f09c | |
parent | 059478c79945c65a27cc9e45fb3d4244053fbdec (diff) | |
download | minijava-60710cc10b1be037d3246083c104997d34f75b6a.tar.xz |
Add functions for getting binding
-rw-r--r-- | src/minijava/symboltable/MClass.java | 78 | ||||
-rw-r--r-- | src/minijava/symboltable/MMethod.java | 46 |
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); // 检查返回类型是否和返回值匹配 |