forked from csaroff/MiniJava-Compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKlass.java
More file actions
152 lines (135 loc) · 4.3 KB
/
Copy pathKlass.java
File metadata and controls
152 lines (135 loc) · 4.3 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import java.util.*;
import org.objectweb.asm.*;
/**
* A symbol-table representation of a type.
*/
public class Klass implements Scope{
//The type that this class directly extends,
//or null if it extends Object or isn't a reference type.
private Klass superKlass;
//The name of this Klass.
private String name;
//The symbol table containing all fields and methods.
//Methods in this symbol table always have a () on the
//end of their name to distinguish them from variables.
//eg.
//int f;
//is different and distinguishable from
//int f(){
// return 0;
//}
private Map<String, Symbol> symTable = new HashMap<String, Symbol>();
/**
* Constructs a new Klass with the given name
* @param name The name of the class that you are representing
*/
public Klass(String name){
this.name = name;
}
/**
* sets the superclass of this klass
* @param superKlass the super of this klass
*/
public void setSuperKlass(Klass superKlass){
this.superKlass = superKlass;
}
/**
* @return the symbol-table representation of this klass's superclass
*/
public Klass getSuperKlass(){
return this.superKlass;
}
@Override public String getScopeName(){
return name;
}
/** This is the highest scope level, so this method returns null. */
@Override public Scope getEnclosingScope(){return null;}
/**
* Define a symbol in the current scope
* @param sym The symbol that you want to define.
*/
@Override public void define(Symbol sym){
symTable.put(sym.getName(), sym);
}
/**
* Since all fields of a class are initialized to 0,
* false or null by default, this method should never be called.
*/
@Override public void initialize(Symbol sym){
assert false;
}
/**
* @param other the klass that may be this klass's ancestor
* @return true if this klass is a descendant(direct or indirect) of other, false otherwise
*/
public boolean isDescendantOf(Klass other){
if(this.superKlass==null&&other!=this){
return false;
}else if(other==this){
return true;
}else{
return this.superKlass.isDescendantOf(other);
}
}
/**
* Searches this klass for a symbol with the given name.
* If no such symbol exists,
* returns getSuperKlass()==null? null : getSuperKlass().lookup(name)
* @param name The name of the symbol to search for
* @return the symbol with symbolName equal to name.
*/
@Override public Symbol lookup(String name){
Symbol symbol = null;
for(Klass klass = this; symbol==null&&klass!=null; klass=klass.getSuperKlass()){
symbol = klass.symTable.get(name);
}
return symbol;
}
/**
* Searches this klass for a symbol with the given name.
* If no such symbol exists, return null.
* @param name The name of the symbol to search for.
* @return the symbol with the given name, or null if no such symbol exists.
*/
@Override public Symbol lookupLocally(String name){
return symTable.get(name);
}
/**
* Since all field variables are intialized upon construction of an object,
* this method returns true if this.lookup(name)!=null
* and false otherwise.
* @param name The name of the symbol to search for.
* @return true if this klass contains the field with the given name.
*/
@Override public boolean hasBeenInitialized(String name){
return this.lookup(name)!=null;
}
/**
* This method should never be called.
* @return null
*/
@Override public Set<Symbol> getInitializedVariables(){
assert false;
return null;
}
/**
* @return The name of this klass
*/
public String toString(){
return name;
}
/**
* @return an asm Type representation of this class.
*/
public Type asAsmType(){
if(this.name.equals("int")){
return Type.INT_TYPE;
}else if(this.name.equals("boolean")){
return Type.BOOLEAN_TYPE;
}else if(this.name.equals("int[]")){
return Type.getType(int[].class);
}else{
return Type.getType("L" + this.name + ";");
}
}
}