a4f7c5b6749c45a9520409746aea6f846c40dfe2
[IRC.git] / Robust / src / IR / Tree / BuildIR.java
1 package IR.Tree;
2 import IR.*;
3 import java.util.Vector;
4
5 public class BuildIR {
6     State state;
7     public BuildIR(State state) {
8         this.state=state;
9     }
10     public void buildtree() {
11         ParseNode pn=state.parsetree;
12         FileNode fn=parseFile(pn);
13         System.out.println(fn.printNode());
14     }
15
16     /** Parse the classes in this file */
17     public FileNode parseFile(ParseNode pn) {
18         FileNode fn=new FileNode();
19         ParseNode tpn=pn.getChild("type_declaration_list");
20         if (tpn!=null) {
21             ParseNodeVector pnv=tpn.getChildren();
22             for(int i=0;i<pnv.size();i++) {
23                 ParseNode type_pn=pnv.elementAt(i);
24                 if (isEmpty(type_pn)) /* Skip the semicolon */
25                     continue;
26                 ClassNode cn=parseTypeDecl(type_pn);
27                 fn.addClass(cn);
28             }
29         }
30         return fn;
31     }
32
33     public ClassNode parseTypeDecl(ParseNode pn) {
34         if (isNode(pn, "class_declaration")) {
35             ClassNode cn=new ClassNode();
36             cn.setName(pn.getChild("name").getTerminal());
37             if (!isEmpty(pn.getChild("super").getTerminal())) {
38                 /* parse superclass name */
39             }
40             cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
41             parseClassBody(cn, pn.getChild("classbody"));
42             return cn;
43         } else throw new Error();
44     }
45
46     private void parseClassBody(ClassNode cn, ParseNode pn) {
47         ParseNode decls=pn.getChild("class_body_declaration_list");
48         if (decls!=null) {
49             ParseNodeVector pnv=decls.getChildren();
50             for(int i=0;i<pnv.size();i++) {
51                 ParseNode decl=pnv.elementAt(i);
52                 if (isNode(decl,"member")) {
53                     parseClassMember(cn,decl);
54                 } else if (isNode(decl,"constructor")) {
55                 } else if (isNode(decl,"block")) {
56                 } else throw new Error();
57             }
58         }
59     }
60
61     private void parseClassMember(ClassNode cn, ParseNode pn) {
62         ParseNode fieldnode=pn.getChild("field");
63
64         if (fieldnode!=null) {
65             parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
66             return;
67         }
68         ParseNode methodnode=pn.getChild("method");
69         if (methodnode!=null) {
70             parseMethodDecl(cn,methodnode.getChild("method_declaration"));
71             return;
72         }
73         throw new Error();
74     }
75
76     private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
77         ParseNode tn=pn.getChild("type");
78         String type_st=tn.getTerminal();
79         if(type_st.equals("byte")) {
80             return state.getTypeDescriptor(TypeDescriptor.BYTE);
81         } else if(type_st.equals("short")) {
82             return state.getTypeDescriptor(TypeDescriptor.SHORT);
83         } else if(type_st.equals("boolean")) {
84             return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
85         } else if(type_st.equals("int")) {
86             return state.getTypeDescriptor(TypeDescriptor.INT);
87         } else if(type_st.equals("long")) {
88             return state.getTypeDescriptor(TypeDescriptor.LONG);
89         } else if(type_st.equals("char")) {
90             return state.getTypeDescriptor(TypeDescriptor.CHAR);
91         } else if(type_st.equals("float")) {
92             return state.getTypeDescriptor(TypeDescriptor.FLOAT);
93         } else if(type_st.equals("double")) {
94             return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
95         } else if(type_st.equals("class")) {
96             ParseNode nn=tn.getChild("class");
97             return state.getTypeDescriptor(parseName(nn.getChild("name")));
98         } else {
99             throw new Error();
100         }
101     }
102
103     private NameDescriptor parseName(ParseNode nn) {
104         ParseNode base=nn.getChild("base");
105         ParseNode id=nn.getChild("identifier");
106         
107         if (base==null)
108             return new NameDescriptor(id.getTerminal());
109
110         return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
111         
112     }
113
114     private void parseFieldDecl(ClassNode cn,ParseNode pn) {
115         ParseNode mn=pn.getChild("modifier");
116         Modifiers m=parseModifiersList(mn);
117
118
119         ParseNode tn=pn.getChild("type");
120         TypeDescriptor t=parseTypeDescriptor(tn);
121         ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
122         ParseNodeVector pnv=vn.getChildren();
123         for(int i=0;i<pnv.size();i++) {
124             ParseNode vardecl=pnv.elementAt(i);
125             String identifier=vardecl.getChild("single").getTerminal();
126             ParseNode epn=vardecl.getChild("initializer");
127             
128             ExpressionNode en=null;
129             if (epn!=null)
130                 en=parseExpression(epn.getFirstChild());
131   
132             cn.addField(new FieldDescriptor(m,t,identifier, en));
133         }
134         
135     }
136
137     private ExpressionNode parseExpression(ParseNode pn) {
138         if (isNode(pn,"assignment"))
139             return parseAssignmentExpression(pn);
140         else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
141                  isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
142                  isNode(pn,"bitwise_and")||isNode(pn,"equal")||
143                  isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
144                  isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
145                  isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
146                  isNode(pn,"rightshift")||isNode(pn,"sub")||
147                  isNode(pn,"add")||isNode(pn,"mult")||
148                  isNode(pn,"div")||isNode(pn,"mod")) {
149             ParseNodeVector pnv=pn.getChildren();
150             ParseNode left=pnv.elementAt(0);
151             ParseNode right=pnv.elementAt(1);
152             Operation op=new Operation(pn.getLabel());
153             return new OpNode(parseExpression(left),parseExpression(right),op);
154         } else if (isNode(pn,"unaryplus")||
155                    isNode(pn,"unaryminus")||
156                    isNode(pn,"postinc")||
157                    isNode(pn,"postdec")||
158                    isNode(pn,"preinc")||
159                    isNode(pn,"predec")) {
160             ParseNode left=pn.getFirstChild();
161             Operation op=new Operation(pn.getLabel());
162             return new OpNode(parseExpression(left),op);
163         } else if (isNode(pn,"literal")) {
164             String literaltype=pn.getTerminal();
165             ParseNode literalnode=pn.getChild(literaltype);
166             Object literal_obj=literalnode.getLiteral();
167             return new LiteralNode(literaltype, literal_obj);
168         } else if (isNode(pn,"createobject")) {
169             TypeDescriptor td=parseTypeDescriptor(pn);
170             Vector args=parseArgumentList(pn);
171             CreateObjectNode con=new CreateObjectNode(td);
172             for(int i=0;i<args.size();i++) {
173                 con.addArgument((ExpressionNode)args.get(i));
174             }
175             return con;
176         } else if (isNode(pn,"name")) {
177             NameDescriptor nd=parseName(pn);
178             return new NameNode(nd);
179         } else if (isNode(pn,"this")) {
180             NameDescriptor nd=new NameDescriptor("this");
181             return new NameNode(nd);
182         } else if (isNode(pn,"methodinvoke1")) {
183             NameDescriptor nd=parseName(pn.getChild("name"));
184             Vector args=parseArgumentList(pn);
185             MethodInvokeNode min=new MethodInvokeNode(nd);
186             for(int i=0;i<args.size();i++) {
187                 min.addArgument((ExpressionNode)args.get(i));
188             }
189             return min;
190         } else if (isNode(pn,"methodinvoke2")) {
191             String methodid=pn.getChild("id").getTerminal();
192             ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
193             Vector args=parseArgumentList(pn);
194             MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
195             for(int i=0;i<args.size();i++) {
196                 min.addArgument((ExpressionNode)args.get(i));
197             }
198             return min;
199         } else if (isNode(pn,"fieldaccess")) { 
200             ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
201             String fieldname=pn.getChild("field").getTerminal();
202             return new FieldAccessNode(en,fieldname);
203         } else {
204             System.out.println("---------------------");
205             System.out.println(pn.PPrint(3,true));
206             throw new Error();
207         }
208     }
209
210     private Vector parseArgumentList(ParseNode pn) {
211         Vector arglist=new Vector();
212         ParseNode an=pn.getChild("argument_list");
213         if (an==null)   /* No argument list */
214             return arglist;
215         ParseNodeVector anv=an.getChildren();
216         for(int i=0;i<anv.size();i++) {
217             arglist.add(parseExpression(anv.elementAt(i)));
218         }
219         return arglist;
220     }
221
222     private ExpressionNode parseAssignmentExpression(ParseNode pn) {
223         AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
224         ParseNodeVector pnv=pn.getChild("args").getChildren();
225         
226         AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
227         return an;
228     }
229
230
231     private void parseMethodDecl(ClassNode cn, ParseNode pn) {
232         ParseNode headern=pn.getChild("method_header");
233         ParseNode bodyn=pn.getChild("body");
234         MethodDescriptor md=parseMethodHeader(headern);
235         BlockNode bn=parseBlock(bodyn);
236         cn.addMethod(md,bn);
237     }
238
239     public BlockNode parseBlock(ParseNode pn) {
240         if (isEmpty(pn.getTerminal()))
241             return new BlockNode();
242         ParseNode bsn=pn.getChild("block_statement_list");
243         return parseBlockHelper(bsn);
244     }
245     
246     private BlockNode parseBlockHelper(ParseNode pn) {
247         ParseNodeVector pnv=pn.getChildren();
248         BlockNode bn=new BlockNode();
249         for(int i=0;i<pnv.size();i++) {
250             Vector bsv=parseBlockStatement(pnv.elementAt(i));
251             for(int j=0;j<bsv.size();j++) {
252                 bn.addBlockStatement((BlockStatementNode)bsv.get(j));
253             }
254         }
255         return bn;
256     }
257
258     public BlockNode parseSingleBlock(ParseNode pn) {
259         BlockNode bn=new BlockNode();
260         Vector bsv=parseBlockStatement(pn);
261         for(int j=0;j<bsv.size();j++) {
262             bn.addBlockStatement((BlockStatementNode)bsv.get(j));
263         }
264         return bn;
265     }
266
267     public Vector parseBlockStatement(ParseNode pn) {
268         Vector blockstatements=new Vector();
269         if (isNode(pn,"local_variable_declaration")) {
270             TypeDescriptor t=parseTypeDescriptor(pn);
271             ParseNode vn=pn.getChild("variable_declarators_list");
272             ParseNodeVector pnv=vn.getChildren();
273             for(int i=0;i<pnv.size();i++) {
274                 ParseNode vardecl=pnv.elementAt(i);
275                 String identifier=vardecl.getChild("single").getTerminal();
276                 ParseNode epn=vardecl.getChild("initializer");
277                 
278                 ExpressionNode en=null;
279                 if (epn!=null)
280                     en=parseExpression(epn.getFirstChild());
281                 
282                 blockstatements.add(new DeclarationNode(new VarDescriptor(t,identifier, en)));
283             }
284         } else if (isNode(pn,"nop")) {
285             /* Do Nothing */
286         } else if (isNode(pn,"expression")) {
287             blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
288         } else if (isNode(pn,"ifstatement")) {
289             blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
290                                        parseSingleBlock(pn.getChild("statement").getFirstChild()),
291                                        pn.getChild("else_statement")!=null?parseSingleBlock(pn.getChild("else_statement").getFirstChild()):null));
292         } else if (isNode(pn,"return")) {
293             if (isEmpty(pn.getTerminal()))
294                 blockstatements.add(new ReturnNode());
295             else {
296                 ExpressionNode en=parseExpression(pn.getFirstChild());
297                 blockstatements.add(new ReturnNode(en));
298             }
299         } else if (isNode(pn,"block_statement_list")) {
300             BlockNode bn=parseBlockHelper(pn);
301             blockstatements.add(new SubBlockNode(bn));
302         } else if (isNode(pn,"empty")) {
303             /* nop */
304         } /*else {
305             System.out.println("---------------");
306             System.out.println(pn.PPrint(3,true));
307             throw new Error();
308             }*/
309         return blockstatements;
310     }
311
312     public MethodDescriptor parseMethodHeader(ParseNode pn) {
313         ParseNode mn=pn.getChild("modifiers");
314         Modifiers m=parseModifiersList(mn);
315         
316         ParseNode tn=pn.getChild("returntype");
317         TypeDescriptor returntype;
318         if (tn!=null) 
319             returntype=parseTypeDescriptor(tn);
320         else
321             returntype=new TypeDescriptor(TypeDescriptor.VOID);
322
323         ParseNode pmd=pn.getChild("method_declarator");
324         String name=pmd.getChild("name").getTerminal();
325         MethodDescriptor md=new MethodDescriptor(m, returntype, name);
326        
327         ParseNode paramnode=pmd.getChild("parameters");
328         parseParameterList(md,paramnode);
329         return md;
330     }
331
332     public void parseParameterList(MethodDescriptor md, ParseNode pn) {
333         ParseNode paramlist=pn.getChild("formal_parameter_list");
334         if (paramlist==null)
335             return;
336          ParseNodeVector pnv=paramlist.getChildren();
337          for(int i=0;i<pnv.size();i++) {
338              ParseNode paramn=pnv.elementAt(i);
339              TypeDescriptor type=parseTypeDescriptor(paramn);
340              String paramname=paramn.getChild("single").getTerminal();
341              md.addParameter(type,paramname);
342          }
343     }
344
345     public Modifiers parseModifiersList(ParseNode pn) {
346         Modifiers m=new Modifiers();
347         ParseNode modlist=pn.getChild("modifier_list");
348         if (modlist!=null) {
349             ParseNodeVector pnv=modlist.getChildren();
350             for(int i=0;i<pnv.size();i++) {
351                 ParseNode modn=pnv.elementAt(i);
352                 if (isNode(modn,"public"))
353                     m.addModifier(Modifiers.PUBLIC);
354                 if (isNode(modn,"protected"))
355                     m.addModifier(Modifiers.PROTECTED);
356                 if (isNode(modn,"private"))
357                     m.addModifier(Modifiers.PRIVATE);
358                 if (isNode(modn,"static"))
359                     m.addModifier(Modifiers.STATIC);
360                 if (isNode(modn,"final"))
361                     m.addModifier(Modifiers.FINAL);
362                 if (isNode(modn,"native"))
363                     m.addModifier(Modifiers.NATIVE);
364             }
365         }
366         return m;
367     }
368
369     private boolean isNode(ParseNode pn, String label) {
370         if (pn.getLabel().equals(label))
371             return true;
372         else return false;
373     }
374
375     private static boolean isEmpty(ParseNode pn) {
376         if (pn.getLabel().equals("empty"))
377             return true;
378         else
379             return false;
380     }
381
382     private static boolean isEmpty(String s) {
383         if (s.equals("empty"))
384             return true;
385         else
386             return false;
387     }
388
389     /** Throw an exception if something is unexpected */
390     private void check(ParseNode pn, String label) {
391         if (pn == null) {
392             throw new Error(pn+ "IE: Expected '" + label + "', got null");
393         }
394         if (! pn.getLabel().equals(label)) {
395             throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
396         }
397     }
398 }