diff options
Diffstat (limited to 'src/minijava/symboltable/MMethod.java')
-rw-r--r-- | src/minijava/symboltable/MMethod.java | 46 |
1 files changed, 45 insertions, 1 deletions
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); // 检查返回类型是否和返回值匹配 |