summaryrefslogtreecommitdiff
path: root/src/minijava/symboltable/MStatement.java
blob: 5169097c895cd6ba54c671c14f1dbc1aa5a26391 (plain)
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;
		}
	}

}