Initial implementation of symbols and scopes with symbol table.
[charm.git] / src / langs / charj / src / charj / translator / SymbolWithScope.java
1
2 package charj.translator;
3
4 import java.util.Map;
5
6 public abstract class SymbolWithScope 
7     extends Symbol 
8     implements Scope {
9
10     public SymbolWithScope(SymbolTable symtab) 
11     {
12         super(symtab);
13     }
14
15     public SymbolWithScope(
16             SymbolTable symtab, 
17             String name) 
18     {
19         super(symtab, name, null);
20     }
21
22     /** Find any symbol matching name; won't look on disk for classes though */
23     public Symbol resolve(String name) 
24     {
25         Symbol s = null;
26         
27         // in this scope?
28         if ( getMembers()!=null ) {
29             s = (Symbol)getMembers().get(name);
30         }
31
32         // if not, check any enclosing scope
33         if ( s==null && getEnclosingScope() != null ) 
34         {
35             return getEnclosingScope().resolve(name);
36         }
37
38         return s;
39     }
40
41     /** Scopes other other package and class don't know how to resolve types
42      *  (e.g., MethodSymbol).  Look to enclosing scope.
43      */
44     public ClassSymbol resolveType(String type) 
45     {
46         if ( getEnclosingScope()!=null ) {
47             return getEnclosingScope().resolveType(type);
48         }
49         return null;
50     }
51
52     public VariableSymbol resolveVariable(String name) 
53     {
54         Symbol s = getMembers().get(name);
55         if (debug()) System.out.println(
56                 "SymbolWithScope.resolveVariable(" + name + 
57                 "): examine " + this.getClass().getName() + "=" + toString());
58         
59         // found it
60         if (s != null && s.getClass() == VariableSymbol.class) {
61             if (debug()) System.out.println(
62                     "SymbolWithScope.resolveVariable(" + name + ") found in " +
63                     this.getClass().getName() + "=" + toString());
64             return (VariableSymbol)s;
65         }
66
67         // not here, check enclosing scope
68         if ( s==null && getEnclosingScope() != null ) {
69             return getEnclosingScope().resolveVariable(name);
70         }
71
72         // not a variable
73         if (debug()) System.out.println(
74                 "SymbolWithScope.resolveVariable(" + name + 
75                 "): not a variable in " + this.getClass().getName() + 
76                 "=" + toString());
77         return null;
78     }
79
80     public MethodSymbol resolveMethod(
81             String name, 
82             int numargs) 
83     {
84         if (debug()) System.out.println(
85                 "SymbolWithScope.resolveMethod(" + name + "," + numargs +
86                 "): examine " + this.getClass().getName() + "=" + toString());
87         
88         Symbol s = null;
89         if ( numargs == 0 ) {
90             s = resolve(name);
91         } else {
92             s = resolve(name+numargs);
93         }
94
95         if ( s!=null && debug() ) System.out.println(
96                 "SymbolWithScope.resolveMethod(" + name + "," + numargs +
97                 "): found in context " + this.getClass().getName() +
98                 "=" + toString());
99         else if ( s==null && debug() ) System.out.println(
100                 "SymbolWithScope.resolveMethod(" + name + "," + numargs +
101                 "): not found in context " + this.getClass().getName() + 
102                 "="+toString());
103         
104         if ( s==null || (s!=null && s.getClass() != MethodSymbol.class) ) {
105             // not a method
106             if ( s!=null && debug() ) System.out.println(
107                     "SymbolWithScope.resolveMethod(" + name + "," + numargs +
108                     "): not a method");
109             return null;         
110         }
111         return (MethodSymbol)s;
112     }
113
114     /** By default, pass up responsibility in scope hierarchy until we
115      *  find a class.
116      */
117     public boolean isMethod(String name) 
118     {
119         if ( getEnclosingScope()!=null ) {
120             return getEnclosingScope().isMethod(name);
121         }
122         return false;
123     }
124
125     public Symbol remove(String name) 
126     {
127         Symbol s = (Symbol)getMembers().get(name);
128         if ( s==null && getEnclosingScope() != null) {
129             return getEnclosingScope().remove(name);
130         }
131         if ( s != null) {
132             getMembers().remove(name);
133         }
134         return s;
135     }
136
137     public Symbol define(
138             String name, 
139             Symbol sym) 
140     {
141         // check for error
142         Map members = getMembers();
143         if ( members == null ) {
144             members = createMembers();
145         }
146         members.put(name, sym);
147         sym.scope = this; // track the scope in each symbol
148         
149         if (debug()) System.out.println("define " + name + " as " + sym);
150         return sym;
151     }
152
153     /** create the member list; we're about to add stuff */
154     protected Map<String, Symbol> createMembers() 
155     {
156         return getMembers();
157     }
158
159     /** Scope defaults to just the symbol name; method f's scope is f by 
160      *  default. 
161      */
162     public String getScopeName() 
163     {
164         return name;
165     }
166
167     public String getFullyQualifiedName() 
168     {
169         String parent = null;
170         if ( getEnclosingScope()!=null ) {
171             parent = getEnclosingScope().getFullyQualifiedName();
172         }
173         if ( parent!=null ) {
174             return parent + "::" + name;
175         }
176         return name;
177     }
178
179     public String getFullyQualifiedJavaName() 
180     {
181         String parent = null;
182         if ( getEnclosingScope()!=null ) {
183             parent = getEnclosingScope().getFullyQualifiedJavaName();
184         }
185         if ( parent!=null ) {
186             return parent + "." + name;
187         }
188         return name;
189     }
190 }