From 60710cc10b1be037d3246083c104997d34f75b6a Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Sat, 25 Oct 2014 16:54:18 +0800 Subject: Add functions for getting binding --- src/minijava/symboltable/MClass.java | 78 +++++++++++++++++++++++++++++++++++ src/minijava/symboltable/MMethod.java | 46 ++++++++++++++++++++- 2 files changed, 123 insertions(+), 1 deletion(-) 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 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(); + for (int i=0; i=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); // 检查返回类型是否和返回值匹配 -- cgit v1.2.3