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