summaryrefslogtreecommitdiff
path: root/src/minijava/symboltable
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2014-10-13 07:34:34 +0800
committerIru Cai <mytbk920423@gmail.com>2014-10-13 07:34:34 +0800
commit92f91d3e9bce1aaf581baa9339744266d7eb0c1a (patch)
treeb179091deae37958f92294a4079b65c5519c7752 /src/minijava/symboltable
parent31aac86103f0c05fbaaf1e690ec27b23cfeea9c0 (diff)
downloadminijava-92f91d3e9bce1aaf581baa9339744266d7eb0c1a.tar.xz
final version
Diffstat (limited to 'src/minijava/symboltable')
-rw-r--r--src/minijava/symboltable/MClasses.java3
-rw-r--r--src/minijava/symboltable/MExpression.java17
-rw-r--r--src/minijava/symboltable/MMethod.java33
-rw-r--r--src/minijava/symboltable/MPrimaryExpr.java4
-rw-r--r--src/minijava/symboltable/MStatement.java22
5 files changed, 70 insertions, 9 deletions
diff --git a/src/minijava/symboltable/MClasses.java b/src/minijava/symboltable/MClasses.java
index 10bd009..34601a5 100644
--- a/src/minijava/symboltable/MClasses.java
+++ b/src/minijava/symboltable/MClasses.java
@@ -46,6 +46,9 @@ public class MClasses extends MType {
String ext_name = m_class.extend_class_name;
if (ext_name!=null) {
m_class.extend_class = findClassByName(ext_name);
+ if (m_class.extend_class==null) {
+ PrintError.print(m_class.line, m_class.column, "Extend class not exist!");
+ }
}
}
int tag = 1; // 扫描循环继承的标记
diff --git a/src/minijava/symboltable/MExpression.java b/src/minijava/symboltable/MExpression.java
index 4cf4724..a5dc0ba 100644
--- a/src/minijava/symboltable/MExpression.java
+++ b/src/minijava/symboltable/MExpression.java
@@ -76,7 +76,15 @@ public class MExpression extends MType {
PrintError.print(line, column, "no class found in a message send expression");
return null;
}
- int idx = m_class.methods.findMethod(e_id.name);
+ int idx=-1;
+ while (m_class!=null) {
+ idx = m_class.methods.findMethod(e_id.name);
+ if (idx==-1) {
+ m_class = m_class.extend_class; // 本类无该方法,从父类继续找
+ } else {
+ break;
+ }
+ }
if (idx==-1) {
PrintError.print(line, column, "method " + e_id.name + " not found");
return null;
@@ -141,6 +149,13 @@ public class MExpression extends MType {
System.err.print("]");
case ArrayLen:
case MsgSend:
+ first.printExpr(0);
+ System.err.print("."+e_id.name+"(");
+ for (int i=0; i<e_list.size(); i++) {
+ if (i>0) System.err.print(",");
+ e_list.e_list.elementAt(i).printExpr(0);
+ }
+ System.err.print(")");
}
}
}
diff --git a/src/minijava/symboltable/MMethod.java b/src/minijava/symboltable/MMethod.java
index 2d2dc24..9e770a3 100644
--- a/src/minijava/symboltable/MMethod.java
+++ b/src/minijava/symboltable/MMethod.java
@@ -4,7 +4,7 @@ import minijava.typecheck.PrintError;
public class MMethod extends MLocalVarType {
MVarList params;
- String ret_type_name;
+ public String ret_type_name;
public MClass method_class;
MVarList paramList;
public MStatementList statements;
@@ -74,9 +74,10 @@ public class MMethod extends MLocalVarType {
if (idx!=-1) {
// 找到同名方法,检测是否能覆盖
if (this.ret_type_name.
- equals(m_class.methods.methods.elementAt(idx))==false) {
+ equals(m_class.methods.methods.elementAt(idx).ret_type_name)==false) {
PrintError.print(line, column, "Method " +
- this.name + " has type different from the one in its parent class");
+ this.name + " has type different from the one in its parent class "
+ + m_class.name);
return false;
}
}
@@ -95,15 +96,37 @@ public class MMethod extends MLocalVarType {
if (idx!=-1) {
return paramList.varlist.elementAt(idx);
}
- idx = method_class.vars.findVar(s);
+ MClass m_class = method_class;
+ idx = m_class.vars.findVar(s);
+ while (idx==-1 && m_class.extend_class!=null) {
+ // 在父类继续查找
+ m_class = m_class.extend_class;
+ idx = m_class.vars.findVar(s);
+ }
if (idx!=-1) {
- return method_class.vars.varlist.elementAt(idx);
+ return m_class.vars.varlist.elementAt(idx);
}
return null;
}
public void checkStatements() {
statements.checkStatements(this);
+ // 检查返回类型是否和返回值匹配
+ if (ret_type_name==MIdentifier.voidType && ret_expr==null) {
+ // ok
+ } else if (!ret_type_name.equals(ret_expr.exprType(this))) {
+ MClasses all = this.method_class.all_classes;
+ MClass t1 = all.findClassByName(ret_type_name);
+ MClass t2 = all.findClassByName(ret_expr.exprType(this));
+ if (t1!=null) {
+ while (t2!=null && t2!=t1) {
+ t2 = t2.extend_class;
+ }
+ }
+ if (t1!=t2) {
+ PrintError.print(line, column, "return expression and return type mismatch!");
+ }
+ }
}
public void printMethod(int spaces) {
diff --git a/src/minijava/symboltable/MPrimaryExpr.java b/src/minijava/symboltable/MPrimaryExpr.java
index ba233b5..246ac93 100644
--- a/src/minijava/symboltable/MPrimaryExpr.java
+++ b/src/minijava/symboltable/MPrimaryExpr.java
@@ -44,6 +44,10 @@ public class MPrimaryExpr extends MType {
case Alloc:
return e_id.getName();
case ArrayAlloc:
+ if (e_exp.exprType(m)!=MIdentifier.intType) {
+ PrintError.print(getLine(), getColumn(), "wrong type of expression in array alloc");
+ return null;
+ }
return MIdentifier.arrType;
case Braket:
return e_exp.exprType(m);
diff --git a/src/minijava/symboltable/MStatement.java b/src/minijava/symboltable/MStatement.java
index 3610719..5169097 100644
--- a/src/minijava/symboltable/MStatement.java
+++ b/src/minijava/symboltable/MStatement.java
@@ -36,13 +36,29 @@ public class MStatement extends MType {
case Assign:
// id = expr
MVariable m_var = m.findVarByName(s_id.name);
+ String expr_type = e_first.exprType(m);
+ //System.err.println(s_id.name + " " + expr_type);
if (m_var==null) {
PrintError.print(line, column, "variable "+s_id.name+" not exist!");
return;
- } else if (m_var.typename.equals(e_first.exprType(m))) {
+ } else if (m_var.typename.equals(expr_type)) {
return;
} else {
- PrintError.print(line, column, "type mismatch in assign statement");
+ MClasses all = m.method_class.all_classes;
+ MClass id_class = all.findClassByName(m_var.typename);
+ MClass expr_class = all.findClassByName(expr_type);
+ if (id_class==null) { // id本身不是类
+ PrintError.print(line, column, "type mismatch in assign statement");
+ return;
+ }
+ while (expr_class!=id_class && expr_class!=null) { // 从expr的类找父类
+ expr_class = expr_class.extend_class;
+ }
+ if (expr_class!=id_class) {
+ PrintError.print(line, column, "type mismatch in assign statement");
+ } else {
+ return;
+ }
}
break;
case Block:
@@ -57,7 +73,7 @@ public class MStatement extends MType {
}
break;
case Print:
- if (e_first.exprType(m)!=null) {
+ if (e_first.exprType(m)==MIdentifier.intType) {
return;
} else {
PrintError.print(line, column, "Invalid type in print statement");