1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
package minijava.symboltable;
import minijava.typecheck.PrintError;
public class MStatement extends MType {
public enum Keyword {
Block, Assign, ArrAssign, If, While, Print;
}
Keyword s_type;
public MStatementList s_list; // for block statement
public MIdentifier s_id; // for assign, array assign
public MExpression e_first, e_second; // for assign(e_first), array assign, if, while, print
public MStatement s_first, s_second; // for if, while
public MStatement(int s_line, int s_column, Keyword keyw) {
super(s_line, s_column);
s_type = keyw;
s_list = null;
s_id = null;
e_first = e_second = null;
s_first = s_second = null;
}
public void checkStatement(MMethod m) {
switch (s_type) {
case ArrAssign:
// id[expr] = expr
if (m.findVarByName(s_id.name).typename==MIdentifier.arrType
&& e_first.exprType(m)==MIdentifier.intType
&& e_second.exprType(m)==MIdentifier.intType) {
return;
} else {
PrintError.print(line, column, "type mismatch in array assign statement");
}
break;
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(expr_type)) {
return;
} else {
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:
s_list.checkStatements(m);
break;
case If:
if (e_first.exprType(m)==MIdentifier.boolType) {
s_first.checkStatement(m);
s_second.checkStatement(m);
} else {
PrintError.print(line, column, "invalid type in if statement.");
}
break;
case Print:
if (e_first.exprType(m)==MIdentifier.intType) {
return;
} else {
PrintError.print(line, column, "Invalid type in print statement");
}
break;
case While:
// while (expr) state
if (e_first.exprType(m)==MIdentifier.boolType) {
s_first.checkStatement(m);
} else {
PrintError.print(line, column, "invalid type in while statement.");
}
break;
default:
break;
}
}
public void printStatement(int spaces) {
String sp = OutputFormat.spaces(spaces);
switch (s_type) {
case Block:
System.err.println(sp+"Block statement:");
break;
case Assign:
System.err.print(sp+"="+" ("+s_id.getName()+") (");
e_first.printExpr(0);
System.err.println(")");
break;
case ArrAssign:
System.err.println(sp+"[]= ("+s_id.getName()+") (");
e_first.printExpr(0);
System.err.print(") (");
e_second.printExpr(0);
System.err.println(")");
break;
case If:
System.err.println(sp+"if (");
e_first.printExpr(0);
System.err.println(")");
s_first.printStatement(spaces+2);
s_second.printStatement(spaces+2);
break;
case While:
System.err.println(sp+"while (");
e_first.printExpr(0);
System.err.println(")");
s_first.printStatement(spaces+2);
break;
case Print:
System.err.println(sp+"print (");
e_first.printExpr(0);
System.err.println(")");
break;
}
}
}
|