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