Charj: improved error message and added pupping for proxy types
[charm.git] / src / langs / charj / src / charj / translator / PupRoutineCreator.java
1 package charj.translator;
2
3 import org.antlr.runtime.tree.CommonTree;
4 import org.antlr.runtime.Token;
5 import org.antlr.runtime.CommonToken;
6
7 class PupRoutineCreator
8 {
9     private CharjAST pupNode;
10     private CharjAST initNode;
11
12     PupRoutineCreator()
13     {
14         createPupNode();
15         createInitNode();
16     }
17
18     protected CharjAST getPupRoutineNode()
19     {
20         return pupNode;
21     }
22
23     protected CharjAST getInitRoutineNode()
24     {
25         return initNode;
26     }
27
28     private CharjAST createNode(int type, String text)
29     {
30         return new CharjAST(new CommonToken(type, text));
31     }    
32     
33     private void createInitNode()
34     {
35         initNode = createNode(CharjParser.FUNCTION_METHOD_DECL, "FUNCTION_METHOD_DECL");
36
37         initNode.addChild(createNode(CharjParser.MODIFIER_LIST, "MODIFIER_LIST"));
38         initNode.addChild(createNode(CharjParser.VOID, "void"));
39         initNode.addChild(createNode(CharjParser.IDENT, "initMethod"));
40         initNode.addChild(createNode(CharjParser.FORMAL_PARAM_LIST, "FORMAL_PARAM_LIST"));
41         initNode.addChild(createNode(CharjParser.BLOCK, "BLOCK"));
42
43         initNode.getChild(0).addChild(createNode(CharjParser.PRIVATE, "private"));
44     }
45
46     private void createPupNode()
47     {
48         pupNode = createNode(CharjParser.FUNCTION_METHOD_DECL, "FUNCTION_METHOD_DECL");
49
50         pupNode.addChild(createNode(CharjParser.MODIFIER_LIST, "MODIFIER_LIST"));
51         pupNode.addChild(createNode(CharjParser.VOID, "void"));
52         pupNode.addChild(createNode(CharjParser.IDENT, "pup"));
53         pupNode.addChild(createNode(CharjParser.FORMAL_PARAM_LIST, "FORMAL_PARAM_LIST"));
54         pupNode.addChild(createNode(CharjParser.BLOCK, "BLOCK"));
55
56         pupNode.getChild(0).addChild(createNode(CharjParser.PUBLIC, "public"));
57
58         pupNode.getChild(3).addChild(createNode(CharjParser.FORMAL_PARAM_STD_DECL, "FORMAL_PARAM_STD_DECL"));
59         pupNode.getChild(3).getChild(0).addChild(createNode(CharjParser.REFERENCE_TYPE, "REFERENCE_TYPE"));
60         pupNode.getChild(3).getChild(0).getChild(0).addChild(createNode(CharjParser.QUALIFIED_TYPE_IDENT, "QUALIFIED_TYPE_IDENT"));
61         pupNode.getChild(3).getChild(0).getChild(0).getChild(0).addChild(createNode(CharjParser.IDENT, "PUP::er"));
62
63         pupNode.getChild(3).getChild(0).addChild(createNode(CharjParser.IDENT, "p"));
64     }
65
66     protected CharjAST getEnclosingType(CharjAST varDeclNode)
67     {
68         for(CharjAST p = varDeclNode.getParent(); p != null; p = p.getParent())
69             if(p.getType() == CharjParser.TYPE)
70                 return p;
71         return null;
72     }         
73
74     protected void varPup(CharjAST idNode)
75     {
76         int type = -1;
77
78         for(CharjAST p = idNode.getParent(); p != null; p = p.getParent())
79         {
80             switch(p.getType())
81             {
82                 case CharjParser.PRIMITIVE_VAR_DECLARATION:
83                     type = p.getType();
84                     break;
85                 case CharjParser.OBJECT_VAR_DECLARATION:
86                     type = p.getChild(0).getType();
87                     break;
88                 case CharjParser.FUNCTION_METHOD_DECL:
89                 case CharjParser.BLOCK:
90                 case CharjParser.FORMAL_PARAM_LIST:
91                     return;
92                 case CharjParser.TYPE:
93                     switch(type)
94                     {
95                         case CharjParser.REFERENCE_TYPE:
96                             break;
97                         case CharjParser.PRIMITIVE_VAR_DECLARATION:
98                             primitiveVarPup(idNode);
99                             break;
100                         case CharjParser.POINTER_TYPE:
101                             pointerVarPup(idNode);
102                             break;
103                         case CharjParser.PROXY_TYPE:
104                             proxyVarPup(idNode);
105                             break;
106                         default:
107                             System.out.println("PupRoutineCreator.varPup: unknown type " + idNode);
108                             break;
109                     }
110                     return;
111             }
112         }
113         System.out.println("PupRoutineCreator.varPup: could not pup variable " + idNode);
114     }
115
116     protected void primitiveVarPup(CharjAST idNode)
117     {
118         pupNode.getChild(4).addChild(createNode(CharjParser.EXPR, "EXPR"));
119         
120         int index = pupNode.getChild(4).getChildren().size() - 1;
121
122         pupNode.getChild(4).getChild(index).addChild(createNode(CharjParser.BITWISE_OR, "|"));
123         pupNode.getChild(4).getChild(index).getChild(0).addChild(createNode(CharjParser.IDENT, "p"));
124         pupNode.getChild(4).getChild(index).getChild(0).addChild(idNode.dupNode());
125     }
126
127     protected void proxyVarPup(CharjAST idNode)
128     {
129         // For now, just do a basic PUP. More complex handling may be needed later.
130         primitiveVarPup(idNode);
131     }
132     
133     private boolean generatedIf = false;
134
135     protected void pointerVarPup(CharjAST idNode)
136     {
137         if(!generatedIf)
138         {
139             generateIf();
140             generatedIf = true;
141         }
142
143         // add stuff to the initMethod routine
144         initNode.getChild(4).addChild(createNode(CharjParser.EXPR, "EXPR"));
145
146         int index = initNode.getChild(4).getChildren().size() - 1;
147
148         initNode.getChild(4).getChild(index).addChild(createNode(CharjParser.ASSIGNMENT, "="));
149         initNode.getChild(4).getChild(index).getChild(0).addChild(idNode.dupNode());
150         initNode.getChild(4).getChild(index).getChild(0).addChild(createNode(CharjParser.NEW, "new"));
151         initNode.getChild(4).getChild(index).getChild(0).getChild(1).addChild(createNode(CharjParser.QUALIFIED_TYPE_IDENT, "QUALIFIED_TYPE_IDENT"));
152         initNode.getChild(4).getChild(index).getChild(0).getChild(1).getChild(0).addChild(idNode.getParent().getParent().getParent().getChild(0).getChild(0).getChild(0).dupNode());
153         initNode.getChild(4).getChild(index).getChild(0).getChild(1).addChild(createNode(CharjParser.ARGUMENT_LIST, "ARGUMENT_LIST"));
154
155         // add stuff to the pup routine
156         pupNode.getChild(4).addChild(createNode(CharjParser.EXPR, "EXPR"));
157
158         index = pupNode.getChild(4).getChildren().size() - 1;
159
160         pupNode.getChild(4).getChild(index).addChild(createNode(CharjParser.METHOD_CALL, "METHOD_CALL"));
161         pupNode.getChild(4).getChild(index).getChild(0).addChild(createNode(CharjParser.ARROW, "ARROW"));
162         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).addChild(idNode.dupNode());
163         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).addChild(createNode(CharjParser.IDENT, "pup"));
164         pupNode.getChild(4).getChild(index).getChild(0).addChild(createNode(CharjParser.ARGUMENT_LIST, "ARGUMENT_LIST"));
165         pupNode.getChild(4).getChild(index).getChild(0).getChild(1).addChild(createNode(CharjParser.EXPR, "EXPR"));
166         pupNode.getChild(4).getChild(index).getChild(0).getChild(1).getChild(0).addChild(createNode(CharjParser.IDENT, "p"));
167     }
168
169     protected void generateIf()
170     {
171         pupNode.getChild(4).addChild(createNode(CharjParser.IF, "if"));
172         
173         int index = pupNode.getChild(4).getChildren().size() - 1;
174        
175         pupNode.getChild(4).getChild(index).addChild(createNode(CharjParser.PAREN_EXPR, "PAREN_EXPR"));
176         pupNode.getChild(4).getChild(index).getChild(0).addChild(createNode(CharjParser.EXPR, "EXPR"));
177         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).addChild(createNode(CharjParser.METHOD_CALL, "METHOD_CALL"));
178         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).getChild(0).addChild(createNode(CharjParser.DOT, "."));
179         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).getChild(0).getChild(0).addChild(createNode(CharjParser.IDENT, "p"));
180         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).getChild(0).getChild(0).addChild(createNode(CharjParser.IDENT, "isUnpacking"));
181         pupNode.getChild(4).getChild(index).getChild(0).getChild(0).getChild(0).addChild(createNode(CharjParser.ARGUMENT_LIST, "ARGUMENT_LIST"));
182         pupNode.getChild(4).getChild(index).addChild(createNode(CharjParser.BLOCK, "BLOCK"));
183         pupNode.getChild(4).getChild(index).getChild(1).addChild(createNode(CharjParser.EXPR, "EXPR"));
184         pupNode.getChild(4).getChild(index).getChild(1).getChild(0).addChild(createNode(CharjParser.METHOD_CALL, "METHOD_CALL"));
185         pupNode.getChild(4).getChild(index).getChild(1).getChild(0).getChild(0).addChild(createNode(CharjParser.IDENT, "initMethod"));
186         pupNode.getChild(4).getChild(index).getChild(1).getChild(0).getChild(0).addChild(createNode(CharjParser.ARGUMENT_LIST, "ARGUMENT_LIST"));
187     }
188
189 }