Other changes
[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(0));
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         if (base==null)
107             return new NameDescriptor(id.getTerminal());
108         return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
109         
110     }
111
112     private void parseFieldDecl(ClassNode cn,ParseNode pn) {
113         ParseNode mn=pn.getChild("modifier");
114         Modifiers m=parseModifiersList(mn);
115
116         ParseNode tn=pn.getChild("type");
117         TypeDescriptor t=parseTypeDescriptor(tn);
118         ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
119         ParseNodeVector pnv=vn.getChildren();
120         for(int i=0;i<pnv.size();i++) {
121             ParseNode vardecl=pnv.elementAt(i);
122             String identifier=vardecl.getChild("single").getTerminal();
123             ParseNode epn=vardecl.getChild("initializer");
124             
125             ExpressionNode en=null;
126             if (epn!=null)
127                 en=parseExpression(epn.getFirstChild());
128   
129             cn.addField(new FieldDescriptor(m,t,identifier, en));
130         }
131         
132     }
133
134     private ExpressionNode parseExpression(ParseNode pn) {
135         if (isNode(pn,"assignment"))
136             return parseAssignmentExpression(pn);
137         else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
138                  isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
139                  isNode(pn,"bitwise_and")||isNode(pn,"equal")||
140                  isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
141                  isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
142                  isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
143                  isNode(pn,"rightshift")||isNode(pn,"sub")||
144                  isNode(pn,"add")||isNode(pn,"mult")||
145                  isNode(pn,"div")||isNode(pn,"mod")) {
146             ParseNodeVector pnv=pn.getChildren();
147             ParseNode left=pnv.elementAt(0);
148             ParseNode right=pnv.elementAt(1);
149             Operation op=new Operation(pn.getLabel());
150             return new OpNode(parseExpression(left),parseExpression(right),op);
151         } else if (isNode(pn,"unaryplus")||
152                    isNode(pn,"unaryminus")||
153                    isNode(pn,"postinc")||
154                    isNode(pn,"postdec")||
155                    isNode(pn,"preinc")||
156                    isNode(pn,"predec")) {
157             ParseNode left=pn.getFirstChild();
158             Operation op=new Operation(pn.getLabel());
159             return new OpNode(parseExpression(left),op);
160         } else if (isNode(pn,"literal")) {
161             String literaltype=pn.getTerminal();
162             ParseNode literalnode=pn.getChild(literaltype);
163             Object literal_obj=literalnode.getLiteral();
164             return new LiteralNode(literaltype, literal_obj);
165         } else if (isNode(pn,"createobject")) {
166             TypeDescriptor td=parseTypeDescriptor(pn);
167             Vector args=parseArgumentList(pn);
168             CreateObjectNode con=new CreateObjectNode(td);
169             for(int i=0;i<args.size();i++) {
170                 con.addArgument((ExpressionNode)args.get(i));
171             }
172             return con;
173         } else if (isNode(pn,"name")) {
174             NameDescriptor nd=parseName(pn);
175             return new NameNode(nd);
176         } else if (isNode(pn,"this")) {
177             NameDescriptor nd=new NameDescriptor("this");
178             return new NameNode(nd);
179         } else if (isNode(pn,"methodinvoke1")) {
180             NameDescriptor nd=parseName(pn.getChild("name"));
181             Vector args=parseArgumentList(pn);
182             MethodInvokeNode min=new MethodInvokeNode(nd);
183             for(int i=0;i<args.size();i++) {
184                 min.addArgument((ExpressionNode)args.get(i));
185             }
186             return min;
187         } else if (isNode(pn,"methodinvoke2")) {
188             String methodid=pn.getChild("id").getTerminal();
189             ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
190             Vector args=parseArgumentList(pn);
191             MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
192             for(int i=0;i<args.size();i++) {
193                 min.addArgument((ExpressionNode)args.get(i));
194             }
195             return min;
196         } else if (isNode(pn,"fieldaccess")) { 
197             ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
198             String fieldname=pn.getChild("field").getTerminal();
199             return new FieldAccessNode(en,fieldname);
200         } else if (isNode(pn,"cast1")) { 
201             return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
202         } else if (isNode(pn,"cast2")) { 
203             return new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
204         } else {
205             System.out.println("---------------------");
206             System.out.println(pn.PPrint(3,true));
207             throw new Error();
208         }
209     }
210
211     private Vector parseArgumentList(ParseNode pn) {
212         Vector arglist=new Vector();
213         ParseNode an=pn.getChild("argument_list");
214         if (an==null)   /* No argument list */
215             return arglist;
216         ParseNodeVector anv=an.getChildren();
217         for(int i=0;i<anv.size();i++) {
218             arglist.add(parseExpression(anv.elementAt(i)));
219         }
220         return arglist;
221     }
222
223     private ExpressionNode parseAssignmentExpression(ParseNode pn) {
224         AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
225         ParseNodeVector pnv=pn.getChild("args").getChildren();
226         
227         AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
228         return an;
229     }
230
231
232     private void parseMethodDecl(ClassNode cn, ParseNode pn) {
233         ParseNode headern=pn.getChild("method_header");
234         ParseNode bodyn=pn.getChild("body");
235         MethodDescriptor md=parseMethodHeader(headern);
236         BlockNode bn=parseBlock(bodyn);
237         cn.addMethod(md,bn);
238     }
239
240     public BlockNode parseBlock(ParseNode pn) {
241         if (isEmpty(pn.getTerminal()))
242             return new BlockNode();
243         ParseNode bsn=pn.getChild("block_statement_list");
244         return parseBlockHelper(bsn);
245     }
246     
247     private BlockNode parseBlockHelper(ParseNode pn) {
248         ParseNodeVector pnv=pn.getChildren();
249         BlockNode bn=new BlockNode();
250         for(int i=0;i<pnv.size();i++) {
251             Vector bsv=parseBlockStatement(pnv.elementAt(i));
252             for(int j=0;j<bsv.size();j++) {
253                 bn.addBlockStatement((BlockStatementNode)bsv.get(j));
254             }
255         }
256         return bn;
257     }
258
259     public BlockNode parseSingleBlock(ParseNode pn) {
260         BlockNode bn=new BlockNode();
261         Vector bsv=parseBlockStatement(pn);
262         for(int j=0;j<bsv.size();j++) {
263             bn.addBlockStatement((BlockStatementNode)bsv.get(j));
264         }
265         bn.setStyle(BlockNode.NOBRACES);
266         return bn;
267     }
268
269     public Vector parseBlockStatement(ParseNode pn) {
270         Vector blockstatements=new Vector();
271         if (isNode(pn,"local_variable_declaration")) {
272             TypeDescriptor t=parseTypeDescriptor(pn);
273             ParseNode vn=pn.getChild("variable_declarators_list");
274             ParseNodeVector pnv=vn.getChildren();
275             for(int i=0;i<pnv.size();i++) {
276                 ParseNode vardecl=pnv.elementAt(i);
277                 String identifier=vardecl.getChild("single").getTerminal();
278                 ParseNode epn=vardecl.getChild("initializer");
279                 
280                 ExpressionNode en=null;
281                 if (epn!=null)
282                     en=parseExpression(epn.getFirstChild());
283                 
284                 blockstatements.add(new DeclarationNode(new VarDescriptor(t,identifier, en)));
285             }
286         } else if (isNode(pn,"nop")) {
287             /* Do Nothing */
288         } else if (isNode(pn,"expression")) {
289             blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
290         } else if (isNode(pn,"ifstatement")) {
291             blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
292                                        parseSingleBlock(pn.getChild("statement").getFirstChild()),
293                                        pn.getChild("else_statement")!=null?parseSingleBlock(pn.getChild("else_statement").getFirstChild()):null));
294         } else if (isNode(pn,"return")) {
295             if (isEmpty(pn.getTerminal()))
296                 blockstatements.add(new ReturnNode());
297             else {
298                 ExpressionNode en=parseExpression(pn.getFirstChild());
299                 blockstatements.add(new ReturnNode(en));
300             }
301         } else if (isNode(pn,"block_statement_list")) {
302             BlockNode bn=parseBlockHelper(pn);
303             blockstatements.add(new SubBlockNode(bn));
304         } else if (isNode(pn,"empty")) {
305             /* nop */
306         } else if (isNode(pn,"statement_expression_list")) {
307             ParseNodeVector pnv=pn.getChildren();
308             BlockNode bn=new BlockNode();
309             for(int i=0;i<pnv.size();i++) {
310                 ExpressionNode en=parseExpression(pnv.elementAt(i));
311                 blockstatements.add(new BlockExpressionNode(en));
312             }
313             bn.setStyle(BlockNode.EXPRLIST);
314         } else if (isNode(pn,"forstatement")) {
315             BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
316             BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
317             ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
318             BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
319             blockstatements.add(new LoopNode(init,condition,update,body));
320         } else {
321             System.out.println("---------------");
322             System.out.println(pn.PPrint(3,true));
323             throw new Error();
324         }
325         return blockstatements;
326     }
327
328     public MethodDescriptor parseMethodHeader(ParseNode pn) {
329         ParseNode mn=pn.getChild("modifiers");
330         Modifiers m=parseModifiersList(mn);
331         
332         ParseNode tn=pn.getChild("returntype");
333         TypeDescriptor returntype;
334         if (tn!=null) 
335             returntype=parseTypeDescriptor(tn);
336         else
337             returntype=new TypeDescriptor(TypeDescriptor.VOID);
338
339         ParseNode pmd=pn.getChild("method_declarator");
340         String name=pmd.getChild("name").getTerminal();
341         MethodDescriptor md=new MethodDescriptor(m, returntype, name);
342        
343         ParseNode paramnode=pmd.getChild("parameters");
344         parseParameterList(md,paramnode);
345         return md;
346     }
347
348     public void parseParameterList(MethodDescriptor md, ParseNode pn) {
349         ParseNode paramlist=pn.getChild("formal_parameter_list");
350         if (paramlist==null)
351             return;
352          ParseNodeVector pnv=paramlist.getChildren();
353          for(int i=0;i<pnv.size();i++) {
354              ParseNode paramn=pnv.elementAt(i);
355              TypeDescriptor type=parseTypeDescriptor(paramn);
356              String paramname=paramn.getChild("single").getTerminal();
357              md.addParameter(type,paramname);
358          }
359     }
360
361     public Modifiers parseModifiersList(ParseNode pn) {
362         Modifiers m=new Modifiers();
363         ParseNode modlist=pn.getChild("modifier_list");
364         if (modlist!=null) {
365             ParseNodeVector pnv=modlist.getChildren();
366             for(int i=0;i<pnv.size();i++) {
367                 ParseNode modn=pnv.elementAt(i);
368                 if (isNode(modn,"public"))
369                     m.addModifier(Modifiers.PUBLIC);
370                 if (isNode(modn,"protected"))
371                     m.addModifier(Modifiers.PROTECTED);
372                 if (isNode(modn,"private"))
373                     m.addModifier(Modifiers.PRIVATE);
374                 if (isNode(modn,"static"))
375                     m.addModifier(Modifiers.STATIC);
376                 if (isNode(modn,"final"))
377                     m.addModifier(Modifiers.FINAL);
378                 if (isNode(modn,"native"))
379                     m.addModifier(Modifiers.NATIVE);
380             }
381         }
382         return m;
383     }
384
385     private boolean isNode(ParseNode pn, String label) {
386         if (pn.getLabel().equals(label))
387             return true;
388         else return false;
389     }
390
391     private static boolean isEmpty(ParseNode pn) {
392         if (pn.getLabel().equals("empty"))
393             return true;
394         else
395             return false;
396     }
397
398     private static boolean isEmpty(String s) {
399         if (s.equals("empty"))
400             return true;
401         else
402             return false;
403     }
404
405     /** Throw an exception if something is unexpected */
406     private void check(ParseNode pn, String label) {
407         if (pn == null) {
408             throw new Error(pn+ "IE: Expected '" + label + "', got null");
409         }
410         if (! pn.getLabel().equals(label)) {
411             throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
412         }
413     }
414 }