66ed97b843905e56801eecc909ec7b14ab8703a0
[charm.git] / src / langs / charj / src / charj / translator / SymbolDefiner.g
1
2 tree grammar SymbolDefiner;
3
4 options {
5     tokenVocab = Charj;
6     ASTLabelType = CharjAST;
7     filter = true;
8 }
9
10 @header {
11 package charj.translator;
12 }
13
14 @members {
15     SymbolTable symtab;
16     Scope currentScope;
17     ClassSymbol currentClass;
18     AstModifier astmod = new AstModifier();
19
20     public SymbolDefiner(TreeNodeStream input, SymbolTable symtab) {
21         this(input);
22         this.symtab = symtab;
23         this.currentScope = symtab.getDefaultPkg();
24     }
25 }
26
27
28 topdown
29     :   enterPackage
30     |   enterClass
31     |   enterMethod
32     |   enterBlock
33     |   varDeclaration
34     |   type
35     |   atoms
36     ;
37
38 bottomup
39     :   exitClass
40     |   exitMethod
41     |   exitBlock
42     ;
43
44 enterPackage
45 @init {
46     List<String> names = null;
47     String packageName = "";
48 }
49     :   ^(PACKAGE ((ids+=IDENT) { packageName += "." + $IDENT.text; })+)
50         {
51             packageName = packageName.substring(1);
52             PackageScope ps = symtab.resolvePackage(packageName);
53             if (ps == null) {
54                 ps = symtab.definePackage(packageName);
55                 symtab.addScope(ps);
56             }
57             currentScope = ps;
58         }
59     ;
60
61 enterBlock
62     :   BLOCK {
63             currentScope = new LocalScope(symtab, currentScope);
64         }
65     ;
66
67 exitBlock
68     :   BLOCK {
69             //System.out.println("exiting block scope, members: " + currentScope);
70             currentScope = currentScope.getEnclosingScope();
71         }
72     ;
73
74 enterMethod
75 @init {
76 boolean entry = false;
77 }
78     :   ^((FUNCTION_METHOD_DECL | ENTRY_FUNCTION_DECL {entry = true;})
79             (^(MODIFIER_LIST .*))?
80             (^(GENERIC_TYPE_PARAM_LIST .*))? 
81             type IDENT .*)
82         {
83             //System.out.println("entering method scope " + $IDENT.text);
84             List<TypeName> typeName = $type.typeName;
85             if (typeName == null || typeName.size() == 0) {
86                 /*System.out.println("Warning: return type of " + $IDENT.text + " has null text, using void");*/
87                 typeName.add(new TypeName("void"));
88             }
89             boolean isTraced = false;
90             if ($MODIFIER_LIST != null) {
91                 CharjAST charj_mod = $MODIFIER_LIST.getChildOfType(CharjParser.CHARJ_MODIFIER_LIST);
92                 if (charj_mod != null) {
93                     charj_mod = charj_mod.getChildOfType(CharjParser.TRACED);
94                     isTraced = (charj_mod != null);
95                     if (isTraced) System.out.println("method " + $IDENT.text + " is traced");
96                 }
97             }
98             Type returnType = currentScope.resolveType(typeName);
99             //System.out.println("Resolving type " + typeName + " in scope " + currentScope + "->" + returnType);
100             MethodSymbol sym = new MethodSymbol(symtab, $IDENT.text, currentClass, returnType);
101             sym.isEntry = entry;
102             sym.isTraced = isTraced;
103             sym.definition = $enterMethod.start;
104             sym.definitionTokenStream = input.getTokenStream();
105             currentScope.define($IDENT.text, sym);
106             $IDENT.def = sym;
107             currentScope = sym;
108             $IDENT.scope = currentScope;
109             //System.out.println(currentScope);
110         }
111     |   ^((CONSTRUCTOR_DECL
112           | ENTRY_CONSTRUCTOR_DECL {
113                 entry = true;
114             })
115             (^(MODIFIER_LIST .*))?
116             (^(GENERIC_TYPE_PARAM_LIST .*))? 
117             IDENT .*)
118         {
119             //System.out.println("entering constructor scope " + $IDENT.text);
120             boolean isTraced = false;
121             CharjAST charj_mod = $MODIFIER_LIST.getChildOfType(CharjParser.CHARJ_MODIFIER_LIST);
122             if (charj_mod != null) {
123                 charj_mod = charj_mod.getChildOfType(CharjParser.TRACED);
124                 isTraced = (charj_mod != null);
125                 if (isTraced) System.out.println("method " + $IDENT.text + " is traced");
126             }
127             MethodSymbol sym = new MethodSymbol(symtab, $IDENT.text, currentClass, currentClass);
128             sym.isEntry = entry;
129             sym.isCtor = true;
130             sym.isTraced = isTraced;
131             sym.definition = $enterMethod.start;
132             sym.definitionTokenStream = input.getTokenStream();
133             currentScope.define($IDENT.text, sym);
134             $IDENT.def = sym;
135             currentScope = sym;
136             $IDENT.scope = currentScope;
137             //System.out.println(currentScope);
138         }
139     ;
140
141 exitMethod
142     :   ^((FUNCTION_METHOD_DECL | ENTRY_FUNCTION_DECL | CONSTRUCTOR_DECL | ENTRY_CONSTRUCTOR_DECL) .*) {
143             //System.out.println("method " + currentScope);
144             currentScope = currentScope.getEnclosingScope();
145         }
146     ;
147
148
149
150 enterClass
151     :   ^(TYPE classType IDENT
152             (^('extends' parent=type))?
153             (^('implements' type+))?
154             (^((FUNCTION_METHOD_DECL | ENTRY_FUNCTION_DECL | PRIMITIVE_VAR_DECLARATION |
155                 OBJECT_VAR_DECLARATION | CONSTRUCTOR_DECL | ENTRY_CONSTRUCTOR_DECL) .*))*)
156         {
157             ClassSymbol sym = new ClassSymbol(symtab, $IDENT.text,
158                     (ClassSymbol)currentScope.
159                       resolveType(TypeName.createTypeName($parent.text)),
160                                   currentScope);
161             currentScope.define(sym.name, sym);
162             currentClass = sym;
163             sym.definition = $IDENT;
164             sym.definitionTokenStream = input.getTokenStream();
165             $IDENT.def = sym;
166             currentScope = sym;
167             $IDENT.scope = currentScope;
168             $IDENT.symbolType = sym;
169             String classTypeName = $classType.text;
170             if (classTypeName.equals("class")) {
171             } else if (classTypeName.equals("chare")) {
172                 currentClass.isChare = true;
173             } else if (classTypeName.equals("group")) {
174                 currentClass.isChare = true;
175             } else if (classTypeName.equals("nodegroup")) {
176                 currentClass.isChare = true;
177             } else if (classTypeName.equals("chare_array")) {
178                 // TODO: test this; might need to use startswith instead of equals
179                 // TODO: should "isChare" be set to true?
180                 currentClass.isChare = true;
181                 currentClass.isChareArray = true;
182             } else if (classTypeName.equals("mainchare")) {
183                 currentClass.isChare = true;
184                 currentClass.isMainChare = true;
185             } else System.out.println("Error: type " + classTypeName + " not recognized.");
186         }
187     ;
188
189 exitClass
190     :   ^(TYPE classType IDENT
191             (^('extends' parent=type))?
192             (^('implements' type+))?
193             (^((FUNCTION_METHOD_DECL | ENTRY_FUNCTION_DECL | PRIMITIVE_VAR_DECLARATION |
194                 OBJECT_VAR_DECLARATION | CONSTRUCTOR_DECL | ENTRY_CONSTRUCTOR_DECL) .*))*)
195         {
196             //System.out.println("class " + currentScope);
197             currentScope = currentScope.getEnclosingScope();
198         }
199     ;
200
201 varDeclaration
202     :   ^((PRIMITIVE_VAR_DECLARATION | OBJECT_VAR_DECLARATION)
203             (^(MODIFIER_LIST .*))? type
204             ^(VAR_DECLARATOR_LIST (^(VAR_DECLARATOR ^(IDENT .*) .*)
205             {
206                 Type varType = currentScope.resolveType($type.typeName);
207                 /*System.out.println("Defining var " + $IDENT.text + " with type " +
208                     varType + " typename " + $type.typeName);*/
209                 VariableSymbol sym = new VariableSymbol(symtab, $IDENT.text, varType);
210                 sym.definition = $IDENT;
211                 sym.definitionTokenStream = input.getTokenStream();
212                 if (currentScope instanceof PackageScope) {
213                     sym.isReadOnly = true;
214                     System.out.println("Marking " + $IDENT.text + " as readonly");
215                 }
216                 $IDENT.def = sym;
217                 $IDENT.scope = currentScope;
218                 $IDENT.symbolType = varType;
219                 currentScope.define($IDENT.text, sym);
220
221             }
222             )+))
223     |   ^(FORMAL_PARAM_STD_DECL (^(MODIFIER_LIST .*))? type ^(IDENT .*))
224         {
225             Type varType = currentScope.resolveType($type.typeName);
226             /*System.out.println("Defining argument var " + $IDENT.text + " with type " + varType);*/
227             VariableSymbol sym = new VariableSymbol(symtab, $IDENT.text,
228                     currentScope.resolveType($type.typeName));
229             sym.definition = $IDENT;
230             sym.definitionTokenStream = input.getTokenStream();
231             $IDENT.def = sym;
232             $IDENT.scope = currentScope;
233             $IDENT.symbolType = varType;
234             currentScope.define($IDENT.text, sym);
235         }
236     ;
237
238
239 type returns [List<TypeName> typeName]
240 @init {
241     $typeName = new ArrayList<TypeName>();
242     if (currentScope == null) System.out.println("*****ERROR: null type scope");
243     assert currentScope != null;
244 }
245     :   VOID {
246             $VOID.scope = currentScope;
247             $typeName.add(new TypeName("void"));
248         }
249     |   ^(SIMPLE_TYPE t=. .*) {
250             $SIMPLE_TYPE.scope = currentScope;
251             $typeName.add(new TypeName($t.toString()));
252         }
253     |   ^(OBJECT_TYPE ^(QUALIFIED_TYPE_IDENT (^(i1=IDENT {$typeName.add(new TypeName($IDENT.text));} .*))+) .*)
254             { $OBJECT_TYPE.scope = currentScope; }
255     |   ^(REFERENCE_TYPE ^(QUALIFIED_TYPE_IDENT (^(IDENT {$typeName.add(new TypeName($IDENT.text));} .*))+) .*)
256             { $REFERENCE_TYPE.scope = currentScope; }
257     |   ^(PROXY_TYPE ^(QUALIFIED_TYPE_IDENT (^(IDENT {$typeName.add(new TypeName($IDENT.text));} .*))+) .*)
258             { $PROXY_TYPE.scope = currentScope; }
259     |   ^(POINTER_TYPE ^(QUALIFIED_TYPE_IDENT (^(i1=IDENT {$typeName.add(new TypeName($i1.text));} .*))+) .*)
260             { $POINTER_TYPE.scope = currentScope; }
261     ;
262
263 literal returns [String lit]
264 @init {
265 $lit = $start.getText().toString();
266 }
267     :   HEX_LITERAL
268     |   OCTAL_LITERAL
269     |   DECIMAL_LITERAL
270     |   FLOATING_POINT_LITERAL
271     |   CHARACTER_LITERAL
272     |   STRING_LITERAL
273     |   TRUE
274     |   FALSE
275     |   NULL
276     ;
277
278 classType
279     :   CLASS
280     |   CHARE
281     |   GROUP
282     |   NODEGROUP
283     |   MAINCHARE
284     |   ^(CHARE_ARRAY ARRAY_DIMENSION)
285     ;
286
287 atoms
288 @init {CharjAST t = (CharjAST)input.LT(1);}
289     :  (IDENT|THIS|SUPER) {
290             assert currentScope != null;
291             t.scope = currentScope;
292        }
293     ;